From 5ce9352028073d0dc9ee7b9ee911a352e42ed433 Mon Sep 17 00:00:00 2001 From: wangfenjin Date: Mon, 13 Feb 2023 21:59:24 +0800 Subject: [PATCH 1/2] upgrade to 0.7.0 Change-Id: I5e9b597d51e0838676028873fa5b71b81d99ba6e --- .github/workflows/rust.yaml | 4 +- Cargo.toml | 4 +- libduckdb-sys/Cargo.toml | 2 +- .../duckdb/bindgen_bundled_version.rs | 551 +- libduckdb-sys/duckdb/duckdb.cpp | 74486 +++++++++------- libduckdb-sys/duckdb/duckdb.h | 177 +- libduckdb-sys/duckdb/duckdb.hpp | 18394 ++-- libduckdb-sys/src/lib.rs | 10 +- libduckdb-sys/upgrade.sh | 2 +- src/cache.rs | 16 +- src/raw_statement.rs | 7 +- 11 files changed, 54700 insertions(+), 38953 deletions(-) diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml index 203c5362..ffbc0390 100644 --- a/.github/workflows/rust.yaml +++ b/.github/workflows/rust.yaml @@ -38,7 +38,7 @@ jobs: name: Download duckdb with: repository: "duckdb/duckdb" - tag: "v0.6.1" + tag: "v0.7.0" fileName: ${{ matrix.duckdb }} out-file-path: . @@ -123,7 +123,7 @@ jobs: name: Download duckdb with: repository: "duckdb/duckdb" - tag: "v0.6.1" + tag: "v0.7.0" fileName: "libduckdb-linux-amd64.zip" out-file-path: . - name: Linux extract duckdb diff --git a/Cargo.toml b/Cargo.toml index 65072b48..c584c44e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "duckdb" -version = "0.6.1" +version = "0.7.0" authors = ["wangfenjin "] edition = "2021" description = "Ergonomic wrapper for DuckDB" @@ -69,7 +69,7 @@ tempdir = "0.3.7" [dependencies.libduckdb-sys] path = "libduckdb-sys" -version = "0.6.1" +version = "0.7.0" [package.metadata.docs.rs] features = [] diff --git a/libduckdb-sys/Cargo.toml b/libduckdb-sys/Cargo.toml index 5937fdf2..341e67f2 100644 --- a/libduckdb-sys/Cargo.toml +++ b/libduckdb-sys/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "libduckdb-sys" -version = "0.6.1" +version = "0.7.0" authors = ["wangfenjin "] edition = "2021" build = "build.rs" diff --git a/libduckdb-sys/duckdb/bindgen_bundled_version.rs b/libduckdb-sys/duckdb/bindgen_bundled_version.rs index c03c7551..2c7a246d 100644 --- a/libduckdb-sys/duckdb/bindgen_bundled_version.rs +++ b/libduckdb-sys/duckdb/bindgen_bundled_version.rs @@ -1,4 +1,4 @@ -/* automatically generated by rust-bindgen 0.63.0 */ +/* automatically generated by rust-bindgen 0.64.0 */ #[repr(C)] #[derive(Copy, Clone, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] @@ -84,9 +84,9 @@ pub const DUCKDB_API_0_3_1: u32 = 1; pub const DUCKDB_API_0_3_2: u32 = 2; pub const DUCKDB_API_LATEST: u32 = 2; pub const DUCKDB_API_VERSION: u32 = 2; +pub const __bool_true_false_are_defined: u32 = 1; pub const true_: u32 = 1; pub const false_: u32 = 0; -pub const __bool_true_false_are_defined: u32 = 1; pub const __WORDSIZE: u32 = 64; pub const __DARWIN_ONLY_64_BIT_INO_T: u32 = 0; pub const __DARWIN_ONLY_UNIX_CONFORMANCE: u32 = 1; @@ -212,6 +212,7 @@ pub const __MAC_12_1: u32 = 120100; pub const __MAC_12_2: u32 = 120200; pub const __MAC_12_3: u32 = 120300; pub const __MAC_13_0: u32 = 130000; +pub const __MAC_13_1: u32 = 130100; pub const __IPHONE_2_0: u32 = 20000; pub const __IPHONE_2_1: u32 = 20100; pub const __IPHONE_2_2: u32 = 20200; @@ -274,6 +275,7 @@ pub const __IPHONE_15_3: u32 = 150300; pub const __IPHONE_15_4: u32 = 150400; pub const __IPHONE_16_0: u32 = 160000; pub const __IPHONE_16_1: u32 = 160100; +pub const __IPHONE_16_2: u32 = 160200; pub const __TVOS_9_0: u32 = 90000; pub const __TVOS_9_1: u32 = 90100; pub const __TVOS_9_2: u32 = 90200; @@ -309,6 +311,7 @@ pub const __TVOS_15_3: u32 = 150300; pub const __TVOS_15_4: u32 = 150400; pub const __TVOS_16_0: u32 = 160000; pub const __TVOS_16_1: u32 = 160100; +pub const __TVOS_16_2: u32 = 160200; pub const __WATCHOS_1_0: u32 = 10000; pub const __WATCHOS_2_0: u32 = 20000; pub const __WATCHOS_2_1: u32 = 20100; @@ -342,6 +345,7 @@ pub const __WATCHOS_8_4: u32 = 80400; pub const __WATCHOS_8_5: u32 = 80500; pub const __WATCHOS_9_0: u32 = 90000; pub const __WATCHOS_9_1: u32 = 90100; +pub const __WATCHOS_9_2: u32 = 90200; pub const MAC_OS_X_VERSION_10_0: u32 = 1000; pub const MAC_OS_X_VERSION_10_1: u32 = 1010; pub const MAC_OS_X_VERSION_10_2: u32 = 1020; @@ -380,7 +384,7 @@ pub const MAC_OS_VERSION_13_0: u32 = 130000; pub const __DRIVERKIT_19_0: u32 = 190000; pub const __DRIVERKIT_20_0: u32 = 200000; pub const __DRIVERKIT_21_0: u32 = 210000; -pub const __MAC_OS_X_VERSION_MAX_ALLOWED: u32 = 130000; +pub const __MAC_OS_X_VERSION_MAX_ALLOWED: u32 = 130100; pub const __ENABLE_LEGACY_MAC_AVAILABILITY: u32 = 1; pub const __DARWIN_WCHAR_MIN: i32 = -2147483648; pub const _FORTIFY_SOURCE: u32 = 2; @@ -11062,8 +11066,8 @@ pub const DUCKDB_TYPE_DUCKDB_TYPE_LIST: DUCKDB_TYPE = 24; pub const DUCKDB_TYPE_DUCKDB_TYPE_STRUCT: DUCKDB_TYPE = 25; pub const DUCKDB_TYPE_DUCKDB_TYPE_MAP: DUCKDB_TYPE = 26; pub const DUCKDB_TYPE_DUCKDB_TYPE_UUID: DUCKDB_TYPE = 27; -pub const DUCKDB_TYPE_DUCKDB_TYPE_JSON: DUCKDB_TYPE = 28; -pub const DUCKDB_TYPE_DUCKDB_TYPE_UNION: DUCKDB_TYPE = 29; +pub const DUCKDB_TYPE_DUCKDB_TYPE_UNION: DUCKDB_TYPE = 28; +pub const DUCKDB_TYPE_DUCKDB_TYPE_BIT: DUCKDB_TYPE = 29; pub type DUCKDB_TYPE = ::std::os::raw::c_uint; pub use self::DUCKDB_TYPE as duckdb_type; #[doc = "! Days are stored as days since 1970-01-01\n! Use the duckdb_from_date/duckdb_to_date function to extract individual information"] @@ -11485,6 +11489,47 @@ fn bindgen_test_layout_duckdb_blob() { } #[repr(C)] #[derive(Debug, Copy, Clone)] +pub struct duckdb_list_entry { + pub offset: u64, + pub length: u64, +} +#[test] +fn bindgen_test_layout_duckdb_list_entry() { + const UNINIT: ::std::mem::MaybeUninit = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::(), + 16usize, + concat!("Size of: ", stringify!(duckdb_list_entry)) + ); + assert_eq!( + ::std::mem::align_of::(), + 8usize, + concat!("Alignment of ", stringify!(duckdb_list_entry)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).offset) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(duckdb_list_entry), + "::", + stringify!(offset) + ) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).length) as usize - ptr as usize }, + 8usize, + concat!( + "Offset of field: ", + stringify!(duckdb_list_entry), + "::", + stringify!(length) + ) + ); +} +#[repr(C)] +#[derive(Debug, Copy, Clone)] pub struct duckdb_column { pub __deprecated_data: *mut ::std::os::raw::c_void, pub __deprecated_nullmask: *mut bool, @@ -11642,19 +11687,430 @@ fn bindgen_test_layout_duckdb_result() { ) ); } -pub type duckdb_database = *mut ::std::os::raw::c_void; -pub type duckdb_connection = *mut ::std::os::raw::c_void; -pub type duckdb_prepared_statement = *mut ::std::os::raw::c_void; -pub type duckdb_pending_result = *mut ::std::os::raw::c_void; -pub type duckdb_appender = *mut ::std::os::raw::c_void; -pub type duckdb_arrow = *mut ::std::os::raw::c_void; -pub type duckdb_config = *mut ::std::os::raw::c_void; -pub type duckdb_arrow_schema = *mut ::std::os::raw::c_void; -pub type duckdb_arrow_array = *mut ::std::os::raw::c_void; -pub type duckdb_logical_type = *mut ::std::os::raw::c_void; -pub type duckdb_data_chunk = *mut ::std::os::raw::c_void; -pub type duckdb_vector = *mut ::std::os::raw::c_void; -pub type duckdb_value = *mut ::std::os::raw::c_void; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _duckdb_database { + pub __db: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout__duckdb_database() { + const UNINIT: ::std::mem::MaybeUninit<_duckdb_database> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_duckdb_database>(), + 8usize, + concat!("Size of: ", stringify!(_duckdb_database)) + ); + assert_eq!( + ::std::mem::align_of::<_duckdb_database>(), + 8usize, + concat!("Alignment of ", stringify!(_duckdb_database)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__db) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(_duckdb_database), + "::", + stringify!(__db) + ) + ); +} +pub type duckdb_database = *mut _duckdb_database; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _duckdb_connection { + pub __conn: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout__duckdb_connection() { + const UNINIT: ::std::mem::MaybeUninit<_duckdb_connection> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_duckdb_connection>(), + 8usize, + concat!("Size of: ", stringify!(_duckdb_connection)) + ); + assert_eq!( + ::std::mem::align_of::<_duckdb_connection>(), + 8usize, + concat!("Alignment of ", stringify!(_duckdb_connection)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__conn) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(_duckdb_connection), + "::", + stringify!(__conn) + ) + ); +} +pub type duckdb_connection = *mut _duckdb_connection; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _duckdb_prepared_statement { + pub __prep: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout__duckdb_prepared_statement() { + const UNINIT: ::std::mem::MaybeUninit<_duckdb_prepared_statement> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_duckdb_prepared_statement>(), + 8usize, + concat!("Size of: ", stringify!(_duckdb_prepared_statement)) + ); + assert_eq!( + ::std::mem::align_of::<_duckdb_prepared_statement>(), + 8usize, + concat!("Alignment of ", stringify!(_duckdb_prepared_statement)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__prep) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(_duckdb_prepared_statement), + "::", + stringify!(__prep) + ) + ); +} +pub type duckdb_prepared_statement = *mut _duckdb_prepared_statement; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _duckdb_extracted_statements { + pub __extrac: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout__duckdb_extracted_statements() { + const UNINIT: ::std::mem::MaybeUninit<_duckdb_extracted_statements> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_duckdb_extracted_statements>(), + 8usize, + concat!("Size of: ", stringify!(_duckdb_extracted_statements)) + ); + assert_eq!( + ::std::mem::align_of::<_duckdb_extracted_statements>(), + 8usize, + concat!("Alignment of ", stringify!(_duckdb_extracted_statements)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__extrac) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(_duckdb_extracted_statements), + "::", + stringify!(__extrac) + ) + ); +} +pub type duckdb_extracted_statements = *mut _duckdb_extracted_statements; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _duckdb_pending_result { + pub __pend: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout__duckdb_pending_result() { + const UNINIT: ::std::mem::MaybeUninit<_duckdb_pending_result> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_duckdb_pending_result>(), + 8usize, + concat!("Size of: ", stringify!(_duckdb_pending_result)) + ); + assert_eq!( + ::std::mem::align_of::<_duckdb_pending_result>(), + 8usize, + concat!("Alignment of ", stringify!(_duckdb_pending_result)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__pend) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(_duckdb_pending_result), + "::", + stringify!(__pend) + ) + ); +} +pub type duckdb_pending_result = *mut _duckdb_pending_result; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _duckdb_appender { + pub __appn: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout__duckdb_appender() { + const UNINIT: ::std::mem::MaybeUninit<_duckdb_appender> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_duckdb_appender>(), + 8usize, + concat!("Size of: ", stringify!(_duckdb_appender)) + ); + assert_eq!( + ::std::mem::align_of::<_duckdb_appender>(), + 8usize, + concat!("Alignment of ", stringify!(_duckdb_appender)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__appn) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(_duckdb_appender), + "::", + stringify!(__appn) + ) + ); +} +pub type duckdb_appender = *mut _duckdb_appender; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _duckdb_arrow { + pub __arrw: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout__duckdb_arrow() { + const UNINIT: ::std::mem::MaybeUninit<_duckdb_arrow> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_duckdb_arrow>(), + 8usize, + concat!("Size of: ", stringify!(_duckdb_arrow)) + ); + assert_eq!( + ::std::mem::align_of::<_duckdb_arrow>(), + 8usize, + concat!("Alignment of ", stringify!(_duckdb_arrow)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__arrw) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(_duckdb_arrow), "::", stringify!(__arrw)) + ); +} +pub type duckdb_arrow = *mut _duckdb_arrow; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _duckdb_config { + pub __cnfg: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout__duckdb_config() { + const UNINIT: ::std::mem::MaybeUninit<_duckdb_config> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_duckdb_config>(), + 8usize, + concat!("Size of: ", stringify!(_duckdb_config)) + ); + assert_eq!( + ::std::mem::align_of::<_duckdb_config>(), + 8usize, + concat!("Alignment of ", stringify!(_duckdb_config)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__cnfg) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(_duckdb_config), + "::", + stringify!(__cnfg) + ) + ); +} +pub type duckdb_config = *mut _duckdb_config; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _duckdb_arrow_schema { + pub __arrs: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout__duckdb_arrow_schema() { + const UNINIT: ::std::mem::MaybeUninit<_duckdb_arrow_schema> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_duckdb_arrow_schema>(), + 8usize, + concat!("Size of: ", stringify!(_duckdb_arrow_schema)) + ); + assert_eq!( + ::std::mem::align_of::<_duckdb_arrow_schema>(), + 8usize, + concat!("Alignment of ", stringify!(_duckdb_arrow_schema)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__arrs) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(_duckdb_arrow_schema), + "::", + stringify!(__arrs) + ) + ); +} +pub type duckdb_arrow_schema = *mut _duckdb_arrow_schema; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _duckdb_arrow_array { + pub __arra: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout__duckdb_arrow_array() { + const UNINIT: ::std::mem::MaybeUninit<_duckdb_arrow_array> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_duckdb_arrow_array>(), + 8usize, + concat!("Size of: ", stringify!(_duckdb_arrow_array)) + ); + assert_eq!( + ::std::mem::align_of::<_duckdb_arrow_array>(), + 8usize, + concat!("Alignment of ", stringify!(_duckdb_arrow_array)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__arra) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(_duckdb_arrow_array), + "::", + stringify!(__arra) + ) + ); +} +pub type duckdb_arrow_array = *mut _duckdb_arrow_array; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _duckdb_logical_type { + pub __lglt: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout__duckdb_logical_type() { + const UNINIT: ::std::mem::MaybeUninit<_duckdb_logical_type> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_duckdb_logical_type>(), + 8usize, + concat!("Size of: ", stringify!(_duckdb_logical_type)) + ); + assert_eq!( + ::std::mem::align_of::<_duckdb_logical_type>(), + 8usize, + concat!("Alignment of ", stringify!(_duckdb_logical_type)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__lglt) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(_duckdb_logical_type), + "::", + stringify!(__lglt) + ) + ); +} +pub type duckdb_logical_type = *mut _duckdb_logical_type; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _duckdb_data_chunk { + pub __dtck: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout__duckdb_data_chunk() { + const UNINIT: ::std::mem::MaybeUninit<_duckdb_data_chunk> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_duckdb_data_chunk>(), + 8usize, + concat!("Size of: ", stringify!(_duckdb_data_chunk)) + ); + assert_eq!( + ::std::mem::align_of::<_duckdb_data_chunk>(), + 8usize, + concat!("Alignment of ", stringify!(_duckdb_data_chunk)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__dtck) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(_duckdb_data_chunk), + "::", + stringify!(__dtck) + ) + ); +} +pub type duckdb_data_chunk = *mut _duckdb_data_chunk; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _duckdb_vector { + pub __vctr: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout__duckdb_vector() { + const UNINIT: ::std::mem::MaybeUninit<_duckdb_vector> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_duckdb_vector>(), + 8usize, + concat!("Size of: ", stringify!(_duckdb_vector)) + ); + assert_eq!( + ::std::mem::align_of::<_duckdb_vector>(), + 8usize, + concat!("Alignment of ", stringify!(_duckdb_vector)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__vctr) as usize - ptr as usize }, + 0usize, + concat!( + "Offset of field: ", + stringify!(_duckdb_vector), + "::", + stringify!(__vctr) + ) + ); +} +pub type duckdb_vector = *mut _duckdb_vector; +#[repr(C)] +#[derive(Debug, Copy, Clone)] +pub struct _duckdb_value { + pub __val: *mut ::std::os::raw::c_void, +} +#[test] +fn bindgen_test_layout__duckdb_value() { + const UNINIT: ::std::mem::MaybeUninit<_duckdb_value> = ::std::mem::MaybeUninit::uninit(); + let ptr = UNINIT.as_ptr(); + assert_eq!( + ::std::mem::size_of::<_duckdb_value>(), + 8usize, + concat!("Size of: ", stringify!(_duckdb_value)) + ); + assert_eq!( + ::std::mem::align_of::<_duckdb_value>(), + 8usize, + concat!("Alignment of ", stringify!(_duckdb_value)) + ); + assert_eq!( + unsafe { ::std::ptr::addr_of!((*ptr).__val) as usize - ptr as usize }, + 0usize, + concat!("Offset of field: ", stringify!(_duckdb_value), "::", stringify!(__val)) + ); +} +pub type duckdb_value = *mut _duckdb_value; pub const duckdb_state_DuckDBSuccess: duckdb_state = 0; pub const duckdb_state_DuckDBError: duckdb_state = 1; pub type duckdb_state = ::std::os::raw::c_uint; @@ -12111,6 +12567,33 @@ extern "C" { out_result: *mut duckdb_arrow, ) -> duckdb_state; } +extern "C" { + #[doc = "Extract all statements from a query.\nNote that after calling `duckdb_extract_statements`, the extracted statements should always be destroyed using\n`duckdb_destroy_extracted`, even if no statements were extracted.\nIf the extract fails, `duckdb_extract_statements_error` can be called to obtain the reason why the extract failed.\n connection: The connection object\n query: The SQL query to extract\n out_extracted_statements: The resulting extracted statements object\n returns: The number of extracted statements or 0 on failure."] + pub fn duckdb_extract_statements( + connection: duckdb_connection, + query: *const ::std::os::raw::c_char, + out_extracted_statements: *mut duckdb_extracted_statements, + ) -> idx_t; +} +extern "C" { + #[doc = "Prepare an extracted statement.\nNote that after calling `duckdb_prepare_extracted_statement`, the prepared statement should always be destroyed using\n`duckdb_destroy_prepare`, even if the prepare fails.\nIf the prepare fails, `duckdb_prepare_error` can be called to obtain the reason why the prepare failed.\n connection: The connection object\n extracted_statements: The extracted statements object\n index: The index of the extracted statement to prepare\n out_prepared_statement: The resulting prepared statement object\n returns: `DuckDBSuccess` on success or `DuckDBError` on failure."] + pub fn duckdb_prepare_extracted_statement( + connection: duckdb_connection, + extracted_statements: duckdb_extracted_statements, + index: idx_t, + out_prepared_statement: *mut duckdb_prepared_statement, + ) -> duckdb_state; +} +extern "C" { + #[doc = "Returns the error message contained within the extracted statements.\nThe result of this function must not be freed. It will be cleaned up when `duckdb_destroy_extracted` is called.\n result: The extracted statements to fetch the error from.\n returns: The error of the extracted statements."] + pub fn duckdb_extract_statements_error( + extracted_statements: duckdb_extracted_statements, + ) -> *const ::std::os::raw::c_char; +} +extern "C" { + #[doc = "De-allocates all memory allocated for the extracted statements.\n extracted_statements: The extracted statements to destroy."] + pub fn duckdb_destroy_extracted(extracted_statements: *mut duckdb_extracted_statements); +} extern "C" { #[doc = "Executes the prepared statement with the given bound parameters, and returns a pending result.\nThe pending result represents an intermediate structure for a query that is not yet fully executed.\nThe pending result can be used to incrementally execute a query, returning control to the client between tasks.\n\nNote that after calling `duckdb_pending_prepared`, the pending result should always be destroyed using\n`duckdb_destroy_pending`, even if this function returns DuckDBError.\n\n prepared_statement: The prepared statement to execute.\n out_result: The pending query result.\n returns: `DuckDBSuccess` on success or `DuckDBError` on failure."] pub fn duckdb_pending_prepared( @@ -12176,6 +12659,14 @@ extern "C" { value_type: duckdb_logical_type, ) -> duckdb_logical_type; } +extern "C" { + #[doc = "Creates a UNION type from the passed types array\nThe resulting type should be destroyed with `duckdb_destroy_logical_type`.\n\n types: The array of types that the union should consist of.\n type_amount: The size of the types array.\n returns: The logical type."] + pub fn duckdb_create_union_type( + member_types: duckdb_logical_type, + member_names: *mut *const ::std::os::raw::c_char, + member_count: idx_t, + ) -> duckdb_logical_type; +} extern "C" { #[doc = "Creates a `duckdb_logical_type` of type decimal with the specified width and scale\nThe resulting type should be destroyed with `duckdb_destroy_logical_type`.\n\n width: The width of the decimal type\n scale: The scale of the decimal type\n returns: The logical type."] pub fn duckdb_create_decimal_type(width: u8, scale: u8) -> duckdb_logical_type; @@ -12232,6 +12723,18 @@ extern "C" { #[doc = "Retrieves the child type of the given struct type at the specified index.\n\nThe result must be freed with `duckdb_destroy_logical_type`\n\n type: The logical type object\n index: The child index\n returns: The child type of the struct type. Must be destroyed with `duckdb_destroy_logical_type`."] pub fn duckdb_struct_type_child_type(type_: duckdb_logical_type, index: idx_t) -> duckdb_logical_type; } +extern "C" { + #[doc = "Returns the number of members that the union type has.\n\n type: The logical type (union) object\n returns: The number of members of a union type."] + pub fn duckdb_union_type_member_count(type_: duckdb_logical_type) -> idx_t; +} +extern "C" { + #[doc = "Retrieves the name of the union member.\n\nThe result must be freed with `duckdb_free`\n\n type: The logical type object\n index: The child index\n returns: The name of the union member. Must be freed with `duckdb_free`."] + pub fn duckdb_union_type_member_name(type_: duckdb_logical_type, index: idx_t) -> *mut ::std::os::raw::c_char; +} +extern "C" { + #[doc = "Retrieves the child type of the given union member at the specified index.\n\nThe result must be freed with `duckdb_destroy_logical_type`\n\n type: The logical type object\n index: The child index\n returns: The child type of the union member. Must be destroyed with `duckdb_destroy_logical_type`."] + pub fn duckdb_union_type_member_type(type_: duckdb_logical_type, index: idx_t) -> duckdb_logical_type; +} extern "C" { #[doc = "Destroys the logical type and de-allocates all memory allocated for that type.\n\n type: The logical type to destroy."] pub fn duckdb_destroy_logical_type(type_: *mut duckdb_logical_type); @@ -12305,6 +12808,14 @@ extern "C" { #[doc = "Returns the size of the child vector of the list\n\n vector: The vector\n returns: The size of the child list"] pub fn duckdb_list_vector_get_size(vector: duckdb_vector) -> idx_t; } +extern "C" { + #[doc = "Sets the total size of the underlying child-vector of a list vector.\n\n vector: The list vector.\n size: The size of the child list.\n returns: The duckdb state. Returns DuckDBError if the vector is nullptr."] + pub fn duckdb_list_vector_set_size(vector: duckdb_vector, size: idx_t) -> duckdb_state; +} +extern "C" { + #[doc = "Sets the total capacity of the underlying child-vector of a list.\n\n vector: The list vector.\n required_capacity: the total capacity to reserve.\n return: The duckdb state. Returns DuckDBError if the vector is nullptr."] + pub fn duckdb_list_vector_reserve(vector: duckdb_vector, required_capacity: idx_t) -> duckdb_state; +} extern "C" { #[doc = "Retrieves the child vector of a struct vector.\n\nThe resulting vector is valid as long as the parent vector is valid.\n\n vector: The vector\n index: The child index\n returns: The child vector"] pub fn duckdb_struct_vector_get_child(vector: duckdb_vector, index: idx_t) -> duckdb_vector; @@ -12695,6 +13206,10 @@ extern "C" { #[doc = "Destroys the task state returned from duckdb_create_task_state.\n\nNote that this should not be called while there is an active duckdb_execute_tasks_state running\non the task state.\n\n state: The task state to clean up"] pub fn duckdb_destroy_task_state(state: duckdb_task_state); } +extern "C" { + #[doc = "Returns true if execution of the current query is finished.\n\n con: The connection on which to check"] + pub fn duckdb_execution_is_finished(con: duckdb_connection) -> bool; +} pub type __builtin_va_list = [__va_list_tag; 1usize]; #[repr(C)] #[derive(Debug, Copy, Clone)] diff --git a/libduckdb-sys/duckdb/duckdb.cpp b/libduckdb-sys/duckdb/duckdb.cpp index 587816f7..1a7e3de7 100644 --- a/libduckdb-sys/duckdb/duckdb.cpp +++ b/libduckdb-sys/duckdb/duckdb.cpp @@ -30,32 +30,52 @@ namespace duckdb { class ClientContext; +struct CatalogSearchEntry { + CatalogSearchEntry(string catalog, string schema); + + string catalog; + string schema; + +public: + string ToString() const; + static string ListToString(const vector &input); + static CatalogSearchEntry Parse(const string &input); + static vector ParseList(const string &input); + +private: + static CatalogSearchEntry ParseInternal(const string &input, idx_t &pos); + static string WriteOptionallyQuoted(const string &input); +}; + //! The schema search path, in order by which entries are searched if no schema entry is provided class CatalogSearchPath { public: DUCKDB_API explicit CatalogSearchPath(ClientContext &client_p); CatalogSearchPath(const CatalogSearchPath &other) = delete; - DUCKDB_API void Set(const string &new_value, bool is_set_schema); - DUCKDB_API void Set(vector &new_paths, bool is_set_schema = false); + DUCKDB_API void Set(CatalogSearchEntry new_value, bool is_set_schema); + DUCKDB_API void Set(vector new_paths, bool is_set_schema = false); + DUCKDB_API void Reset(); - DUCKDB_API const vector &Get(); - DUCKDB_API const vector &GetSetPaths() { + DUCKDB_API const vector &Get(); + DUCKDB_API const vector &GetSetPaths() { return set_paths; } - DUCKDB_API const string &GetDefault(); - DUCKDB_API const string &GetOrDefault(const string &name); + DUCKDB_API const CatalogSearchEntry &GetDefault(); + DUCKDB_API string GetDefaultSchema(const string &catalog); + DUCKDB_API string GetDefaultCatalog(const string &schema); -private: - static vector ParsePaths(const string &value); + DUCKDB_API vector GetSchemasForCatalog(const string &catalog); + DUCKDB_API vector GetCatalogsForSchema(const string &schema); - void SetPaths(vector new_paths); +private: + void SetPaths(vector new_paths); private: ClientContext &context; - vector paths; + vector paths; //! Only the paths that were explicitly set (minus the always included paths) - vector set_paths; + vector set_paths; }; } // namespace duckdb @@ -89,28 +109,13 @@ class CatalogSearchPath { namespace duckdb { struct CreateAggregateFunctionInfo : public CreateFunctionInfo { - explicit CreateAggregateFunctionInfo(AggregateFunction function) - : CreateFunctionInfo(CatalogType::AGGREGATE_FUNCTION_ENTRY), functions(function.name) { - name = function.name; - functions.AddFunction(move(function)); - } - - explicit CreateAggregateFunctionInfo(AggregateFunctionSet set) - : CreateFunctionInfo(CatalogType::AGGREGATE_FUNCTION_ENTRY), functions(move(set)) { - name = functions.name; - for (auto &func : functions.functions) { - func.name = functions.name; - } - } + explicit CreateAggregateFunctionInfo(AggregateFunction function); + explicit CreateAggregateFunctionInfo(AggregateFunctionSet set); AggregateFunctionSet functions; public: - unique_ptr Copy() const override { - auto result = make_unique(functions); - CopyProperties(*result); - return move(result); - } + unique_ptr Copy() const override; }; } // namespace duckdb @@ -120,6 +125,10 @@ namespace duckdb { //! An aggregate function in the catalog class AggregateFunctionCatalogEntry : public StandardEntry { +public: + static constexpr const CatalogType Type = CatalogType::AGGREGATE_FUNCTION_ENTRY; + static constexpr const char *Name = "aggregate function"; + public: AggregateFunctionCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateAggregateFunctionInfo *info) : StandardEntry(CatalogType::AGGREGATE_FUNCTION_ENTRY, schema, catalog, info->name), @@ -159,11 +168,8 @@ class AggregateFunctionCatalogEntry : public StandardEntry { namespace duckdb { struct CreateCollationInfo : public CreateInfo { - CreateCollationInfo(string name_p, ScalarFunction function_p, bool combinable_p, bool not_required_for_equality_p) - : CreateInfo(CatalogType::COLLATION_ENTRY), function(move(function_p)), combinable(combinable_p), - not_required_for_equality(not_required_for_equality_p) { - this->name = move(name_p); - } + DUCKDB_API CreateCollationInfo(string name_p, ScalarFunction function_p, bool combinable_p, + bool not_required_for_equality_p); //! The name of the collation string name; @@ -177,16 +183,10 @@ struct CreateCollationInfo : public CreateInfo { bool not_required_for_equality; protected: - void SerializeInternal(Serializer &) const override { - throw NotImplementedException("Cannot serialize '%s'", CatalogTypeToString(type)); - } + void SerializeInternal(Serializer &) const override; public: - unique_ptr Copy() const override { - auto result = make_unique(name, function, combinable, not_required_for_equality); - CopyProperties(*result); - return move(result); - } + unique_ptr Copy() const override; }; } // namespace duckdb @@ -196,6 +196,10 @@ namespace duckdb { //! A collation catalog entry class CollateCatalogEntry : public StandardEntry { +public: + static constexpr const CatalogType Type = CatalogType::COLLATION_ENTRY; + static constexpr const char *Name = "collation"; + public: CollateCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateCollationInfo *info) : StandardEntry(CatalogType::COLLATION_ENTRY, schema, catalog, info->name), function(info->function), @@ -234,6 +238,10 @@ struct CreateCopyFunctionInfo; //! A table function in the catalog class CopyFunctionCatalogEntry : public StandardEntry { +public: + static constexpr const CatalogType Type = CatalogType::COPY_FUNCTION_ENTRY; + static constexpr const char *Name = "copy function"; + public: CopyFunctionCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateCopyFunctionInfo *info); @@ -316,9 +324,12 @@ namespace duckdb { //! Represents a TableReference to a base table in the schema class BaseTableRef : public TableRef { public: - BaseTableRef() : TableRef(TableReferenceType::BASE_TABLE), schema_name(INVALID_SCHEMA) { + BaseTableRef() + : TableRef(TableReferenceType::BASE_TABLE), catalog_name(INVALID_CATALOG), schema_name(INVALID_SCHEMA) { } + //! The catalog name + string catalog_name; //! Schema name string schema_name; //! Table name @@ -371,7 +382,7 @@ struct CreateIndexInfo : public CreateInfo { void SerializeInternal(Serializer &serializer) const override; public: - unique_ptr Copy() const override; + DUCKDB_API unique_ptr Copy() const override; static unique_ptr Deserialize(Deserializer &deserializer); }; @@ -491,7 +502,9 @@ class BlockManager { virtual idx_t FreeBlocks() = 0; //! Register a block with the given block id in the base file - shared_ptr RegisterBlock(block_id_t block_id); + shared_ptr RegisterBlock(block_id_t block_id, bool is_meta_block = false); + //! Clear cached handles for meta blocks + void ClearMetaBlockHandles(); //! Convert an existing in-memory buffer into a persistent disk-backed block shared_ptr ConvertToPersistent(block_id_t block_id, shared_ptr old_block); @@ -505,6 +518,8 @@ class BlockManager { mutex blocks_lock; //! A mapping of block id -> BlockHandle unordered_map> blocks; + //! A map to cache the BlockHandles of meta blocks + unordered_map> meta_blocks; }; } // namespace duckdb @@ -553,13 +568,15 @@ class Index; //! An index catalog entry class IndexCatalogEntry : public StandardEntry { +public: + static constexpr const CatalogType Type = CatalogType::INDEX_ENTRY; + static constexpr const char *Name = "index"; + public: //! Create an IndexCatalogEntry and initialize storage for it IndexCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateIndexInfo *info); - ~IndexCatalogEntry() override; Index *index; - shared_ptr info; string sql; vector> expressions; vector> parsed_expressions; @@ -568,6 +585,9 @@ class IndexCatalogEntry : public StandardEntry { string ToSQL() override; void Serialize(duckdb::MetaBlockWriter &serializer); static unique_ptr Deserialize(Deserializer &source, ClientContext &context); + + virtual string GetSchemaName() = 0; + virtual string GetTableName() = 0; }; } // namespace duckdb @@ -636,7 +656,7 @@ class ConstantExpression : public ParsedExpression { public: string ToString() const override; - static bool Equals(const ConstantExpression *a, const ConstantExpression *b); + static bool Equal(const ConstantExpression *a, const ConstantExpression *b); hash_t Hash() const override; unique_ptr Copy() const override; @@ -699,7 +719,7 @@ struct CreateMacroInfo : public CreateFunctionInfo { result->function = function->Copy(); result->name = name; CopyProperties(*result); - return move(result); + return std::move(result); } }; @@ -745,6 +765,10 @@ namespace duckdb { //! A macro function in the catalog class ScalarMacroCatalogEntry : public MacroCatalogEntry { +public: + static constexpr const CatalogType Type = CatalogType::MACRO_ENTRY; + static constexpr const char *Name = "macro function"; + public: ScalarMacroCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateMacroInfo *info); @@ -777,6 +801,10 @@ struct CreatePragmaFunctionInfo; //! A table function in the catalog class PragmaFunctionCatalogEntry : public StandardEntry { +public: + static constexpr const CatalogType Type = CatalogType::PRAGMA_FUNCTION_ENTRY; + static constexpr const char *Name = "pragma function"; + public: PragmaFunctionCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreatePragmaFunctionInfo *info); @@ -832,6 +860,10 @@ namespace duckdb { //! A table function in the catalog class ScalarFunctionCatalogEntry : public StandardEntry { +public: + static constexpr const CatalogType Type = CatalogType::SCALAR_FUNCTION_ENTRY; + static constexpr const char *Name = "scalar function"; + public: ScalarFunctionCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateScalarFunctionInfo *info); @@ -845,7 +877,436 @@ class ScalarFunctionCatalogEntry : public StandardEntry { +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/catalog/catalog_entry/table_catalog_entry.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/column_list.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +//! A set of column definitions +class ColumnList { +public: + class ColumnListIterator; + +public: + DUCKDB_API ColumnList(bool allow_duplicate_names = false); + + DUCKDB_API void AddColumn(ColumnDefinition column); + void Finalize(); + + DUCKDB_API const ColumnDefinition &GetColumn(LogicalIndex index) const; + DUCKDB_API const ColumnDefinition &GetColumn(PhysicalIndex index) const; + DUCKDB_API const ColumnDefinition &GetColumn(const string &name) const; + DUCKDB_API ColumnDefinition &GetColumnMutable(LogicalIndex index); + DUCKDB_API ColumnDefinition &GetColumnMutable(PhysicalIndex index); + DUCKDB_API ColumnDefinition &GetColumnMutable(const string &name); + DUCKDB_API vector GetColumnNames() const; + DUCKDB_API vector GetColumnTypes() const; + + DUCKDB_API bool ColumnExists(const string &name) const; + + DUCKDB_API LogicalIndex GetColumnIndex(string &column_name) const; + DUCKDB_API PhysicalIndex LogicalToPhysical(LogicalIndex index) const; + DUCKDB_API LogicalIndex PhysicalToLogical(PhysicalIndex index) const; + + idx_t LogicalColumnCount() const { + return columns.size(); + } + idx_t PhysicalColumnCount() const { + return physical_columns.size(); + } + bool empty() const { + return columns.empty(); + } + + ColumnList Copy() const; + void Serialize(FieldWriter &writer) const; + static ColumnList Deserialize(FieldReader &reader); + + DUCKDB_API ColumnListIterator Logical() const; + DUCKDB_API ColumnListIterator Physical() const; + + void SetAllowDuplicates(bool allow_duplicates) { + allow_duplicate_names = allow_duplicates; + } + +private: + vector columns; + //! A map of column name to column index + case_insensitive_map_t name_map; + //! The set of physical columns + vector physical_columns; + //! Allow duplicate names or not + bool allow_duplicate_names; + +private: + void AddToNameMap(ColumnDefinition &column); + +public: + // logical iterator + class ColumnListIterator { + public: + DUCKDB_API ColumnListIterator(const ColumnList &list, bool physical) : list(list), physical(physical) { + } + + private: + const ColumnList &list; + bool physical; + + private: + class ColumnLogicalIteratorInternal { + public: + DUCKDB_API ColumnLogicalIteratorInternal(const ColumnList &list, bool physical, idx_t pos, idx_t end) + : list(list), physical(physical), pos(pos), end(end) { + } + + const ColumnList &list; + bool physical; + idx_t pos; + idx_t end; + + public: + DUCKDB_API ColumnLogicalIteratorInternal &operator++() { + pos++; + return *this; + } + DUCKDB_API bool operator!=(const ColumnLogicalIteratorInternal &other) const { + return pos != other.pos || end != other.end || &list != &other.list; + } + DUCKDB_API const ColumnDefinition &operator*() const { + if (physical) { + return list.GetColumn(PhysicalIndex(pos)); + } else { + return list.GetColumn(LogicalIndex(pos)); + } + } + }; + + public: + idx_t Size() { + return physical ? list.PhysicalColumnCount() : list.LogicalColumnCount(); + } + + DUCKDB_API ColumnLogicalIteratorInternal begin() { + return ColumnLogicalIteratorInternal(list, physical, 0, Size()); + } + DUCKDB_API ColumnLogicalIteratorInternal end() { + return ColumnLogicalIteratorInternal(list, physical, Size(), Size()); + } + }; +}; + +} // namespace duckdb + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/bound_constraint.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + +namespace duckdb { +//! Bound equivalent of Constraint +class BoundConstraint { +public: + explicit BoundConstraint(ConstraintType type) : type(type) {}; + virtual ~BoundConstraint() { + } + + void Serialize(Serializer &serializer) const { + serializer.Write(type); + } + + static unique_ptr Deserialize(Deserializer &source) { + return make_unique(source.Read()); + } + + ConstraintType type; +}; +} // namespace duckdb + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/catalog/catalog_entry/column_dependency_manager.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/stack.hpp +// +// +//===----------------------------------------------------------------------===// + + + +#include + +namespace duckdb { +using std::stack; +} + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/index_map.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + +namespace duckdb { + +struct LogicalIndexHashFunction { + uint64_t operator()(const LogicalIndex &index) const { + return std::hash()(index.index); + } +}; + +struct PhysicalIndexHashFunction { + uint64_t operator()(const PhysicalIndex &index) const { + return std::hash()(index.index); + } +}; + +template +using logical_index_map_t = unordered_map; + +using logical_index_set_t = unordered_set; + +template +using physical_index_map_t = unordered_map; + +using physical_index_set_t = unordered_set; + +} // namespace duckdb + + +namespace duckdb { + +//! Dependency Manager local to a table, responsible for keeping track of generated column dependencies + +class ColumnDependencyManager { +public: + DUCKDB_API ColumnDependencyManager(); + DUCKDB_API ~ColumnDependencyManager(); + DUCKDB_API ColumnDependencyManager(ColumnDependencyManager &&other) = default; + ColumnDependencyManager(const ColumnDependencyManager &other) = delete; + +public: + //! Get the bind order that ensures dependencies are resolved before dependents are + stack GetBindOrder(const ColumnList &columns); + + //! Adds a connection between the dependent and its dependencies + void AddGeneratedColumn(LogicalIndex index, const vector &indices, bool root = true); + //! Add a generated column from a column definition + void AddGeneratedColumn(const ColumnDefinition &column, const ColumnList &list); + + //! Removes the column(s) and outputs the new column indices + vector RemoveColumn(LogicalIndex index, idx_t column_amount); + + bool IsDependencyOf(LogicalIndex dependent, LogicalIndex dependency) const; + bool HasDependencies(LogicalIndex index) const; + const logical_index_set_t &GetDependencies(LogicalIndex index) const; + + bool HasDependents(LogicalIndex index) const; + const logical_index_set_t &GetDependents(LogicalIndex index) const; + +private: + void RemoveStandardColumn(LogicalIndex index); + void RemoveGeneratedColumn(LogicalIndex index); + + void AdjustSingle(LogicalIndex idx, idx_t offset); + // Clean up the gaps created by a Remove operation + vector CleanupInternals(idx_t column_amount); + +private: + //! A map of column dependency to generated column(s) + logical_index_map_t dependencies_map; + //! A map of generated column name to (potentially generated)column dependencies + logical_index_map_t dependents_map; + //! For resolve-order purposes, keep track of the 'direct' (not inherited) dependencies of a generated column + logical_index_map_t direct_dependencies; + logical_index_set_t deleted_columns; +}; + +} // namespace duckdb + + +namespace duckdb { + +class DataTable; +struct CreateTableInfo; +struct BoundCreateTableInfo; + +struct RenameColumnInfo; +struct AddColumnInfo; +struct RemoveColumnInfo; +struct SetDefaultInfo; +struct ChangeColumnTypeInfo; +struct AlterForeignKeyInfo; +struct SetNotNullInfo; +struct DropNotNullInfo; + +class TableFunction; +struct FunctionData; + +class TableColumnInfo; +class TableIndexInfo; +class TableStorageInfo; + +//! A table catalog entry +class TableCatalogEntry : public StandardEntry { +public: + static constexpr const CatalogType Type = CatalogType::TABLE_ENTRY; + static constexpr const char *Name = "table"; + +public: + //! Create a TableCatalogEntry and initialize storage for it + DUCKDB_API TableCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateTableInfo &info); + +public: + DUCKDB_API bool HasGeneratedColumns() const; + + //! Returns whether or not a column with the given name exists + DUCKDB_API bool ColumnExists(const string &name); + //! Returns a reference to the column of the specified name. Throws an + //! exception if the column does not exist. + DUCKDB_API const ColumnDefinition &GetColumn(const string &name); + //! Returns a reference to the column of the specified logical index. Throws an + //! exception if the column does not exist. + DUCKDB_API const ColumnDefinition &GetColumn(LogicalIndex idx); + //! Returns a list of types of the table, excluding generated columns + DUCKDB_API vector GetTypes(); + //! Returns a list of the columns of the table + DUCKDB_API const ColumnList &GetColumns() const; + //! Returns a mutable list of the columns of the table + DUCKDB_API ColumnList &GetColumnsMutable(); + //! Returns the underlying storage of the table + virtual DataTable &GetStorage(); + virtual DataTable *GetStoragePtr(); + //! Returns a list of the bound constraints of the table + virtual const vector> &GetBoundConstraints(); + + //! Returns a list of the constraints of the table + DUCKDB_API const vector> &GetConstraints(); + DUCKDB_API string ToSQL() override; + + //! Get statistics of a column (physical or virtual) within the table + virtual unique_ptr GetStatistics(ClientContext &context, column_t column_id) = 0; + + //! Serialize the meta information of the TableCatalogEntry a serializer + virtual void Serialize(Serializer &serializer); + //! Deserializes to a CreateTableInfo + static unique_ptr Deserialize(Deserializer &source, ClientContext &context); + //! Returns the column index of the specified column name. + //! If the column does not exist: + //! If if_column_exists is true, returns DConstants::INVALID_INDEX + //! If if_column_exists is false, throws an exception + DUCKDB_API LogicalIndex GetColumnIndex(string &name, bool if_exists = false); + + //! Returns the scan function that can be used to scan the given table + virtual TableFunction GetScanFunction(ClientContext &context, unique_ptr &bind_data) = 0; + + virtual bool IsDuckTable() { + return false; + } + + DUCKDB_API static string ColumnsToSQL(const ColumnList &columns, const vector> &constraints); + + //! Returns the storage info of this table + virtual TableStorageInfo GetStorageInfo(ClientContext &context) = 0; + +protected: + //! A list of columns that are part of this table + ColumnList columns; + //! A list of constraints that are part of this table + vector> constraints; +}; +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/catalog/catalog_entry/table_function_catalog_entry.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + + +namespace duckdb { + +class Catalog; +class Constraint; + +struct CreateTableFunctionInfo; + +//! A table function in the catalog +class TableFunctionCatalogEntry : public StandardEntry { +public: + static constexpr const CatalogType Type = CatalogType::TABLE_FUNCTION_ENTRY; + static constexpr const char *Name = "table function"; + +public: + TableFunctionCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateTableFunctionInfo *info); + + //! The table function + TableFunctionSet functions; +}; +} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB @@ -869,6 +1330,10 @@ struct CreateViewInfo; //! A view catalog entry class ViewCatalogEntry : public StandardEntry { +public: + static constexpr const CatalogType Type = CatalogType::VIEW_ENTRY; + static constexpr const char *Name = "view"; + public: //! Create a real TableCatalogEntry and initialize storage for it ViewCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateViewInfo *info); @@ -926,109 +1391,6 @@ class DefaultSchemaGenerator : public DefaultGenerator { } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/catalog/dependency_manager.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/catalog/dependency.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -namespace duckdb { -class CatalogEntry; - -enum class DependencyType { - DEPENDENCY_REGULAR = 0, - DEPENDENCY_AUTOMATIC = 1, - DEPENDENCY_OWNS = 2, - DEPENDENCY_OWNED_BY = 3 -}; - -struct Dependency { - Dependency(CatalogEntry *entry, DependencyType dependency_type = DependencyType::DEPENDENCY_REGULAR) - : // NOLINT: Allow implicit conversion from `CatalogEntry` - entry(entry), dependency_type(dependency_type) { - } - - //! The catalog entry this depends on - CatalogEntry *entry; - //! The type of dependency - DependencyType dependency_type; -}; - -struct DependencyHashFunction { - uint64_t operator()(const Dependency &a) const { - std::hash hash_func; - return hash_func((void *)a.entry); - } -}; - -struct DependencyEquality { - bool operator()(const Dependency &a, const Dependency &b) const { - return a.entry == b.entry; - } -}; - -using dependency_set_t = unordered_set; - -} // namespace duckdb - - -#include - -namespace duckdb { -class Catalog; -class ClientContext; - -//! The DependencyManager is in charge of managing dependencies between catalog entries -class DependencyManager { - friend class CatalogSet; - -public: - explicit DependencyManager(Catalog &catalog); - - //! Erase the object from the DependencyManager; this should only happen when the object itself is destroyed - void EraseObject(CatalogEntry *object); - - //! Scans all dependencies, returning pairs of (object, dependent) - void Scan(const std::function &callback); - - void AddOwnership(ClientContext &context, CatalogEntry *owner, CatalogEntry *entry); - -private: - Catalog &catalog; - //! Map of objects that DEPEND on [object], i.e. [object] can only be deleted when all entries in the dependency map - //! are deleted. - unordered_map dependents_map; - //! Map of objects that the source object DEPENDS on, i.e. when any of the entries in the vector perform a CASCADE - //! drop then [object] is deleted as well - unordered_map> dependencies_map; - -private: - void AddObject(ClientContext &context, CatalogEntry *object, unordered_set &dependencies); - void DropObject(ClientContext &context, CatalogEntry *object, bool cascade); - void AlterObject(ClientContext &context, CatalogEntry *old_obj, CatalogEntry *new_obj); - void EraseObjectInternal(CatalogEntry *object); -}; -} // namespace duckdb - //===----------------------------------------------------------------------===// // DuckDB // @@ -1062,7 +1424,7 @@ struct CreateTypeInfo : public CreateInfo { CreateTypeInfo() : CreateInfo(CatalogType::TYPE_ENTRY) { } CreateTypeInfo(string name_p, LogicalType type_p) - : CreateInfo(CatalogType::TYPE_ENTRY), name(move(name_p)), type(move(type_p)) { + : CreateInfo(CatalogType::TYPE_ENTRY), name(std::move(name_p)), type(std::move(type_p)) { } //! Name of the Type @@ -1081,7 +1443,7 @@ struct CreateTypeInfo : public CreateInfo { if (query) { result->query = query->Copy(); } - return move(result); + return std::move(result); } protected: @@ -1099,6 +1461,10 @@ class Deserializer; //! A type catalog entry class TypeCatalogEntry : public StandardEntry { +public: + static constexpr const CatalogType Type = CatalogType::TYPE_ENTRY; + static constexpr const char *Name = "type"; + public: //! Create a TypeCatalogEntry and initialize storage for it TypeCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateTypeInfo *info); @@ -1132,11 +1498,14 @@ class TypeCatalogEntry : public StandardEntry { + namespace duckdb { +class AttachedDatabase; class BufferedFileWriter; class ClientContext; class CatalogSearchPath; class FileOpener; +class HTTPStats; class QueryProfiler; class QueryProfilerHistory; class PreparedStatementData; @@ -1153,7 +1522,7 @@ struct ClientData { unique_ptr query_profiler_history; //! The set of temporary objects that belong to this client - shared_ptr temporary_objects; + shared_ptr temporary_objects; //! The set of bound prepared statements that belong to this client unordered_map> prepared_statements; @@ -1168,6 +1537,9 @@ struct ClientData { //! The file opener of the client context unique_ptr file_opener; + //! Statistics on HTTP traffic + unique_ptr http_stats; + //! The file search path string file_search_path; @@ -1196,7 +1568,7 @@ namespace duckdb { //! Represents a function call class FunctionExpression : public ParsedExpression { public: - DUCKDB_API FunctionExpression(string schema_name, const string &function_name, + DUCKDB_API FunctionExpression(string catalog_name, string schema_name, const string &function_name, vector> children, unique_ptr filter = nullptr, unique_ptr order_bys = nullptr, bool distinct = false, @@ -1206,6 +1578,8 @@ class FunctionExpression : public ParsedExpression { unique_ptr order_bys = nullptr, bool distinct = false, bool is_operator = false, bool export_state = false); + //! Catalog of the function + string catalog; //! Schema of the function string schema; //! Function name @@ -1228,7 +1602,7 @@ class FunctionExpression : public ParsedExpression { unique_ptr Copy() const override; - static bool Equals(const FunctionExpression *a, const FunctionExpression *b); + static bool Equal(const FunctionExpression *a, const FunctionExpression *b); hash_t Hash() const override; void Serialize(FieldWriter &writer) const override; @@ -1246,8 +1620,8 @@ class FunctionExpression : public ParsedExpression { D_ASSERT(!distinct); if (entry.children.size() == 1) { if (StringUtil::Contains(function_name, "__postfix")) { - return "(" + entry.children[0]->ToString() + ")" + - StringUtil::Replace(function_name, "__postfix", ""); + return "((" + entry.children[0]->ToString() + ")" + + StringUtil::Replace(function_name, "__postfix", "") + ")"; } else { return function_name + "(" + entry.children[0]->ToString() + ")"; } @@ -1318,24 +1692,13 @@ class FunctionExpression : public ParsedExpression { namespace duckdb { struct CreatePragmaFunctionInfo : public CreateFunctionInfo { - explicit CreatePragmaFunctionInfo(PragmaFunction function) - : CreateFunctionInfo(CatalogType::PRAGMA_FUNCTION_ENTRY), functions(function.name) { - name = function.name; - functions.AddFunction(move(function)); - } - CreatePragmaFunctionInfo(string name, PragmaFunctionSet functions_) - : CreateFunctionInfo(CatalogType::PRAGMA_FUNCTION_ENTRY), functions(functions_) { - this->name = name; - } + DUCKDB_API explicit CreatePragmaFunctionInfo(PragmaFunction function); + DUCKDB_API CreatePragmaFunctionInfo(string name, PragmaFunctionSet functions_); PragmaFunctionSet functions; public: - unique_ptr Copy() const override { - auto result = make_unique(functions.name, functions); - CopyProperties(*result); - return move(result); - } + DUCKDB_API unique_ptr Copy() const override; }; } // namespace duckdb @@ -1363,7 +1726,7 @@ struct CreateSchemaInfo : public CreateInfo { unique_ptr Copy() const override { auto result = make_unique(); CopyProperties(*result); - return move(result); + return std::move(result); } static unique_ptr Deserialize(Deserializer &deserializer) { @@ -1396,13 +1759,12 @@ struct CreateSchemaInfo : public CreateInfo { namespace duckdb { +class SchemaCatalogEntry; struct CreateViewInfo : public CreateInfo { - CreateViewInfo() : CreateInfo(CatalogType::VIEW_ENTRY, INVALID_SCHEMA) { - } - CreateViewInfo(string schema, string view_name) - : CreateInfo(CatalogType::VIEW_ENTRY, schema), view_name(view_name) { - } + CreateViewInfo(); + CreateViewInfo(SchemaCatalogEntry *schema, string view_name); + CreateViewInfo(string catalog_p, string schema_p, string view_name); //! Table name to insert to string view_name; @@ -1414,38 +1776,17 @@ struct CreateViewInfo : public CreateInfo { unique_ptr query; public: - unique_ptr Copy() const override { - auto result = make_unique(schema, view_name); - CopyProperties(*result); - result->aliases = aliases; - result->types = types; - result->query = unique_ptr_cast(query->Copy()); - return move(result); - } - - static unique_ptr Deserialize(Deserializer &deserializer) { - auto result = make_unique(); - result->DeserializeBase(deserializer); + unique_ptr Copy() const override; - FieldReader reader(deserializer); - result->view_name = reader.ReadRequired(); - result->aliases = reader.ReadRequiredList(); - result->types = reader.ReadRequiredSerializableList(); - result->query = reader.ReadOptional(nullptr); - reader.Finalize(); + static unique_ptr Deserialize(Deserializer &deserializer); - return result; - } + //! Gets a bound CreateViewInfo object from a SELECT statement and a view name, schema name, etc + DUCKDB_API static unique_ptr FromSelect(ClientContext &context, unique_ptr info); + //! Gets a bound CreateViewInfo object from a CREATE VIEW statement + DUCKDB_API static unique_ptr FromCreateView(ClientContext &context, const string &sql); protected: - void SerializeInternal(Serializer &serializer) const override { - FieldWriter writer(serializer); - writer.WriteString(view_name); - writer.WriteList(aliases); - writer.WriteRegularSerializableList(types); - writer.WriteOptional(query); - writer.Finalize(); - } + void SerializeInternal(Serializer &serializer) const override; }; } // namespace duckdb @@ -1463,14 +1804,17 @@ struct CreateViewInfo : public CreateInfo { + namespace duckdb { struct DropInfo : public ParseInfo { - DropInfo() : schema(INVALID_SCHEMA), if_exists(false), cascade(false) { + DropInfo() : catalog(INVALID_CATALOG), schema(INVALID_SCHEMA), if_exists(false), cascade(false) { } //! The catalog type to drop CatalogType type; + //! Catalog name to drop from, if any + string catalog; //! Schema name to drop from, if any string schema; //! Element name to drop @@ -1480,17 +1824,47 @@ struct DropInfo : public ParseInfo { //! Cascade drop (drop all dependents instead of throwing an error if there //! are any) bool cascade = false; + //! Allow dropping of internal system entries + bool allow_drop_internal = false; public: unique_ptr Copy() const { auto result = make_unique(); result->type = type; + result->catalog = catalog; result->schema = schema; result->name = name; result->if_exists = if_exists; result->cascade = cascade; + result->allow_drop_internal = allow_drop_internal; return result; } + + void Serialize(Serializer &serializer) const { + FieldWriter writer(serializer); + writer.WriteField(type); + writer.WriteString(catalog); + writer.WriteString(schema); + writer.WriteString(name); + writer.WriteField(if_exists); + writer.WriteField(cascade); + writer.WriteField(allow_drop_internal); + writer.Finalize(); + } + + static unique_ptr Deserialize(Deserializer &deserializer) { + FieldReader reader(deserializer); + auto drop_info = make_unique(); + drop_info->type = reader.ReadRequired(); + drop_info->catalog = reader.ReadRequired(); + drop_info->schema = reader.ReadRequired(); + drop_info->name = reader.ReadRequired(); + drop_info->if_exists = reader.ReadRequired(); + drop_info->cascade = reader.ReadRequired(); + drop_info->allow_drop_internal = reader.ReadRequired(); + reader.Finalize(); + return std::move(drop_info); + } }; } // namespace duckdb @@ -1524,10 +1898,12 @@ struct DropInfo : public ParseInfo { namespace duckdb { +class SchemaCatalogEntry; struct CreateTableInfo : public CreateInfo { DUCKDB_API CreateTableInfo(); - DUCKDB_API CreateTableInfo(string schema, string name); + DUCKDB_API CreateTableInfo(string catalog, string schema, string name); + DUCKDB_API CreateTableInfo(SchemaCatalogEntry *schema, string name); //! Table name to insert to string table; @@ -1649,9 +2025,12 @@ class SegmentBase { } virtual ~SegmentBase() { } - SegmentBase *Next() { +#ifndef DUCKDB_R_BUILD return next.load(); +#else + return next; +#endif } //! The start row id of this chunk @@ -1659,7 +2038,12 @@ class SegmentBase { //! The amount of entries in this storage chunk atomic count; //! The next segment after this one + +#ifndef DUCKDB_R_BUILD atomic next; +#else + SegmentBase *next; +#endif }; } // namespace duckdb @@ -1984,7 +2368,7 @@ struct CompressedSegmentState { }; struct CompressionAppendState { - CompressionAppendState(BufferHandle handle_p) : handle(move(handle_p)) { + CompressionAppendState(BufferHandle handle_p) : handle(std::move(handle_p)) { } virtual ~CompressionAppendState() { } @@ -2421,8 +2805,8 @@ class BoundCastExpression : public Expression { static unique_ptr AddDefaultCastToType(unique_ptr expr, const LogicalType &target_type, bool try_cast = false); //! Cast an expression to the specified SQL type if required - static unique_ptr AddCastToType(ClientContext &context, unique_ptr expr, - const LogicalType &target_type, bool try_cast = false); + DUCKDB_API static unique_ptr AddCastToType(ClientContext &context, unique_ptr expr, + const LogicalType &target_type, bool try_cast = false); //! Returns true if a cast is invertible (i.e. CAST(s -> t -> s) = s for all values of s). This is not true for e.g. //! boolean casts, because that can be e.g. -1 -> TRUE -> 1. This is necessary to prevent some optimizer bugs. static bool CastIsInvertible(const LogicalType &source_type, const LogicalType &target_type); @@ -2675,7 +3059,7 @@ class LambdaExpression : public ParsedExpression { public: string ToString() const override; - static bool Equals(const LambdaExpression *a, const LambdaExpression *b); + static bool Equal(const LambdaExpression *a, const LambdaExpression *b); hash_t Hash() const override; unique_ptr Copy() const override; @@ -2772,7 +3156,7 @@ namespace duckdb { struct BoundParameterData { BoundParameterData() { } - BoundParameterData(Value val) : value(move(val)), return_type(value.type()) { + BoundParameterData(Value val) : value(std::move(val)), return_type(value.type()) { } Value value; @@ -2789,7 +3173,7 @@ struct BoundParameterData { static shared_ptr Deserialize(Deserializer &source) { FieldReader reader(source); auto value = Value::Deserialize(reader.GetSource()); - auto result = make_shared(move(value)); + auto result = make_shared(std::move(value)); result->return_type = reader.ReadRequiredSerializable(); reader.Finalize(); return result; @@ -3095,8 +3479,10 @@ enum class WindowBoundary : uint8_t { //! they inherit from them. class WindowExpression : public ParsedExpression { public: - WindowExpression(ExpressionType type, string schema_name, const string &function_name); + WindowExpression(ExpressionType type, string catalog_name, string schema_name, const string &function_name); + //! Catalog of the aggregate function + string catalog; //! Schema of the aggregate function string schema; //! Name of the aggregate function @@ -3129,7 +3515,7 @@ class WindowExpression : public ParsedExpression { //! Convert the Expression to a String string ToString() const override; - static bool Equals(const WindowExpression *a, const WindowExpression *b); + static bool Equal(const WindowExpression *a, const WindowExpression *b); unique_ptr Copy() const override; @@ -3367,6 +3753,7 @@ class ColumnSegment; class ValiditySegment; class TableFilterSet; class ColumnData; +class DuckTransaction; struct SegmentScanState { virtual ~SegmentScanState() { @@ -3398,7 +3785,7 @@ struct ColumnScanState { //! The version of the column data that we are scanning. //! This is used to detect if the ColumnData has been changed out from under us during a scan //! If this is the case, we re-initialize the scan - idx_t version; + idx_t version = 0; //! We initialize one SegmentScanState per segment, however, if scanning a DataChunk requires us to scan over more //! than one Segment, we need to keep the scan states of the previous segments around vector> previous_states; @@ -3463,7 +3850,7 @@ class CollectionScanState { const vector &GetColumnIds(); TableFilterSet *GetFilters(); AdaptiveFilter *GetAdaptiveFilter(); - bool Scan(Transaction &transaction, DataChunk &result); + bool Scan(DuckTransaction &transaction, DataChunk &result); bool ScanCommitted(DataChunk &result, TableScanType type); private: @@ -3557,6 +3944,7 @@ class SegmentStatistics { namespace duckdb { +class AttachedDatabase; class BlockManager; class ColumnData; class DatabaseInstance; @@ -3566,6 +3954,7 @@ struct DataTableInfo; class ExpressionExecutor; class RowGroupWriter; class UpdateSegment; +class TableStorageInfo; class Vector; struct ColumnCheckpointState; struct RowGroupPointer; @@ -3587,15 +3976,15 @@ class RowGroup : public SegmentBase { static constexpr const idx_t ROW_GROUP_VECTOR_COUNT = ROW_GROUP_SIZE / STANDARD_VECTOR_SIZE; public: - RowGroup(DatabaseInstance &db, BlockManager &block_manager, DataTableInfo &table_info, idx_t start, idx_t count); - RowGroup(DatabaseInstance &db, BlockManager &block_manager, DataTableInfo &table_info, + RowGroup(AttachedDatabase &db, BlockManager &block_manager, DataTableInfo &table_info, idx_t start, idx_t count); + RowGroup(AttachedDatabase &db, BlockManager &block_manager, DataTableInfo &table_info, const vector &types, RowGroupPointer &&pointer); RowGroup(RowGroup &row_group, idx_t start); ~RowGroup(); private: //! The database instance - DatabaseInstance &db; + AttachedDatabase &db; //! The block manager BlockManager &block_manager; //! The table info of this row_group @@ -3608,9 +3997,7 @@ class RowGroup : public SegmentBase { vector> stats; public: - DatabaseInstance &GetDatabase() { - return db; - } + DatabaseInstance &GetDatabase(); BlockManager &GetBlockManager() { return block_manager; } @@ -3688,7 +4075,7 @@ class RowGroup : public SegmentBase { void MergeIntoStatistics(idx_t column_idx, BaseStatistics &other); unique_ptr GetStatistics(idx_t column_idx); - void GetStorageInfo(idx_t row_group_index, vector> &result); + void GetStorageInfo(idx_t row_group_index, TableStorageInfo &result); void Verify(); @@ -4862,17 +5249,17 @@ struct Comparators { static int TemplatedCompareVal(const data_ptr_t &left_ptr, const data_ptr_t &right_ptr); //! Compare two values at the pointers (can be recursive if nested type) - static int CompareValAndAdvance(data_ptr_t &l_ptr, data_ptr_t &r_ptr, const LogicalType &type); + static int CompareValAndAdvance(data_ptr_t &l_ptr, data_ptr_t &r_ptr, const LogicalType &type, bool valid); //! Compares two fixed-size values at the given pointers template static int TemplatedCompareAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr); //! Compares two string values at the given pointers - static int CompareStringAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr); + static int CompareStringAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr, bool valid); //! Compares two struct values at the given pointers (recursive) static int CompareStructAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr, - const child_list_t &types); + const child_list_t &types, bool valid); //! Compare two list values at the pointers (can be recursive if nested type) - static int CompareListAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr, const LogicalType &type); + static int CompareListAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr, const LogicalType &type, bool valid); //! Compares a list of fixed-size values template static int TemplatedCompareListLoop(data_ptr_t &left_ptr, data_ptr_t &right_ptr, const ValidityBytes &left_validity, @@ -4968,6 +5355,9 @@ struct RowDataCollectionScanner { //! Scans the next data chunk from the sorted data void Scan(DataChunk &chunk); + //! Resets to the start and updates the flush flag + void Reset(bool flush = true); + private: //! The row data being scanned RowDataCollection &rows; @@ -4986,7 +5376,7 @@ struct RowDataCollectionScanner { //! Whether the blocks can be flushed to disk const bool external; //! Whether to flush the blocks after scanning - const bool flush; + bool flush; //! Whether we are unswizzling the blocks const bool unswizzling; @@ -5120,7 +5510,7 @@ struct PayloadScanner { explicit PayloadScanner(GlobalSortState &global_sort_state, bool flush = true); //! Scan a single block - PayloadScanner(GlobalSortState &global_sort_state, idx_t block_idx); + PayloadScanner(GlobalSortState &global_sort_state, idx_t block_idx, bool flush = false); //! The type layout of the payload inline const vector &GetPayloadTypes() const { @@ -5420,16 +5810,24 @@ class BufferManager { //! blocks can be evicted void SetLimit(idx_t limit = (idx_t)-1); - static BufferManager &GetBufferManager(ClientContext &context); + DUCKDB_API static BufferManager &GetBufferManager(ClientContext &context); DUCKDB_API static BufferManager &GetBufferManager(DatabaseInstance &db); + DUCKDB_API static BufferManager &GetBufferManager(AttachedDatabase &db); + //! Returns the currently allocated memory idx_t GetUsedMemory() { return current_memory; } + //! Returns the maximum available memory idx_t GetMaxMemory() { return maximum_memory; } + //! Increases the currently allocated memory, but the actual allocation does not go through the buffer manager + void IncreaseUsedMemory(idx_t size); + //! Decrease the currently allocated memory, but the actual deallocation does not go through the buffer manager + void DecreaseUsedMemory(idx_t size); + const string &GetTemporaryDirectory() { return temp_directory; } @@ -5447,10 +5845,8 @@ class BufferManager { } //! Construct a managed buffer. - //! The block_id is just used for internal tracking. It doesn't map to any actual - //! BlockManager. - virtual unique_ptr ConstructManagedBuffer(idx_t size, unique_ptr &&source, - FileBufferType type = FileBufferType::MANAGED_BUFFER); + unique_ptr ConstructManagedBuffer(idx_t size, unique_ptr &&source, + FileBufferType type = FileBufferType::MANAGED_BUFFER); DUCKDB_API void ReserveMemory(idx_t size); DUCKDB_API void FreeReservedMemory(idx_t size); @@ -5503,7 +5899,7 @@ class BufferManager { idx_t size); //! When the BlockHandle reaches 0 readers, this creates a new FileBuffer for this BlockHandle and - //! overwrites the data within with garbage. Any readers that do not hold the pin will notice TODO rewrite + //! overwrites the data within with garbage. Any readers that do not hold the pin will notice void VerifyZeroReaders(shared_ptr &handle); private: @@ -5852,19 +6248,49 @@ struct MergeSorter { + + + + + + +namespace duckdb { + +class Index; + +class ConflictInfo { +public: + ConflictInfo(const unordered_set &column_ids, bool only_check_unique = true) + : column_ids(column_ids), only_check_unique(only_check_unique) { + } + const unordered_set &column_ids; + +public: + bool ConflictTargetMatches(Index &index) const; + void VerifyAllConflictsMeetCondition() const; + +public: + bool only_check_unique = true; +}; + +} // namespace duckdb + + namespace duckdb { class ClientContext; class TableIOManager; class Transaction; +class ConflictManager; struct IndexLock; //! The index is an abstract base class that serves as the basis for indexes class Index { public: - Index(IndexType type, TableIOManager &table_io_manager, const vector &column_ids, - const vector> &unbound_expressions, IndexConstraintType constraint_type); + Index(AttachedDatabase &db, IndexType type, TableIOManager &table_io_manager, const vector &column_ids, + const vector> &unbound_expressions, IndexConstraintType constraint_type, + bool track_memory); virtual ~Index() = default; //! The type of the index @@ -5873,7 +6299,7 @@ class Index { TableIOManager &table_io_manager; //! Column identifiers to extract from the base table vector column_ids; - //! unordered_set of column_ids used by the index + //! Unordered_set of column_ids used by the index unordered_set column_id_set; //! Unbound expressions used by the index vector> unbound_expressions; @@ -5881,18 +6307,29 @@ class Index { vector types; //! The logical types of the expressions vector logical_types; - //! constraint type + //! Index constraint type (primary key, foreign key, ...) IndexConstraintType constraint_type; + //! Attached database instance + AttachedDatabase &db; + //! Buffer manager of the database instance + BufferManager &buffer_manager; + //! The size of the index in memory + //! This does not track the size of the index meta information, but only allocated nodes and leaves + idx_t memory_size; + //! Flag determining if this index's size is tracked by the buffer manager + bool track_memory; + public: //! Initialize a scan on the index with the given expression and column ids //! to fetch from the base table when we only have one query predicate - virtual unique_ptr InitializeScanSinglePredicate(Transaction &transaction, Value value, + virtual unique_ptr InitializeScanSinglePredicate(const Transaction &transaction, const Value &value, ExpressionType expressionType) = 0; //! Initialize a scan on the index with the given expression and column ids //! to fetch from the base table for two query predicates - virtual unique_ptr InitializeScanTwoPredicates(Transaction &transaction, Value low_value, - ExpressionType low_expression_type, Value high_value, + virtual unique_ptr InitializeScanTwoPredicates(Transaction &transaction, const Value &low_value, + ExpressionType low_expression_type, + const Value &high_value, ExpressionType high_expression_type) = 0; //! Perform a lookup on the index, fetching up to max_count result ids. Returns true if all row ids were fetched, //! and false otherwise. @@ -5906,10 +6343,12 @@ class Index { bool Append(DataChunk &entries, Vector &row_identifiers); //! Verify that data can be appended to the index virtual void VerifyAppend(DataChunk &chunk) = 0; + //! Verify that data can be appended to the index + virtual void VerifyAppend(DataChunk &chunk, ConflictManager &conflict_manager) = 0; //! Verify that data can be appended to the index for foreign key constraint - virtual void VerifyAppendForeignKey(DataChunk &chunk, string *err_msg_ptr) = 0; + virtual void VerifyAppendForeignKey(DataChunk &chunk) = 0; //! Verify that data can be delete from the index for foreign key constraint - virtual void VerifyDeleteForeignKey(DataChunk &chunk, string *err_msg_ptr) = 0; + virtual void VerifyDeleteForeignKey(DataChunk &chunk) = 0; //! Called when data inside the index is Deleted virtual void Delete(IndexLock &state, DataChunk &entries, Vector &row_identifiers) = 0; @@ -5917,8 +6356,6 @@ class Index { //! Insert data into the index. Does not lock the index. virtual bool Insert(IndexLock &lock, DataChunk &input, Vector &row_identifiers) = 0; - //! Construct an index from sorted chunks of keys. - virtual void ConstructAndMerge(IndexLock &lock, PayloadScanner &scanner, Allocator &allocator) = 0; //! Merge other_index into this index. virtual bool MergeIndexes(IndexLock &state, Index *other_index) = 0; @@ -5926,10 +6363,16 @@ class Index { //! Returns the string representation of an index virtual string ToString() = 0; + //! Verifies that the memory_size value of the index matches its actual size + virtual void Verify() = 0; //! Returns true if the index is affected by updates on the specified column ids, and false otherwise bool IndexIsUpdated(const vector &column_ids) const; + //! Returns how many of the input values were found in the 'input' chunk, with the option to also record what those + //! matches were. For this purpose, nulls count as a match, and are returned in 'null_count' + virtual void LookupValues(DataChunk &input, ConflictManager &conflict_manager) = 0; + //! Returns unique flag bool IsUnique() { return (constraint_type == IndexConstraintType::UNIQUE || constraint_type == IndexConstraintType::PRIMARY); @@ -5944,6 +6387,7 @@ class Index { } //! Serializes the index and returns the pair of block_id offset positions virtual BlockPointer Serialize(duckdb::MetaBlockWriter &writer); + BlockPointer GetBlockPointer(); //! Returns block/offset of where index was most recently serialized. BlockPointer GetSerializedDataPointer() const { @@ -5972,6 +6416,9 @@ class Index { namespace duckdb { + +class ConflictManager; + class TableIndexList { public: //! Scan the catalog set, invoking the callback method for every entry @@ -5986,6 +6433,10 @@ class TableIndexList { } } + const vector> &Indexes() const { + return indexes; + } + void AddIndex(unique_ptr index); void RemoveIndex(Index *index); @@ -5997,8 +6448,7 @@ class TableIndexList { void Move(TableIndexList &other); Index *FindForeignKeyIndex(const vector &fk_keys, ForeignKeyType fk_type); - void VerifyForeignKey(const vector &fk_keys, bool is_append, DataChunk &chunk, - vector &err_msg); + void VerifyForeignKey(const vector &fk_keys, DataChunk &chunk, ConflictManager &conflict_manager); //! Serialize all indexes owned by this table, returns a vector of block info of all indexes vector SerializeIndexes(duckdb::MetaBlockWriter &writer); @@ -6013,11 +6463,12 @@ class TableIndexList { } // namespace duckdb + namespace duckdb { class CatalogEntry; struct BoundCreateTableInfo { - explicit BoundCreateTableInfo(unique_ptr base_p) : base(move(base_p)) { + explicit BoundCreateTableInfo(unique_ptr base_p) : base(std::move(base_p)) { D_ASSERT(base); } @@ -6034,7 +6485,7 @@ struct BoundCreateTableInfo { //! Bound default values vector> bound_defaults; //! Dependents of the table (in e.g. default values) - unordered_set dependencies; + DependencyList dependencies; //! The existing table data on disk (if any) unique_ptr data; //! CREATE TABLE from QUERY @@ -6110,6 +6561,8 @@ static constexpr ExtensionFunction EXTENSION_FUNCTIONS[] = { {"->>", "json"}, {"array_to_json", "json"}, {"create_fts_index", "fts"}, + {"current_localtime", "icu"}, + {"current_localtimestamp", "icu"}, {"dbgen", "tpch"}, {"drop_fts_index", "fts"}, {"dsdgen", "tpcds"}, @@ -6119,6 +6572,7 @@ static constexpr ExtensionFunction EXTENSION_FUNCTIONS[] = { {"from_substrait", "substrait"}, {"get_substrait", "substrait"}, {"get_substrait_json", "substrait"}, + {"from_substrait_json", "substrait"}, {"icu_calendar_names", "icu"}, {"icu_sort_key", "icu"}, {"json", "json"}, @@ -6132,6 +6586,7 @@ static constexpr ExtensionFunction EXTENSION_FUNCTIONS[] = { {"json_group_array", "json"}, {"json_group_object", "json"}, {"json_group_structure", "json"}, + {"json_keys", "json"}, {"json_merge_patch", "json"}, {"json_object", "json"}, {"json_quote", "json"}, @@ -6148,7 +6603,11 @@ static constexpr ExtensionFunction EXTENSION_FUNCTIONS[] = { {"postgres_attach", "postgres_scanner"}, {"postgres_scan", "postgres_scanner"}, {"postgres_scan_pushdown", "postgres_scanner"}, + {"read_json", "json"}, + {"read_json_auto", "json"}, {"read_json_objects", "json"}, + {"read_ndjson", "json"}, + {"read_ndjson_auto", "json"}, {"read_ndjson_objects", "json"}, {"read_parquet", "parquet"}, {"row_to_json", "json"}, @@ -6171,147 +6630,474 @@ static constexpr ExtensionFunction EXTENSION_FUNCTIONS[] = { }; } // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/attached_database.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + + + +namespace duckdb { +class Catalog; +class DatabaseInstance; +class StorageManager; +class TransactionManager; +class StorageExtension; + +struct AttachInfo; + +enum class AttachedDatabaseType { + READ_WRITE_DATABASE, + READ_ONLY_DATABASE, + SYSTEM_DATABASE, + TEMP_DATABASE, +}; + +//! The AttachedDatabase represents an attached database instance +class AttachedDatabase : public CatalogEntry { +public: + //! Create the built-in system attached database (without storage) + explicit AttachedDatabase(DatabaseInstance &db, AttachedDatabaseType type = AttachedDatabaseType::SYSTEM_DATABASE); + //! Create an attached database instance with the specified name and storage + AttachedDatabase(DatabaseInstance &db, Catalog &catalog, string name, string file_path, AccessMode access_mode); + //! Create an attached database instance with the specified storage extension + AttachedDatabase(DatabaseInstance &db, Catalog &catalog, StorageExtension &ext, string name, AttachInfo &info, + AccessMode access_mode); + ~AttachedDatabase(); + + void Initialize(); + + StorageManager &GetStorageManager(); + Catalog &GetCatalog(); + TransactionManager &GetTransactionManager(); + DatabaseInstance &GetDatabase() { + return db; + } + const string &GetName() const { + return name; + } + bool IsSystem() const; + bool IsTemporary() const; + bool IsReadOnly() const; + + static string ExtractDatabaseName(const string &dbpath); + +private: + DatabaseInstance &db; + unique_ptr storage; + unique_ptr catalog; + unique_ptr transaction_manager; + AttachedDatabaseType type; +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/database_manager.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + + +namespace duckdb { +class AttachedDatabase; +class Catalog; +class CatalogSet; +class ClientContext; +class DatabaseInstance; + +//! The DatabaseManager is a class that sits at the root of all attached databases +class DatabaseManager { + friend class Catalog; + +public: + explicit DatabaseManager(DatabaseInstance &db); + ~DatabaseManager(); + +public: + static DatabaseManager &Get(DatabaseInstance &db); + static DatabaseManager &Get(ClientContext &db); + static DatabaseManager &Get(AttachedDatabase &db); + + void InitializeSystemCatalog(); + //! Get an attached database with the given name + AttachedDatabase *GetDatabase(ClientContext &context, const string &name); + //! Add a new attached database to the database manager + void AddDatabase(ClientContext &context, unique_ptr db); + void DetachDatabase(ClientContext &context, const string &name, bool if_exists); + //! Returns a reference to the system catalog + Catalog &GetSystemCatalog(); + static const string &GetDefaultDatabase(ClientContext &context); + + AttachedDatabase *GetDatabaseFromPath(ClientContext &context, const string &path); + vector GetDatabases(ClientContext &context); + + transaction_t GetNewQueryNumber() { + return current_query_number++; + } + transaction_t ActiveQueryNumber() const { + return current_query_number; + } + idx_t ModifyCatalog() { + return catalog_version++; + } + +private: + //! The system database is a special database that holds system entries (e.g. functions) + unique_ptr system; + //! The set of attached databases + unique_ptr databases; + //! The global catalog version, incremented whenever anything changes in the catalog + atomic catalog_version; + //! The current query number + atomic current_query_number; + //! The current default database + string default_database; +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/function/built_in_functions.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +class BuiltinFunctions { +public: + BuiltinFunctions(CatalogTransaction transaction, Catalog &catalog); + ~BuiltinFunctions(); + + //! Initialize a catalog with all built-in functions + void Initialize(); + +public: + void AddFunction(AggregateFunctionSet set); + void AddFunction(AggregateFunction function); + void AddFunction(ScalarFunctionSet set); + void AddFunction(PragmaFunction function); + void AddFunction(const string &name, PragmaFunctionSet functions); + void AddFunction(ScalarFunction function); + void AddFunction(const vector &names, ScalarFunction function); + void AddFunction(TableFunctionSet set); + void AddFunction(TableFunction function); + void AddFunction(CopyFunction function); + + void AddCollation(string name, ScalarFunction function, bool combinable = false, + bool not_required_for_equality = false); + +private: + CatalogTransaction transaction; + Catalog &catalog; + +private: + template + void Register() { + T::RegisterFunction(*this); + } + + // table-producing functions + void RegisterTableScanFunctions(); + void RegisterSQLiteFunctions(); + void RegisterReadFunctions(); + void RegisterTableFunctions(); + void RegisterArrowFunctions(); + + // aggregates + void RegisterAlgebraicAggregates(); + void RegisterDistributiveAggregates(); + void RegisterNestedAggregates(); + void RegisterHolisticAggregates(); + void RegisterRegressiveAggregates(); + + // scalar functions + void RegisterDateFunctions(); + void RegisterEnumFunctions(); + void RegisterGenericFunctions(); + void RegisterMathFunctions(); + void RegisterOperators(); + void RegisterStringFunctions(); + void RegisterNestedFunctions(); + void RegisterSequenceFunctions(); + void RegisterTrigonometricsFunctions(); + + // pragmas + void RegisterPragmaFunctions(); +}; + +} // namespace duckdb + + #include + namespace duckdb { -string SimilarCatalogEntry::GetQualifiedName() const { - D_ASSERT(Found()); +Catalog::Catalog(AttachedDatabase &db) : db(db) { +} + +Catalog::~Catalog() { +} - return schema->name + "." + name; +DatabaseInstance &Catalog::GetDatabase() { + return db.GetDatabase(); } -Catalog::Catalog(DatabaseInstance &db) - : db(db), schemas(make_unique(*this, make_unique(*this))), - dependency_manager(make_unique(*this)) { - catalog_version = 0; +AttachedDatabase &Catalog::GetAttached() { + return db; } -Catalog::~Catalog() { + +const string &Catalog::GetName() { + return GetAttached().GetName(); +} + +idx_t Catalog::GetOid() { + return GetAttached().oid; +} + +Catalog &Catalog::GetSystemCatalog(ClientContext &context) { + return Catalog::GetSystemCatalog(*context.db); +} + +Catalog &Catalog::GetCatalog(ClientContext &context, const string &catalog_name) { + auto &db_manager = DatabaseManager::Get(context); + if (catalog_name == TEMP_CATALOG) { + return ClientData::Get(context).temporary_objects->GetCatalog(); + } + if (catalog_name == SYSTEM_CATALOG) { + return GetSystemCatalog(context); + } + auto entry = db_manager.GetDatabase( + context, IsInvalidCatalog(catalog_name) ? DatabaseManager::GetDefaultDatabase(context) : catalog_name); + if (!entry) { + throw BinderException("Catalog \"%s\" does not exist!", catalog_name); + } + return entry->GetCatalog(); +} + +//===--------------------------------------------------------------------===// +// Schema +//===--------------------------------------------------------------------===// +CatalogEntry *Catalog::CreateSchema(ClientContext &context, CreateSchemaInfo *info) { + return CreateSchema(GetCatalogTransaction(context), info); } -Catalog &Catalog::GetCatalog(ClientContext &context) { - return context.db->GetCatalog(); +CatalogTransaction Catalog::GetCatalogTransaction(ClientContext &context) { + return CatalogTransaction(*this, context); } +//===--------------------------------------------------------------------===// +// Table +//===--------------------------------------------------------------------===// CatalogEntry *Catalog::CreateTable(ClientContext &context, BoundCreateTableInfo *info) { - auto schema = GetSchema(context, info->base->schema); - return CreateTable(context, schema, info); + return CreateTable(GetCatalogTransaction(context), info); } CatalogEntry *Catalog::CreateTable(ClientContext &context, unique_ptr info) { auto binder = Binder::CreateBinder(context); - auto bound_info = binder->BindCreateTableInfo(move(info)); + auto bound_info = binder->BindCreateTableInfo(std::move(info)); return CreateTable(context, bound_info.get()); } -CatalogEntry *Catalog::CreateTable(ClientContext &context, SchemaCatalogEntry *schema, BoundCreateTableInfo *info) { - return schema->CreateTable(context, info); +CatalogEntry *Catalog::CreateTable(CatalogTransaction transaction, SchemaCatalogEntry *schema, + BoundCreateTableInfo *info) { + return schema->CreateTable(transaction, info); +} + +CatalogEntry *Catalog::CreateTable(CatalogTransaction transaction, BoundCreateTableInfo *info) { + auto schema = GetSchema(transaction, info->base->schema); + return CreateTable(transaction, schema, info); +} + +//===--------------------------------------------------------------------===// +// View +//===--------------------------------------------------------------------===// +CatalogEntry *Catalog::CreateView(CatalogTransaction transaction, CreateViewInfo *info) { + auto schema = GetSchema(transaction, info->schema); + return CreateView(transaction, schema, info); } CatalogEntry *Catalog::CreateView(ClientContext &context, CreateViewInfo *info) { - auto schema = GetSchema(context, info->schema); - return CreateView(context, schema, info); + return CreateView(GetCatalogTransaction(context), info); } -CatalogEntry *Catalog::CreateView(ClientContext &context, SchemaCatalogEntry *schema, CreateViewInfo *info) { - return schema->CreateView(context, info); +CatalogEntry *Catalog::CreateView(CatalogTransaction transaction, SchemaCatalogEntry *schema, CreateViewInfo *info) { + return schema->CreateView(transaction, info); +} + +//===--------------------------------------------------------------------===// +// Sequence +//===--------------------------------------------------------------------===// +CatalogEntry *Catalog::CreateSequence(CatalogTransaction transaction, CreateSequenceInfo *info) { + auto schema = GetSchema(transaction, info->schema); + return CreateSequence(transaction, schema, info); } CatalogEntry *Catalog::CreateSequence(ClientContext &context, CreateSequenceInfo *info) { - auto schema = GetSchema(context, info->schema); - return CreateSequence(context, schema, info); + return CreateSequence(GetCatalogTransaction(context), info); +} + +CatalogEntry *Catalog::CreateSequence(CatalogTransaction transaction, SchemaCatalogEntry *schema, + CreateSequenceInfo *info) { + return schema->CreateSequence(transaction, info); +} + +//===--------------------------------------------------------------------===// +// Type +//===--------------------------------------------------------------------===// +CatalogEntry *Catalog::CreateType(CatalogTransaction transaction, CreateTypeInfo *info) { + auto schema = GetSchema(transaction, info->schema); + return CreateType(transaction, schema, info); } CatalogEntry *Catalog::CreateType(ClientContext &context, CreateTypeInfo *info) { - auto schema = GetSchema(context, info->schema); - return CreateType(context, schema, info); + return CreateType(GetCatalogTransaction(context), info); } -CatalogEntry *Catalog::CreateSequence(ClientContext &context, SchemaCatalogEntry *schema, CreateSequenceInfo *info) { - return schema->CreateSequence(context, info); +CatalogEntry *Catalog::CreateType(CatalogTransaction transaction, SchemaCatalogEntry *schema, CreateTypeInfo *info) { + return schema->CreateType(transaction, info); } -CatalogEntry *Catalog::CreateType(ClientContext &context, SchemaCatalogEntry *schema, CreateTypeInfo *info) { - return schema->CreateType(context, info); +//===--------------------------------------------------------------------===// +// Table Function +//===--------------------------------------------------------------------===// +CatalogEntry *Catalog::CreateTableFunction(CatalogTransaction transaction, CreateTableFunctionInfo *info) { + auto schema = GetSchema(transaction, info->schema); + return CreateTableFunction(transaction, schema, info); } CatalogEntry *Catalog::CreateTableFunction(ClientContext &context, CreateTableFunctionInfo *info) { - auto schema = GetSchema(context, info->schema); - return CreateTableFunction(context, schema, info); + return CreateTableFunction(GetCatalogTransaction(context), info); } -CatalogEntry *Catalog::CreateTableFunction(ClientContext &context, SchemaCatalogEntry *schema, +CatalogEntry *Catalog::CreateTableFunction(CatalogTransaction transaction, SchemaCatalogEntry *schema, CreateTableFunctionInfo *info) { - return schema->CreateTableFunction(context, info); + return schema->CreateTableFunction(transaction, info); +} + +//===--------------------------------------------------------------------===// +// Copy Function +//===--------------------------------------------------------------------===// +CatalogEntry *Catalog::CreateCopyFunction(CatalogTransaction transaction, CreateCopyFunctionInfo *info) { + auto schema = GetSchema(transaction, info->schema); + return CreateCopyFunction(transaction, schema, info); } CatalogEntry *Catalog::CreateCopyFunction(ClientContext &context, CreateCopyFunctionInfo *info) { - auto schema = GetSchema(context, info->schema); - return CreateCopyFunction(context, schema, info); + return CreateCopyFunction(GetCatalogTransaction(context), info); } -CatalogEntry *Catalog::CreateCopyFunction(ClientContext &context, SchemaCatalogEntry *schema, +CatalogEntry *Catalog::CreateCopyFunction(CatalogTransaction transaction, SchemaCatalogEntry *schema, CreateCopyFunctionInfo *info) { - return schema->CreateCopyFunction(context, info); + return schema->CreateCopyFunction(transaction, info); +} + +//===--------------------------------------------------------------------===// +// Pragma Function +//===--------------------------------------------------------------------===// +CatalogEntry *Catalog::CreatePragmaFunction(CatalogTransaction transaction, CreatePragmaFunctionInfo *info) { + auto schema = GetSchema(transaction, info->schema); + return CreatePragmaFunction(transaction, schema, info); } CatalogEntry *Catalog::CreatePragmaFunction(ClientContext &context, CreatePragmaFunctionInfo *info) { - auto schema = GetSchema(context, info->schema); - return CreatePragmaFunction(context, schema, info); + return CreatePragmaFunction(GetCatalogTransaction(context), info); } -CatalogEntry *Catalog::CreatePragmaFunction(ClientContext &context, SchemaCatalogEntry *schema, +CatalogEntry *Catalog::CreatePragmaFunction(CatalogTransaction transaction, SchemaCatalogEntry *schema, CreatePragmaFunctionInfo *info) { - return schema->CreatePragmaFunction(context, info); + return schema->CreatePragmaFunction(transaction, info); +} + +//===--------------------------------------------------------------------===// +// Function +//===--------------------------------------------------------------------===// +CatalogEntry *Catalog::CreateFunction(CatalogTransaction transaction, CreateFunctionInfo *info) { + auto schema = GetSchema(transaction, info->schema); + return CreateFunction(transaction, schema, info); } CatalogEntry *Catalog::CreateFunction(ClientContext &context, CreateFunctionInfo *info) { - auto schema = GetSchema(context, info->schema); - return CreateFunction(context, schema, info); + return CreateFunction(GetCatalogTransaction(context), info); } -CatalogEntry *Catalog::CreateFunction(ClientContext &context, SchemaCatalogEntry *schema, CreateFunctionInfo *info) { - return schema->CreateFunction(context, info); +CatalogEntry *Catalog::CreateFunction(CatalogTransaction transaction, SchemaCatalogEntry *schema, + CreateFunctionInfo *info) { + return schema->CreateFunction(transaction, info); +} + +CatalogEntry *Catalog::AddFunction(ClientContext &context, CreateFunctionInfo *info) { + info->on_conflict = OnCreateConflict::ALTER_ON_CONFLICT; + return CreateFunction(context, info); +} + +//===--------------------------------------------------------------------===// +// Collation +//===--------------------------------------------------------------------===// +CatalogEntry *Catalog::CreateCollation(CatalogTransaction transaction, CreateCollationInfo *info) { + auto schema = GetSchema(transaction, info->schema); + return CreateCollation(transaction, schema, info); } CatalogEntry *Catalog::CreateCollation(ClientContext &context, CreateCollationInfo *info) { - auto schema = GetSchema(context, info->schema); - return CreateCollation(context, schema, info); + return CreateCollation(GetCatalogTransaction(context), info); } -CatalogEntry *Catalog::CreateCollation(ClientContext &context, SchemaCatalogEntry *schema, CreateCollationInfo *info) { - return schema->CreateCollation(context, info); +CatalogEntry *Catalog::CreateCollation(CatalogTransaction transaction, SchemaCatalogEntry *schema, + CreateCollationInfo *info) { + return schema->CreateCollation(transaction, info); } -CatalogEntry *Catalog::CreateSchema(ClientContext &context, CreateSchemaInfo *info) { - D_ASSERT(!info->schema.empty()); - if (info->schema == TEMP_SCHEMA) { - throw CatalogException("Cannot create built-in schema \"%s\"", info->schema); +//===--------------------------------------------------------------------===// +// Lookup Structures +//===--------------------------------------------------------------------===// +struct CatalogLookup { + CatalogLookup(Catalog &catalog, string schema_p) : catalog(catalog), schema(std::move(schema_p)) { } - unordered_set dependencies; - auto entry = make_unique(this, info->schema, info->internal); - auto result = entry.get(); - if (!schemas->CreateEntry(context, info->schema, move(entry), dependencies)) { - if (info->on_conflict == OnCreateConflict::ERROR_ON_CONFLICT) { - throw CatalogException("Schema with name %s already exists!", info->schema); - } else { - D_ASSERT(info->on_conflict == OnCreateConflict::IGNORE_ON_CONFLICT); - } - return nullptr; - } - return result; -} + Catalog &catalog; + string schema; +}; -void Catalog::DropSchema(ClientContext &context, DropInfo *info) { - D_ASSERT(!info->name.empty()); - ModifyCatalog(); - if (!schemas->DropEntry(context, info->name, info->cascade)) { - if (!info->if_exists) { - throw CatalogException("Schema with name \"%s\" does not exist!", info->name); - } +//! Return value of Catalog::LookupEntry +struct CatalogEntryLookup { + SchemaCatalogEntry *schema; + CatalogEntry *entry; + + DUCKDB_API bool Found() const { + return entry; } -} +}; +//===--------------------------------------------------------------------===// +// Generic +//===--------------------------------------------------------------------===// void Catalog::DropEntry(ClientContext &context, DropInfo *info) { ModifyCatalog(); if (info->type == CatalogType::SCHEMA_ENTRY) { @@ -6328,50 +7114,30 @@ void Catalog::DropEntry(ClientContext &context, DropInfo *info) { lookup.schema->DropEntry(context, info); } -CatalogEntry *Catalog::AddFunction(ClientContext &context, CreateFunctionInfo *info) { - auto schema = GetSchema(context, info->schema); - return AddFunction(context, schema, info); -} - -CatalogEntry *Catalog::AddFunction(ClientContext &context, SchemaCatalogEntry *schema, CreateFunctionInfo *info) { - return schema->AddFunction(context, info); -} - SchemaCatalogEntry *Catalog::GetSchema(ClientContext &context, const string &schema_name, bool if_exists, QueryErrorContext error_context) { - D_ASSERT(!schema_name.empty()); - if (schema_name == TEMP_SCHEMA) { - return SchemaCatalogEntry::GetTemporaryObjects(context); - } - auto entry = schemas->GetEntry(context, schema_name); - if (!entry && !if_exists) { - throw CatalogException(error_context.FormatError("Schema with name %s does not exist!", schema_name)); - } - return (SchemaCatalogEntry *)entry; -} - -void Catalog::ScanSchemas(ClientContext &context, std::function callback) { - // create all default schemas first - schemas->Scan(context, [&](CatalogEntry *entry) { callback(entry); }); + return GetSchema(GetCatalogTransaction(context), schema_name, if_exists, error_context); } +//===--------------------------------------------------------------------===// +// Lookup +//===--------------------------------------------------------------------===// SimilarCatalogEntry Catalog::SimilarEntryInSchemas(ClientContext &context, const string &entry_name, CatalogType type, - const vector &schemas) { - - vector sets; - std::transform(schemas.begin(), schemas.end(), std::back_inserter(sets), - [type](SchemaCatalogEntry *s) -> CatalogSet * { return &s->GetCatalogSet(type); }); - pair most_similar {"", (idx_t)-1}; - SchemaCatalogEntry *schema_of_most_similar = nullptr; + const unordered_set &schemas) { + SimilarCatalogEntry result; for (auto schema : schemas) { - auto entry = schema->GetCatalogSet(type).SimilarEntry(context, entry_name); - if (!entry.first.empty() && (most_similar.first.empty() || most_similar.second > entry.second)) { - most_similar = entry; - schema_of_most_similar = schema; + auto transaction = schema->catalog->GetCatalogTransaction(context); + auto entry = schema->GetSimilarEntry(transaction, type, entry_name); + if (!entry.Found()) { + // no similar entry found + continue; + } + if (!result.Found() || result.distance > entry.distance) { + result = entry; + result.schema = schema; } } - - return {most_similar.first, most_similar.second, schema_of_most_similar}; + return result; } string FindExtension(const string &function_name) { @@ -6384,18 +7150,87 @@ string FindExtension(const string &function_name) { } return ""; } + +vector GetCatalogEntries(ClientContext &context, const string &catalog, const string &schema) { + vector entries; + auto &search_path = *context.client_data->catalog_search_path; + if (IsInvalidCatalog(catalog) && IsInvalidSchema(schema)) { + // no catalog or schema provided - scan the entire search path + entries = search_path.Get(); + } else if (IsInvalidCatalog(catalog)) { + auto catalogs = search_path.GetCatalogsForSchema(schema); + for (auto &catalog_name : catalogs) { + entries.emplace_back(catalog_name, schema); + } + if (entries.empty()) { + entries.emplace_back(DatabaseManager::GetDefaultDatabase(context), schema); + } + } else if (IsInvalidSchema(schema)) { + auto schemas = search_path.GetSchemasForCatalog(catalog); + for (auto &schema_name : schemas) { + entries.emplace_back(catalog, schema_name); + } + if (entries.empty()) { + entries.emplace_back(catalog, DEFAULT_SCHEMA); + } + } else { + // specific catalog and schema provided + entries.emplace_back(catalog, schema); + } + return entries; +} + +void FindMinimalQualification(ClientContext &context, const string &catalog_name, const string &schema_name, + bool &qualify_database, bool &qualify_schema) { + // check if we can we qualify ONLY the schema + bool found = false; + auto entries = GetCatalogEntries(context, INVALID_CATALOG, schema_name); + for (auto &entry : entries) { + if (entry.catalog == catalog_name && entry.schema == schema_name) { + found = true; + break; + } + } + if (found) { + qualify_database = false; + qualify_schema = true; + return; + } + // check if we can qualify ONLY the catalog + found = false; + entries = GetCatalogEntries(context, catalog_name, INVALID_SCHEMA); + for (auto &entry : entries) { + if (entry.catalog == catalog_name && entry.schema == schema_name) { + found = true; + break; + } + } + if (found) { + qualify_database = true; + qualify_schema = false; + return; + } + // need to qualify both catalog and schema + qualify_database = true; + qualify_schema = true; +} + CatalogException Catalog::CreateMissingEntryException(ClientContext &context, const string &entry_name, - CatalogType type, const vector &schemas, + CatalogType type, + const unordered_set &schemas, QueryErrorContext error_context) { auto entry = SimilarEntryInSchemas(context, entry_name, type, schemas); - vector unseen_schemas; - this->schemas->Scan([&schemas, &unseen_schemas](CatalogEntry *entry) { - auto schema_entry = (SchemaCatalogEntry *)entry; - if (std::find(schemas.begin(), schemas.end(), schema_entry) == schemas.end()) { - unseen_schemas.emplace_back(schema_entry); + unordered_set unseen_schemas; + auto &db_manager = DatabaseManager::Get(context); + auto databases = db_manager.GetDatabases(context); + for (auto database : databases) { + auto &catalog = database->GetCatalog(); + auto current_schemas = catalog.GetAllSchemas(context); + for (auto ¤t_schema : current_schemas) { + unseen_schemas.insert(current_schema); } - }); + } auto unseen_entry = SimilarEntryInSchemas(context, entry_name, type, unseen_schemas); auto extension_name = FindExtension(entry_name); if (!extension_name.empty()) { @@ -6405,7 +7240,14 @@ CatalogException Catalog::CreateMissingEntryException(ClientContext &context, co } string did_you_mean; if (unseen_entry.Found() && unseen_entry.distance < entry.distance) { - did_you_mean = "\nDid you mean \"" + unseen_entry.GetQualifiedName() + "\"?"; + // the closest matching entry requires qualification as it is not in the default search path + // check how to minimally qualify this entry + auto catalog_name = unseen_entry.schema->catalog->GetName(); + auto schema_name = unseen_entry.schema->name; + bool qualify_database; + bool qualify_schema; + FindMinimalQualification(context, catalog_name, schema_name, qualify_database, qualify_schema); + did_you_mean = "\nDid you mean \"" + unseen_entry.GetQualifiedName(qualify_database, qualify_schema) + "\"?"; } else if (entry.Found()) { did_you_mean = "\nDid you mean \"" + entry.name + "\"?"; } @@ -6414,44 +7256,74 @@ CatalogException Catalog::CreateMissingEntryException(ClientContext &context, co entry_name, did_you_mean)); } -CatalogEntryLookup Catalog::LookupEntry(ClientContext &context, CatalogType type, const string &schema_name, - const string &name, bool if_exists, QueryErrorContext error_context) { - if (!schema_name.empty()) { - auto schema = GetSchema(context, schema_name, if_exists, error_context); - if (!schema) { - D_ASSERT(if_exists); - return {nullptr, nullptr}; - } - - auto entry = schema->GetCatalogSet(type).GetEntry(context, name); - if (!entry && !if_exists) { - throw CreateMissingEntryException(context, name, type, {schema}, error_context); - } +CatalogEntryLookup Catalog::LookupEntryInternal(CatalogTransaction transaction, CatalogType type, const string &schema, + const string &name) { - return {schema, entry}; + auto schema_entry = (SchemaCatalogEntry *)GetSchema(transaction, schema, true); + if (!schema_entry) { + return {nullptr, nullptr}; } - - const auto &paths = ClientData::Get(context).catalog_search_path->Get(); - for (const auto &path : paths) { - auto lookup = LookupEntry(context, type, path, name, true, error_context); - if (lookup.Found()) { - return lookup; - } + auto entry = schema_entry->GetEntry(transaction, type, name); + if (!entry) { + return {schema_entry, nullptr}; } + return {schema_entry, entry}; +} - if (!if_exists) { - vector schemas; - for (const auto &path : paths) { - auto schema = GetSchema(context, path, true); - if (schema) { - schemas.emplace_back(schema); +CatalogEntryLookup Catalog::LookupEntry(ClientContext &context, CatalogType type, const string &schema, + const string &name, bool if_exists, QueryErrorContext error_context) { + unordered_set schemas; + if (IsInvalidSchema(schema)) { + // try all schemas for this catalog + auto catalog_name = GetName(); + if (catalog_name == DatabaseManager::GetDefaultDatabase(context)) { + catalog_name = INVALID_CATALOG; + } + auto entries = GetCatalogEntries(context, GetName(), INVALID_SCHEMA); + for (auto &entry : entries) { + auto &candidate_schema = entry.schema; + auto transaction = GetCatalogTransaction(context); + auto result = LookupEntryInternal(transaction, type, candidate_schema, name); + if (result.Found()) { + return result; + } + if (result.schema) { + schemas.insert(result.schema); } } - - throw CreateMissingEntryException(context, name, type, schemas, error_context); + } else { + auto transaction = GetCatalogTransaction(context); + auto result = LookupEntryInternal(transaction, type, schema, name); + if (result.Found()) { + return result; + } + if (result.schema) { + schemas.insert(result.schema); + } + } + if (if_exists) { + return {nullptr, nullptr}; } + throw CreateMissingEntryException(context, name, type, schemas, error_context); +} - return {nullptr, nullptr}; +CatalogEntryLookup Catalog::LookupEntry(ClientContext &context, vector &lookups, CatalogType type, + const string &name, bool if_exists, QueryErrorContext error_context) { + unordered_set schemas; + for (auto &lookup : lookups) { + auto transaction = lookup.catalog.GetCatalogTransaction(context); + auto result = lookup.catalog.LookupEntryInternal(transaction, type, lookup.schema, name); + if (result.Found()) { + return result; + } + if (result.schema) { + schemas.insert(result.schema); + } + } + if (if_exists) { + return {nullptr, nullptr}; + } + throw CreateMissingEntryException(context, name, type, schemas, error_context); } CatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema, const string &name) { @@ -6472,75 +7344,106 @@ CatalogEntry *Catalog::GetEntry(ClientContext &context, CatalogType type, const return LookupEntry(context, type, schema_name, name, if_exists, error_context).entry; } -template <> -TableCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name, - bool if_exists, QueryErrorContext error_context) { - auto entry = GetEntry(context, CatalogType::TABLE_ENTRY, schema_name, name, if_exists); - if (!entry) { - return nullptr; +CatalogEntry *Catalog::GetEntry(ClientContext &context, CatalogType type, const string &catalog, const string &schema, + const string &name, bool if_exists_p, QueryErrorContext error_context) { + auto entries = GetCatalogEntries(context, catalog, schema); + vector lookups; + lookups.reserve(entries.size()); + for (auto &entry : entries) { + lookups.emplace_back(Catalog::GetCatalog(context, entry.catalog), entry.schema); } - if (entry->type != CatalogType::TABLE_ENTRY) { - throw CatalogException(error_context.FormatError("%s is not a table", name)); + auto result = LookupEntry(context, lookups, type, name, if_exists_p, error_context); + if (!result.Found()) { + D_ASSERT(if_exists_p); + return nullptr; } - return (TableCatalogEntry *)entry; + return result.entry; } -template <> -SequenceCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name, - bool if_exists, QueryErrorContext error_context) { - return (SequenceCatalogEntry *)GetEntry(context, CatalogType::SEQUENCE_ENTRY, schema_name, name, if_exists, - error_context); +SchemaCatalogEntry *Catalog::GetSchema(ClientContext &context, const string &catalog_name, const string &schema_name, + bool if_exists_p, QueryErrorContext error_context) { + auto entries = GetCatalogEntries(context, catalog_name, schema_name); + SchemaCatalogEntry *result = nullptr; + for (idx_t i = 0; i < entries.size(); i++) { + auto if_exists = i + 1 == entries.size() ? if_exists_p : true; + auto &catalog = Catalog::GetCatalog(context, entries[i].catalog); + auto result = catalog.GetSchema(context, schema_name, if_exists, error_context); + if (result) { + return result; + } + } + return result; } -template <> -TableFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name, - bool if_exists, QueryErrorContext error_context) { - return (TableFunctionCatalogEntry *)GetEntry(context, CatalogType::TABLE_FUNCTION_ENTRY, schema_name, name, - if_exists, error_context); +LogicalType Catalog::GetType(ClientContext &context, const string &schema, const string &name, bool if_exists) { + auto type_entry = GetEntry(context, schema, name, if_exists); + if (!type_entry) { + return LogicalType::INVALID; + } + auto result_type = type_entry->user_type; + LogicalType::SetCatalog(result_type, type_entry); + return result_type; } -template <> -CopyFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name, - bool if_exists, QueryErrorContext error_context) { - return (CopyFunctionCatalogEntry *)GetEntry(context, CatalogType::COPY_FUNCTION_ENTRY, schema_name, name, if_exists, - error_context); +LogicalType Catalog::GetType(ClientContext &context, const string &catalog_name, const string &schema, + const string &name) { + auto type_entry = Catalog::GetEntry(context, catalog_name, schema, name); + auto result_type = type_entry->user_type; + LogicalType::SetCatalog(result_type, type_entry); + return result_type; } -template <> -PragmaFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name, - bool if_exists, QueryErrorContext error_context) { - return (PragmaFunctionCatalogEntry *)GetEntry(context, CatalogType::PRAGMA_FUNCTION_ENTRY, schema_name, name, - if_exists, error_context); +vector Catalog::GetSchemas(ClientContext &context) { + vector schemas; + ScanSchemas(context, [&](CatalogEntry *entry) { schemas.push_back((SchemaCatalogEntry *)entry); }); + return schemas; } -template <> -AggregateFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name, - bool if_exists, QueryErrorContext error_context) { - auto entry = GetEntry(context, CatalogType::AGGREGATE_FUNCTION_ENTRY, schema_name, name, if_exists, error_context); - if (entry->type != CatalogType::AGGREGATE_FUNCTION_ENTRY) { - throw CatalogException(error_context.FormatError("%s is not an aggregate function", name)); +vector Catalog::GetSchemas(ClientContext &context, const string &catalog_name) { + vector catalogs; + if (IsInvalidCatalog(catalog_name)) { + unordered_set name; + + auto &search_path = *context.client_data->catalog_search_path; + for (auto &entry : search_path.Get()) { + if (name.find(entry.catalog) != name.end()) { + continue; + } + name.insert(entry.catalog); + catalogs.push_back(&Catalog::GetCatalog(context, entry.catalog)); + } + } else { + catalogs.push_back(&Catalog::GetCatalog(context, catalog_name)); } - return (AggregateFunctionCatalogEntry *)entry; + vector result; + for (auto catalog : catalogs) { + auto schemas = catalog->GetSchemas(context); + result.insert(result.end(), schemas.begin(), schemas.end()); + } + return result; } -template <> -CollateCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name, - bool if_exists, QueryErrorContext error_context) { - return (CollateCatalogEntry *)GetEntry(context, CatalogType::COLLATION_ENTRY, schema_name, name, if_exists, - error_context); -} +vector Catalog::GetAllSchemas(ClientContext &context) { + vector result; -template <> -TypeCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name, - bool if_exists, QueryErrorContext error_context) { - return (TypeCatalogEntry *)GetEntry(context, CatalogType::TYPE_ENTRY, schema_name, name, if_exists, error_context); -} + auto &db_manager = DatabaseManager::Get(context); + auto databases = db_manager.GetDatabases(context); + for (auto database : databases) { + auto &catalog = database->GetCatalog(); + auto new_schemas = catalog.GetSchemas(context); + result.insert(result.end(), new_schemas.begin(), new_schemas.end()); + } + sort(result.begin(), result.end(), [&](SchemaCatalogEntry *x, SchemaCatalogEntry *y) { + if (x->catalog->GetName() < y->catalog->GetName()) { + return true; + } + if (x->catalog->GetName() == y->catalog->GetName()) { + return x->name < y->name; + } + return false; + }); -LogicalType Catalog::GetType(ClientContext &context, const string &schema, const string &name) { - auto user_type_catalog = GetEntry(context, schema, name); - auto result_type = user_type_catalog->user_type; - LogicalType::SetCatalog(result_type, user_type_catalog); - return result_type; + return result; } void Catalog::Alter(ClientContext &context, AlterInfo *info) { @@ -6552,12 +7455,26 @@ void Catalog::Alter(ClientContext &context, AlterInfo *info) { return lookup.schema->Alter(context, info); } +void Catalog::Verify() { +} + +//===--------------------------------------------------------------------===// +// Catalog Version +//===--------------------------------------------------------------------===// idx_t Catalog::GetCatalogVersion() { - return catalog_version; + return GetDatabase().GetDatabaseManager().catalog_version; } idx_t Catalog::ModifyCatalog() { - return catalog_version++; + return GetDatabase().GetDatabaseManager().ModifyCatalog(); +} + +bool Catalog::IsSystemCatalog() const { + return db.IsSystem(); +} + +bool Catalog::IsTemporaryCatalog() const { + return db.IsTemporary(); } } // namespace duckdb @@ -6755,12 +7672,12 @@ void ColumnDependencyManager::AdjustSingle(LogicalIndex idx, idx_t offset) { } if (has_dependents) { D_ASSERT(!dependencies_map.count(new_idx)); - dependencies_map[new_idx] = move(dependencies_map[idx]); + dependencies_map[new_idx] = std::move(dependencies_map[idx]); dependencies_map.erase(idx); } if (has_dependencies) { D_ASSERT(!dependents_map.count(new_idx)); - dependents_map[new_idx] = move(dependents_map[idx]); + dependents_map[new_idx] = std::move(dependents_map[idx]); dependents_map.erase(idx); } } @@ -6856,6 +7773,35 @@ CopyFunctionCatalogEntry::CopyFunctionCatalogEntry(Catalog *catalog, SchemaCatal : StandardEntry(CatalogType::COPY_FUNCTION_ENTRY, schema, catalog, info->name), function(info->function) { } +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/catalog/catalog_entry/dindex_catalog_entry.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +//! An index catalog entry +class DuckIndexEntry : public IndexCatalogEntry { +public: + //! Create an IndexCatalogEntry and initialize storage for it + DuckIndexEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateIndexInfo *info); + ~DuckIndexEntry(); + + shared_ptr info; + +public: + string GetSchemaName() override; + string GetTableName() override; +}; + } // namespace duckdb //===----------------------------------------------------------------------===// @@ -7127,6 +8073,8 @@ class TableDataWriter; class TableIndexList; class TableStatistics; +class BoundConstraint; + class RowGroupCollection { public: RowGroupCollection(shared_ptr info, BlockManager &block_manager, vector types, @@ -7155,12 +8103,12 @@ class RowGroupCollection { void InitializeParallelScan(ParallelCollectionScanState &state); bool NextParallelScan(ClientContext &context, ParallelCollectionScanState &state, CollectionScanState &scan_state); - bool Scan(Transaction &transaction, const vector &column_ids, + bool Scan(DuckTransaction &transaction, const vector &column_ids, const std::function &fun); - bool Scan(Transaction &transaction, const std::function &fun); + bool Scan(DuckTransaction &transaction, const std::function &fun); void Fetch(TransactionData transaction, DataChunk &result, const vector &column_ids, - Vector &row_identifiers, idx_t fetch_count, ColumnFetchState &state); + const Vector &row_identifiers, idx_t fetch_count, ColumnFetchState &state); //! Initialize an append of a variable number of rows. FinalizeAppend must be called after appending is done. void InitializeAppend(TableAppendState &state); @@ -7187,7 +8135,7 @@ class RowGroupCollection { void CommitDropColumn(idx_t index); void CommitDropTable(); - vector> GetStorageInfo(); + void GetStorageInfo(TableStorageInfo &result); const vector &GetTypes() const; shared_ptr AddColumn(ClientContext &context, ColumnDefinition &new_column, @@ -7236,7 +8184,9 @@ class RowGroupCollection { namespace duckdb { +class AttachedDatabase; class DataTable; +class Transaction; class WriteAheadLog; struct TableAppendState; @@ -7306,9 +8256,9 @@ class LocalTableStorage : public std::enable_shared_from_this void Rollback(); idx_t EstimatedSize(); - void AppendToIndexes(Transaction &transaction, TableAppendState &append_state, idx_t append_count, + void AppendToIndexes(DuckTransaction &transaction, TableAppendState &append_state, idx_t append_count, bool append_to_table); - bool AppendToIndexes(Transaction &transaction, RowGroupCollection &source, TableIndexList &index_list, + bool AppendToIndexes(DuckTransaction &transaction, RowGroupCollection &source, TableIndexList &index_list, const vector &table_types, row_t &start_row); //! Creates an optimistic writer for this table @@ -7342,10 +8292,11 @@ class LocalStorage { }; public: - explicit LocalStorage(ClientContext &context, Transaction &transaction); + explicit LocalStorage(ClientContext &context, DuckTransaction &transaction); - static LocalStorage &Get(Transaction &transaction); - static LocalStorage &Get(ClientContext &context); + static LocalStorage &Get(DuckTransaction &transaction); + static LocalStorage &Get(ClientContext &context, AttachedDatabase &db); + static LocalStorage &Get(ClientContext &context, Catalog &catalog); //! Initialize a scan of the local storage void InitializeScan(DataTable *table, CollectionScanState &state, TableFilterSet *table_filters); @@ -7373,7 +8324,7 @@ class LocalStorage { void Update(DataTable *table, Vector &row_ids, const vector &column_ids, DataChunk &data); //! Commits the local storage, writing it to the WAL and completing the commit - void Commit(LocalStorage::CommitState &commit_state, Transaction &transaction); + void Commit(LocalStorage::CommitState &commit_state, DuckTransaction &transaction); //! Rollback the local storage void Rollback(); @@ -7390,14 +8341,15 @@ class LocalStorage { const vector &bound_columns, Expression &cast_expr); void MoveStorage(DataTable *old_dt, DataTable *new_dt); - void FetchChunk(DataTable *table, Vector &row_ids, idx_t count, DataChunk &chunk); + void FetchChunk(DataTable *table, Vector &row_ids, idx_t count, const vector &col_ids, DataChunk &chunk, + ColumnFetchState &fetch_state); TableIndexList &GetIndexes(DataTable *table); void VerifyNewConstraint(DataTable &parent, const BoundConstraint &constraint); private: ClientContext &context; - Transaction &transaction; + DuckTransaction &transaction; LocalTableManager table_manager; void Flush(DataTable &table, LocalTableStorage &storage); @@ -7424,12 +8376,10 @@ class DatabaseInstance; class TableIOManager; struct DataTableInfo { - DataTableInfo(DatabaseInstance &db, shared_ptr table_io_manager_p, string schema, string table) - : db(db), table_io_manager(move(table_io_manager_p)), cardinality(0), schema(move(schema)), table(move(table)) { - } + DataTableInfo(AttachedDatabase &db, shared_ptr table_io_manager_p, string schema, string table); //! The database instance of the table - DatabaseInstance &db; + AttachedDatabase &db; //! The table IO manager shared_ptr table_io_manager; //! The amount of elements in the table. Note that this number signifies the amount of COMMITTED entries in the @@ -7442,19 +8392,19 @@ struct DataTableInfo { TableIndexList indexes; - bool IsTemporary() { - return schema == TEMP_SCHEMA; - } + bool IsTemporary() const; }; } // namespace duckdb namespace duckdb { +class BoundForeignKeyConstraint; class ClientContext; class ColumnDataCollection; class ColumnDefinition; class DataTable; +class DuckTransaction; class OptimisticDataWriter; class RowGroup; class StorageManager; @@ -7463,12 +8413,14 @@ class TableIOManager; class Transaction; class WriteAheadLog; class TableDataWriter; +class ConflictManager; +enum class VerifyExistenceType : uint8_t; //! DataTable represents a physical table on disk class DataTable { public: //! Constructs a new data table from an (optional) set of persistent segments - DataTable(DatabaseInstance &db, shared_ptr table_io_manager, const string &schema, + DataTable(AttachedDatabase &db, shared_ptr table_io_manager, const string &schema, const string &table, vector column_definitions_p, unique_ptr data = nullptr); //! Constructs a DataTable as a delta on an existing data table with a newly added column @@ -7486,7 +8438,7 @@ class DataTable { //! The set of physical columns stored by this DataTable vector column_definitions; //! A reference to the database instance - DatabaseInstance &db; + AttachedDatabase &db; public: //! Returns a list of types of the table @@ -7494,7 +8446,7 @@ class DataTable { void InitializeScan(TableScanState &state, const vector &column_ids, TableFilterSet *table_filter = nullptr); - void InitializeScan(Transaction &transaction, TableScanState &state, const vector &column_ids, + void InitializeScan(DuckTransaction &transaction, TableScanState &state, const vector &column_ids, TableFilterSet *table_filters = nullptr); //! Returns the maximum amount of threads that should be assigned to scan this data table @@ -7506,16 +8458,17 @@ class DataTable { //! from offset and store them in result. Offset is incremented with how many //! elements were returned. //! Returns true if all pushed down filters were executed during data fetching - void Scan(Transaction &transaction, DataChunk &result, TableScanState &state); + void Scan(DuckTransaction &transaction, DataChunk &result, TableScanState &state); //! Fetch data from the specific row identifiers from the base table - void Fetch(Transaction &transaction, DataChunk &result, const vector &column_ids, Vector &row_ids, - idx_t fetch_count, ColumnFetchState &state); + void Fetch(DuckTransaction &transaction, DataChunk &result, const vector &column_ids, + const Vector &row_ids, idx_t fetch_count, ColumnFetchState &state); //! Initializes an append to transaction-local storage void InitializeLocalAppend(LocalAppendState &state, ClientContext &context); //! Append a DataChunk to the transaction-local storage of the table. - void LocalAppend(LocalAppendState &state, TableCatalogEntry &table, ClientContext &context, DataChunk &chunk); + void LocalAppend(LocalAppendState &state, TableCatalogEntry &table, ClientContext &context, DataChunk &chunk, + bool unsafe = false); //! Finalizes a transaction-local append void FinalizeLocalAppend(LocalAppendState &state); //! Append a chunk to the transaction-local storage of this table @@ -7547,7 +8500,7 @@ class DataTable { //! Fetches an append lock void AppendLock(TableAppendState &state); //! Begin appending structs to this table, obtaining necessary locks, etc - void InitializeAppend(Transaction &transaction, TableAppendState &state, idx_t append_count); + void InitializeAppend(DuckTransaction &transaction, TableAppendState &state, idx_t append_count); //! Append a chunk to the table using the AppendState obtained from InitializeAppend void Append(DataChunk &chunk, TableAppendState &state); //! Commit the append @@ -7594,7 +8547,7 @@ class DataTable { idx_t GetTotalRows(); - vector> GetStorageInfo(); + void GetStorageInfo(TableStorageInfo &result); static bool IsForeignKeyIndex(const vector &fk_keys, Index &index, ForeignKeyType fk_type); //! Initializes a special scan that is used to create an index on the table, it keeps locks on the table @@ -7603,7 +8556,8 @@ class DataTable { bool CreateIndexScan(TableScanState &state, DataChunk &result, TableScanType type); //! Verify constraints with a chunk from the Append containing all columns of the table - void VerifyAppendConstraints(TableCatalogEntry &table, ClientContext &context, DataChunk &chunk); + void VerifyAppendConstraints(TableCatalogEntry &table, ClientContext &context, DataChunk &chunk, + ConflictManager *conflict_manager = nullptr); private: //! Verify the new added constraints against current persistent&local data @@ -7617,6 +8571,13 @@ class DataTable { void InitializeScanWithOffset(TableScanState &state, const vector &column_ids, idx_t start_row, idx_t end_row); + void VerifyForeignKeyConstraint(const BoundForeignKeyConstraint &bfk, ClientContext &context, DataChunk &chunk, + VerifyExistenceType verify_type); + void VerifyAppendForeignKeyConstraint(const BoundForeignKeyConstraint &bfk, ClientContext &context, + DataChunk &chunk); + void VerifyDeleteForeignKeyConstraint(const BoundForeignKeyConstraint &bfk, ClientContext &context, + DataChunk &chunk); + private: //! Lock for appending entries to the table mutex append_lock; @@ -8017,45 +8978,51 @@ class MetaBlockReader : public Deserializer { namespace duckdb { +class ART; + class Prefix { static constexpr idx_t PREFIX_INLINE_BYTES = 8; public: + //! Empty prefix Prefix(); - // Prefix created from key starting on `depth` + //! Construct prefix from key starting at depth Prefix(Key &key, uint32_t depth, uint32_t size); - // Prefix created from other prefix up to size + //! Construct prefix from other prefix up to size Prefix(Prefix &other_prefix, uint32_t size); ~Prefix(); - // Returns the Prefix's size - uint32_t Size() const; - //! Return a pointer to the prefix data + //! Returns the prefix size + inline uint32_t Size() const { + return size; + } + //! Returns the memory size of the prefix + idx_t MemorySize(); + //! Returns a pointer to the prefix data uint8_t *GetPrefixData(); + //! Returns a const pointer to the prefix data const uint8_t *GetPrefixData() const; - // Subscript operator + //! Subscript operator uint8_t &operator[](idx_t idx); - - // Assign operator + //! Assign operator Prefix &operator=(const Prefix &src); - - // Move operator + //! Move operator Prefix &operator=(Prefix &&other) noexcept; - // Concatenate Prefix with a key and another prefix - // Used when deleting a Node. - // other.prefix + key + this->Prefix - void Concatenate(uint8_t key, Prefix &other); - // Reduces the prefix in n elements, and returns what would be the first one as a key - uint8_t Reduce(uint32_t n); - // Serializes Prefix + //! Concatenate prefix with a partial key byte and another prefix: other.prefix + byte + this->prefix + //! Used when deleting a node + void Concatenate(ART &art, uint8_t key, Prefix &other); + //! Reduces the prefix in n bytes, and returns the new first byte + uint8_t Reduce(ART &art, uint32_t n); + + //! Serializes the prefix void Serialize(duckdb::MetaBlockWriter &writer); - // Deserializes Prefix + //! Deserializes the prefix void Deserialize(duckdb::MetaBlockReader &reader); - // Compare the key with the prefix of the node, return the position where it mismatches - uint32_t KeyMismatchPosition(Key &key, uint64_t depth); + //! Compare the key with the prefix of the node, return the position where they mismatch + uint32_t KeyMismatchPosition(Key &key, uint32_t depth); //! Compare this prefix to another prefix, return the position where they mismatch, or size otherwise uint32_t MismatchPosition(Prefix &other); @@ -8101,10 +9068,12 @@ struct InternalType { }; struct MergeInfo { - MergeInfo(ART *l_art, ART *r_art, Node *&l_node, Node *&r_node) - : l_art(l_art), r_art(r_art), l_node(l_node), r_node(r_node) {}; + MergeInfo(ART *l_art, ART *r_art, ART *root_l_art, ART *root_r_art, Node *&l_node, Node *&r_node) + : l_art(l_art), r_art(r_art), root_l_art(root_l_art), root_r_art(root_r_art), l_node(l_node), r_node(r_node) {}; ART *l_art; ART *r_art; + ART *root_l_art; + ART *root_r_art; Node *&l_node; Node *&r_node; }; @@ -8121,6 +9090,8 @@ struct ParentsOfNodes { class Node { public: static const uint8_t EMPTY_MARKER = 48; + static const uint8_t NODE_48_SHRINK_THRESHOLD = 12; + static const uint8_t NODE_256_SHRINK_THRESHOLD = 36; public: explicit Node(NodeType type); @@ -8135,6 +9106,8 @@ class Node { Prefix prefix; static void Delete(Node *node); + //! Returns the memory size of the node + virtual idx_t MemorySize(ART &art, const bool &recurse); //! Get the position of a child corresponding exactly to the specific byte, returns DConstants::INVALID_INDEX if not //! exists virtual idx_t GetChildPos(uint8_t k) { @@ -8152,31 +9125,37 @@ class Node { virtual idx_t GetNextPos(idx_t pos) { return DConstants::INVALID_INDEX; } + //! Get the next position and byte in the node, or DConstants::INVALID_INDEX if there is no next position. if pos == + //! DConstants::INVALID_INDEX, then the first valid position in the node is returned + virtual idx_t GetNextPosAndByte(idx_t pos, uint8_t &byte) { + return DConstants::INVALID_INDEX; + } //! Get the child at the specified position in the node. pos should be between [0, count). Throws an assertion if //! the element is not found virtual Node *GetChild(ART &art, idx_t pos); //! Replaces the pointer to a child node virtual void ReplaceChildPointer(idx_t pos, Node *node); + //! Returns whether the child at pos is in memory + virtual bool ChildIsInMemory(idx_t pos); //! Insert a new child node at key_byte into the node - static void InsertChild(Node *&node, uint8_t key_byte, Node *new_child); + static void InsertChild(ART &art, Node *&node, uint8_t key_byte, Node *new_child); //! Erase child node entry from node - static void EraseChild(Node *&node, idx_t pos, ART &art); + static void EraseChild(ART &art, Node *&node, idx_t pos); //! Get the corresponding node type for the provided size static NodeType GetTypeBySize(idx_t size); //! Create a new node of the specified type - static void New(NodeType &type, Node *&node); + static void New(const NodeType &type, Node *&node); //! Returns the string representation of a node string ToString(ART &art); //! Serialize this node BlockPointer Serialize(ART &art, duckdb::MetaBlockWriter &writer); + //! Returns the memory size of the node + idx_t RecursiveMemorySize(ART &art); //! Deserialize this node static Node *Deserialize(ART &art, idx_t block_id, idx_t offset); - //! Merge r_node into l_node at the specified byte - static bool MergeAtByte(MergeInfo &info, idx_t depth, idx_t &l_child_pos, idx_t &r_pos, uint8_t &key_byte, - Node *&l_parent, idx_t l_pos); //! Merge two ART static bool MergeARTs(ART *l_art, ART *r_art); @@ -8184,7 +9163,7 @@ class Node { //! Serialize internal nodes BlockPointer SerializeInternal(ART &art, duckdb::MetaBlockWriter &writer, InternalType &internal_type); //! Deserialize internal nodes - void DeserializeInternal(duckdb::MetaBlockReader &reader); + void DeserializeInternal(ART &art, duckdb::MetaBlockReader &reader); }; } // namespace duckdb @@ -8195,36 +9174,45 @@ namespace duckdb { class Leaf : public Node { public: + explicit Leaf(); Leaf(Key &value, uint32_t depth, row_t row_id); Leaf(Key &value, uint32_t depth, row_t *row_ids, idx_t num_elements); Leaf(row_t *row_ids, idx_t num_elements, Prefix &prefix); Leaf(row_t row_id, Prefix &prefix); ~Leaf(); - row_t GetRowId(idx_t index); + //! Get the row ID at idx + row_t GetRowId(idx_t idx); + //! Get the maximum capacity of the leaf, must not match with its count idx_t GetCapacity() const; + //! Returns whether a leaf holds exactly one inlined row ID or multiple row IDs bool IsInlined() const; + //! Returns a pointer to all row IDs of the leaf row_t *GetRowIds(); public: + static Leaf *New(); static Leaf *New(Key &value, uint32_t depth, row_t row_id); static Leaf *New(Key &value, uint32_t depth, row_t *row_ids, idx_t num_elements); static Leaf *New(row_t *row_ids, idx_t num_elements, Prefix &prefix); static Leaf *New(row_t row_id, Prefix &prefix); - //! Insert a row_id into a leaf - void Insert(row_t row_id); - //! Remove a row_id from a leaf - void Remove(row_t row_id); + + //! Returns the memory size of the leaf + idx_t MemorySize(ART &art, const bool &recurse) override; + //! Insert a row ID into a leaf + void Insert(ART &art, row_t row_id); + //! Remove a row ID from a leaf + void Remove(ART &art, row_t row_id); //! Returns the string representation of a leaf static string ToString(Node *node); //! Merge two NLeaf nodes - static void Merge(Node *&l_node, Node *&r_node); + static void Merge(ART &art, Node *&l_node, Node *&r_node); //! Serialize a leaf BlockPointer Serialize(duckdb::MetaBlockWriter &writer); - // Deserialize a leaf - static Leaf *Deserialize(duckdb::MetaBlockReader &reader); + //! Deserialize a leaf + void Deserialize(ART &art, duckdb::MetaBlockReader &reader); private: union { @@ -8341,6 +9329,8 @@ class SwizzleablePointer { //! Transforms from Node* to uint64_t SwizzleablePointer &operator=(const Node *ptr); + //! Checks if pointer is swizzled + bool IsSwizzled(); //! Unswizzle the pointer (if possible) Node *Unswizzle(ART &art); @@ -8348,7 +9338,7 @@ class SwizzleablePointer { return pointer; } - //! Deletes the underlying object (if necessary) and set the pointer to null_ptr + //! Deletes the underlying object (if necessary) and set the pointer to nullptr void Reset(); private: @@ -8356,10 +9346,8 @@ class SwizzleablePointer { friend bool operator!=(const SwizzleablePointer &s_ptr, const uint64_t &ptr); - //! Extracts block info from swizzled pointer + //! Extracts the block info from swizzled pointer BlockPointer GetSwizzledBlockInfo(); - //! Checks if pointer is swizzled - bool IsSwizzled(); }; } // namespace duckdb @@ -8369,12 +9357,17 @@ namespace duckdb { class Node16 : public Node { public: + //! Empty Node16 explicit Node16(); + //! Array containing all partial key bytes uint8_t key[16]; + //! ART pointers to the child nodes ARTPointer children[16]; public: static Node16 *New(); + //! Returns the memory size of the Node16 + idx_t MemorySize(ART &art, const bool &recurse) override; //! Get position of a specific byte, returns DConstants::INVALID_INDEX if not exists idx_t GetChildPos(uint8_t k) override; //! Get the position of the first child that is greater or equal to the specific byte, or DConstants::INVALID_INDEX @@ -8384,19 +9377,24 @@ class Node16 : public Node { idx_t GetMin() override; //! Get the next position in the node, or DConstants::INVALID_INDEX if there is no next position idx_t GetNextPos(idx_t pos) override; + //! Get the next position in the node, or DConstants::INVALID_INDEX if there is no next position + idx_t GetNextPosAndByte(idx_t pos, uint8_t &byte) override; //! Get Node16 child Node *GetChild(ART &art, idx_t pos) override; //! Replace child pointer void ReplaceChildPointer(idx_t pos, Node *node) override; + //! Returns whether the child at pos is in memory + bool ChildIsInMemory(idx_t pos) override; //! Insert a new child node at key_byte into the Node16 - static void InsertChild(Node *&node, uint8_t key_byte, Node *new_child); + static void InsertChild(ART &art, Node *&node, uint8_t key_byte, Node *new_child); //! Erase the child at pos and (if necessary) shrink to Node4 - static void EraseChild(Node *&node, int pos, ART &art); - //! Merge Node16 into l_node - static bool Merge(MergeInfo &info, idx_t depth, Node *&l_parent, idx_t l_pos); + static void EraseChild(ART &art, Node *&node, idx_t pos); + //! Returns the size (maximum capacity) of the Node16 - static idx_t GetSize(); + static constexpr idx_t GetSize() { + return 16; + } }; } // namespace duckdb @@ -8416,11 +9414,15 @@ namespace duckdb { class Node256 : public Node { public: + //! Empty Node256 explicit Node256(); + //! ART pointers to the child nodes ARTPointer children[256]; public: static Node256 *New(); + //! Returns the memory size of the Node256 + idx_t MemorySize(ART &art, const bool &recurse) override; //! Get position of a specific byte, returns DConstants::INVALID_INDEX if not exists idx_t GetChildPos(uint8_t k) override; //! Get the position of the first child that is greater or equal to the specific byte, or DConstants::INVALID_INDEX @@ -8430,19 +9432,24 @@ class Node256 : public Node { idx_t GetMin() override; //! Get the next position in the node, or DConstants::INVALID_INDEX if there is no next position idx_t GetNextPos(idx_t pos) override; + //! Get the next position in the node, or DConstants::INVALID_INDEX if there is no next position + idx_t GetNextPosAndByte(idx_t pos, uint8_t &byte) override; //! Get Node256 child Node *GetChild(ART &art, idx_t pos) override; //! Replace child pointer void ReplaceChildPointer(idx_t pos, Node *node) override; + //! Returns whether the child at pos is in memory + bool ChildIsInMemory(idx_t pos) override; //! Insert a new child node at key_byte into the Node256 - static void InsertChild(Node *&node, uint8_t key_byte, Node *new_child); + static void InsertChild(ART &art, Node *&node, uint8_t key_byte, Node *new_child); //! Erase the child at pos and (if necessary) shrink to Node48 - static void EraseChild(Node *&node, int pos, ART &art); - //! Merge Node256 into l_node - static bool Merge(MergeInfo &info, idx_t depth, Node *&l_parent, idx_t l_pos); + static void EraseChild(ART &art, Node *&node, idx_t pos); + //! Returns the size (maximum capacity) of the Node256 - static idx_t GetSize(); + static constexpr idx_t GetSize() { + return 256; + } }; } // namespace duckdb @@ -8462,14 +9469,17 @@ namespace duckdb { class Node4 : public Node { public: - Node4(); - + //! Empty Node4 + explicit Node4(); + //! Array containing all partial key bytes uint8_t key[4]; - // Pointers to the child nodes + //! ART pointers to the child nodes ARTPointer children[4]; public: static Node4 *New(); + //! Returns the memory size of the Node4 + idx_t MemorySize(ART &art, const bool &recurse) override; //! Get position of a byte, returns DConstants::INVALID_INDEX if not exists idx_t GetChildPos(uint8_t k) override; //! Get the position of the first child that is greater or equal to the specific byte, or DConstants::INVALID_INDEX @@ -8479,19 +9489,24 @@ class Node4 : public Node { idx_t GetMin() override; //! Get the next position in the node, or DConstants::INVALID_INDEX if there is no next position idx_t GetNextPos(idx_t pos) override; + //! Get the next position in the node, or DConstants::INVALID_INDEX if there is no next position + idx_t GetNextPosAndByte(idx_t pos, uint8_t &byte) override; //! Get Node4 child Node *GetChild(ART &art, idx_t pos) override; //! Replace child pointer void ReplaceChildPointer(idx_t pos, Node *node) override; + //! Returns whether the child at pos is in memory + bool ChildIsInMemory(idx_t pos) override; //! Insert a new child node at key_byte into the Node4 - static void InsertChild(Node *&node, uint8_t key_byte, Node *new_child); + static void InsertChild(ART &art, Node *&node, uint8_t key_byte, Node *new_child); //! Erase the child at pos and (if necessary) merge with last child - static void EraseChild(Node *&node, int pos, ART &art); - //! Merge Node4 into l_node - static bool Merge(MergeInfo &info, idx_t depth, Node *&l_parent, idx_t l_pos); + static void EraseChild(ART &art, Node *&node, idx_t pos); + //! Returns the size (maximum capacity) of the Node4 - static idx_t GetSize(); + static constexpr idx_t GetSize() { + return 4; + } }; } // namespace duckdb @@ -8511,12 +9526,17 @@ namespace duckdb { class Node48 : public Node { public: + //! Empty Node48 explicit Node48(); + //! Array containing all possible partial key bytes, those not set have an EMPTY_MARKER uint8_t child_index[256]; + //! ART pointers to the child nodes ARTPointer children[48]; public: static Node48 *New(); + //! Returns the memory size of the Node48 + idx_t MemorySize(ART &art, const bool &recurse) override; //! Get position of a specific byte, returns DConstants::INVALID_INDEX if not exists idx_t GetChildPos(uint8_t k) override; //! Get the position of the first child that is greater or equal to the specific byte, or DConstants::INVALID_INDEX @@ -8526,19 +9546,23 @@ class Node48 : public Node { idx_t GetMin() override; //! Get the next position in the node, or DConstants::INVALID_INDEX if there is no next position idx_t GetNextPos(idx_t pos) override; + //! Get the next position in the node, or DConstants::INVALID_INDEX if there is no next position + idx_t GetNextPosAndByte(idx_t pos, uint8_t &byte) override; //! Get Node48 child Node *GetChild(ART &art, idx_t pos) override; //! Replace child pointer void ReplaceChildPointer(idx_t pos, Node *node) override; + //! Returns whether the child at pos is in memory + bool ChildIsInMemory(idx_t pos) override; //! Insert a new child node at key_byte into the Node48 - static void InsertChild(Node *&node, uint8_t key_byte, Node *new_child); + static void InsertChild(ART &art, Node *&node, uint8_t key_byte, Node *new_child); //! Erase the child at pos and (if necessary) shrink to Node16 - static void EraseChild(Node *&node, int pos, ART &art); - //! Merge Node48 into l_node - static bool Merge(MergeInfo &info, idx_t depth, Node *&l_parent, idx_t l_pos); + static void EraseChild(ART &art, Node *&node, idx_t pos); //! Returns the size (maximum capacity) of the Node48 - static idx_t GetSize(); + static constexpr idx_t GetSize() { + return 48; + } }; } // namespace duckdb @@ -8549,6 +9573,8 @@ class Node48 : public Node { namespace duckdb { +class ConflictManager; + struct ARTIndexScanState : public IndexScanState { ARTIndexScanState() : checked(false), result_index(0) { } @@ -8564,7 +9590,7 @@ struct ARTIndexScanState : public IndexScanState { idx_t result_index = 0; }; -enum VerifyExistenceType : uint8_t { +enum class VerifyExistenceType : uint8_t { APPEND = 0, // for purpose to append into table APPEND_FK = 1, // for purpose to append into table has foreign key DELETE_FK = 2 // for purpose to delete from table related to foreign key @@ -8572,27 +9598,26 @@ enum VerifyExistenceType : uint8_t { class ART : public Index { public: + //! Constructs an ART containing the bound expressions, which are resolved during index construction ART(const vector &column_ids, TableIOManager &table_io_manager, const vector> &unbound_expressions, IndexConstraintType constraint_type, - DatabaseInstance &db, idx_t block_id = DConstants::INVALID_INDEX, + AttachedDatabase &db, bool track_memory, idx_t block_id = DConstants::INVALID_INDEX, idx_t block_offset = DConstants::INVALID_INDEX); ~ART() override; //! Root of the tree Node *tree; - DatabaseInstance &db; - public: //! Initialize a scan on the index with the given expression and column ids //! to fetch from the base table for a single predicate - unique_ptr InitializeScanSinglePredicate(Transaction &transaction, Value value, + unique_ptr InitializeScanSinglePredicate(const Transaction &transaction, const Value &value, ExpressionType expression_type) override; //! Initialize a scan on the index with the given expression and column ids //! to fetch from the base table for two predicates - unique_ptr InitializeScanTwoPredicates(Transaction &transaction, Value low_value, - ExpressionType low_expression_type, Value high_value, + unique_ptr InitializeScanTwoPredicates(Transaction &transaction, const Value &low_value, + ExpressionType low_expression_type, const Value &high_value, ExpressionType high_expression_type) override; //! Perform a lookup on the index @@ -8602,17 +9627,19 @@ class ART : public Index { bool Append(IndexLock &lock, DataChunk &entries, Vector &row_identifiers) override; //! Verify that data can be appended to the index void VerifyAppend(DataChunk &chunk) override; + //! Verify that data can be appended to the index + void VerifyAppend(DataChunk &chunk, ConflictManager &conflict_manager) override; //! Verify that data can be appended to the index for foreign key constraint - void VerifyAppendForeignKey(DataChunk &chunk, string *err_msg_ptr) override; + void VerifyAppendForeignKey(DataChunk &chunk) override; //! Verify that data can be delete from the index for foreign key constraint - void VerifyDeleteForeignKey(DataChunk &chunk, string *err_msg_ptr) override; + void VerifyDeleteForeignKey(DataChunk &chunk) override; //! Delete entries in the index void Delete(IndexLock &lock, DataChunk &entries, Vector &row_identifiers) override; - //! Insert data into the index. + //! Insert data into the index bool Insert(IndexLock &lock, DataChunk &data, Vector &row_ids) override; - //! Construct ARTs from sorted chunks and merge them. - void ConstructAndMerge(IndexLock &lock, PayloadScanner &scanner, Allocator &allocator) override; + //! Construct an ART from a vector of sorted keys + bool ConstructFromSorted(idx_t count, vector &keys, Vector &row_identifiers); //! Search Equal and fetches the row IDs bool SearchEqual(Key &key, idx_t max_count, vector &result_ids); @@ -8625,8 +9652,16 @@ class ART : public Index { bool MergeIndexes(IndexLock &state, Index *other_index) override; //! Generate ART keys for an input chunk static void GenerateKeys(ArenaAllocator &allocator, DataChunk &input, vector &keys); + + //! Generate a string containing all the expressions and their respective values that violate a constraint + string GenerateErrorKeyName(DataChunk &input, idx_t row); + //! Generate the matching error message for a constraint violation + string GenerateConstraintErrorMessage(VerifyExistenceType verify_type, const string &key_name); + //! Returns the string representation of an ART string ToString() override; + //! Verifies that the memory_size value of the ART matches its actual size + void Verify() override; private: //! Insert a row id into a leaf node @@ -8637,6 +9672,9 @@ class ART : public Index { //! Erase element from leaf (if leaf has more than one value) or eliminate the leaf itself void Erase(Node *&node, Key &key, idx_t depth, row_t row_id); + //! Perform 'Lookup' for an entire chunk, marking which succeeded + void LookupValues(DataChunk &input, ConflictManager &conflict_manager) final override; + //! Find the node with a matching key, optimistic version Leaf *Lookup(Node *node, Key &key, idx_t depth); @@ -8645,27 +9683,18 @@ class ART : public Index { vector &result_ids); bool SearchCloseRange(ARTIndexScanState *state, Key &lower_bound, Key &upper_bound, bool left_inclusive, bool right_inclusive, idx_t max_count, vector &result_ids); - - void VerifyExistence(DataChunk &chunk, VerifyExistenceType verify_type, string *err_msg_ptr = nullptr); - -private: - //! The estimated ART memory consumption - idx_t estimated_art_size; - //! The estimated memory consumption of a single key - idx_t estimated_key_size; }; } // namespace duckdb - namespace duckdb { -IndexCatalogEntry::IndexCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateIndexInfo *info) - : StandardEntry(CatalogType::INDEX_ENTRY, schema, catalog, info->index_name), index(nullptr), sql(info->sql) { +DuckIndexEntry::DuckIndexEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateIndexInfo *info) + : IndexCatalogEntry(catalog, schema, info) { } -IndexCatalogEntry::~IndexCatalogEntry() { +DuckIndexEntry::~DuckIndexEntry() { // remove the associated index from the info if (!info || !index) { return; @@ -8673,75 +9702,19 @@ IndexCatalogEntry::~IndexCatalogEntry() { info->indexes.RemoveIndex(index); } -string IndexCatalogEntry::ToSQL() { - if (sql.empty()) { - throw InternalException("Cannot convert INDEX to SQL because it was not created with a SQL statement"); - } - if (sql[sql.size() - 1] != ';') { - sql += ";"; - } - return sql; +string DuckIndexEntry::GetSchemaName() { + return info->schema; } -void IndexCatalogEntry::Serialize(duckdb::MetaBlockWriter &serializer) { - // Here we serialize the index metadata in the following order: - // schema name, table name, index name, sql, index type, index constraint type, expression list. - // column_ids, unbound_expression - FieldWriter writer(serializer); - writer.WriteString(info->schema); - writer.WriteString(info->table); - writer.WriteString(name); - writer.WriteString(sql); - writer.WriteField(index->type); - writer.WriteField(index->constraint_type); - writer.WriteSerializableList(expressions); - writer.WriteSerializableList(parsed_expressions); - writer.WriteList(index->column_ids); - writer.Finalize(); -} - -unique_ptr IndexCatalogEntry::Deserialize(Deserializer &source, ClientContext &context) { - // Here we deserialize the index metadata in the following order: - // root block, root offset, schema name, table name, index name, sql, index type, index constraint type, expression - // list. - - auto create_index_info = make_unique(); - - FieldReader reader(source); - - create_index_info->schema = reader.ReadRequired(); - create_index_info->table = make_unique(); - create_index_info->table->schema_name = create_index_info->schema; - create_index_info->table->table_name = reader.ReadRequired(); - create_index_info->index_name = reader.ReadRequired(); - create_index_info->sql = reader.ReadRequired(); - create_index_info->index_type = IndexType(reader.ReadRequired()); - create_index_info->constraint_type = IndexConstraintType(reader.ReadRequired()); - create_index_info->expressions = reader.ReadRequiredSerializableList(); - create_index_info->parsed_expressions = reader.ReadRequiredSerializableList(); - - create_index_info->column_ids = reader.ReadRequiredList(); - reader.Finalize(); - return create_index_info; -} - -} // namespace duckdb - - - -namespace duckdb { - -PragmaFunctionCatalogEntry::PragmaFunctionCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, - CreatePragmaFunctionInfo *info) - : StandardEntry(CatalogType::PRAGMA_FUNCTION_ENTRY, schema, catalog, info->name), functions(move(info->functions)) { +string DuckIndexEntry::GetTableName() { + return info->table; } } // namespace duckdb - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/parser/parsed_data/alter_function_info.hpp +// duckdb/catalog/catalog_entry/dschema_catalog_entry.hpp // // //===----------------------------------------------------------------------===// @@ -8750,288 +9723,64 @@ PragmaFunctionCatalogEntry::PragmaFunctionCatalogEntry(Catalog *catalog, SchemaC - - namespace duckdb { -//===--------------------------------------------------------------------===// -// Alter Table -//===--------------------------------------------------------------------===// -enum class AlterFunctionType : uint8_t { INVALID = 0, ADD_FUNCTION_OVERLOADS = 1 }; - -struct AlterFunctionInfo : public AlterInfo { - AlterFunctionInfo(AlterFunctionType type, string schema, string name, bool if_exists); - virtual ~AlterFunctionInfo() override; - - AlterFunctionType alter_function_type; - +//! A schema in the catalog +class DuckSchemaEntry : public SchemaCatalogEntry { public: - CatalogType GetCatalogType() const override; - void Serialize(FieldWriter &writer) const override; - static unique_ptr Deserialize(FieldReader &reader); -}; - -//===--------------------------------------------------------------------===// -// AddFunctionOverloadInfo -//===--------------------------------------------------------------------===// -struct AddFunctionOverloadInfo : public AlterFunctionInfo { - AddFunctionOverloadInfo(string schema, string name, bool if_exists, ScalarFunctionSet new_overloads); - ~AddFunctionOverloadInfo() override; - - ScalarFunctionSet new_overloads; - -public: - unique_ptr Copy() const override; -}; - -} // namespace duckdb - - -namespace duckdb { - -ScalarFunctionCatalogEntry::ScalarFunctionCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, - CreateScalarFunctionInfo *info) - : StandardEntry(CatalogType::SCALAR_FUNCTION_ENTRY, schema, catalog, info->name), functions(info->functions) { -} - -unique_ptr ScalarFunctionCatalogEntry::AlterEntry(ClientContext &context, AlterInfo *info) { - if (info->type != AlterType::ALTER_FUNCTION) { - throw InternalException("Attempting to alter ScalarFunctionCatalogEntry with unsupported alter type"); - } - auto &function_info = (AlterFunctionInfo &)*info; - if (function_info.alter_function_type != AlterFunctionType::ADD_FUNCTION_OVERLOADS) { - throw InternalException("Attempting to alter ScalarFunctionCatalogEntry with unsupported alter function type"); - } - auto &add_overloads = (AddFunctionOverloadInfo &)function_info; - - ScalarFunctionSet new_set = functions; - if (!new_set.MergeFunctionSet(add_overloads.new_overloads)) { - throw BinderException("Failed to add new function overloads to function \"%s\": function already exists", name); - } - CreateScalarFunctionInfo new_info(move(new_set)); - return make_unique(catalog, schema, &new_info); -} - -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/catalog/catalog_entry/macro_catalog_entry.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - + DuckSchemaEntry(Catalog *catalog, string name, bool is_internal); +private: + //! The catalog set holding the tables + CatalogSet tables; + //! The catalog set holding the indexes + CatalogSet indexes; + //! The catalog set holding the table functions + CatalogSet table_functions; + //! The catalog set holding the copy functions + CatalogSet copy_functions; + //! The catalog set holding the pragma functions + CatalogSet pragma_functions; + //! The catalog set holding the scalar and aggregate functions + CatalogSet functions; + //! The catalog set holding the sequences + CatalogSet sequences; + //! The catalog set holding the collations + CatalogSet collations; + //! The catalog set holding the types + CatalogSet types; + +public: + CatalogEntry *AddEntry(CatalogTransaction transaction, unique_ptr entry, + OnCreateConflict on_conflict); + CatalogEntry *AddEntryInternal(CatalogTransaction transaction, unique_ptr entry, + OnCreateConflict on_conflict, DependencyList dependencies); + + CatalogEntry *CreateTable(CatalogTransaction transaction, BoundCreateTableInfo *info) override; + CatalogEntry *CreateFunction(CatalogTransaction transaction, CreateFunctionInfo *info) override; + CatalogEntry *CreateIndex(ClientContext &context, CreateIndexInfo *info, TableCatalogEntry *table) override; + CatalogEntry *CreateView(CatalogTransaction transaction, CreateViewInfo *info) override; + CatalogEntry *CreateSequence(CatalogTransaction transaction, CreateSequenceInfo *info) override; + CatalogEntry *CreateTableFunction(CatalogTransaction transaction, CreateTableFunctionInfo *info) override; + CatalogEntry *CreateCopyFunction(CatalogTransaction transaction, CreateCopyFunctionInfo *info) override; + CatalogEntry *CreatePragmaFunction(CatalogTransaction transaction, CreatePragmaFunctionInfo *info) override; + CatalogEntry *CreateCollation(CatalogTransaction transaction, CreateCollationInfo *info) override; + CatalogEntry *CreateType(CatalogTransaction transaction, CreateTypeInfo *info) override; + void Alter(ClientContext &context, AlterInfo *info) override; + void Scan(ClientContext &context, CatalogType type, const std::function &callback) override; + void Scan(CatalogType type, const std::function &callback) override; + void DropEntry(ClientContext &context, DropInfo *info) override; + CatalogEntry *GetEntry(CatalogTransaction transaction, CatalogType type, const string &name) override; + SimilarCatalogEntry GetSimilarEntry(CatalogTransaction transaction, CatalogType type, const string &name) override; + + void Verify(Catalog &catalog) override; -namespace duckdb { - -//! A macro function in the catalog -class TableMacroCatalogEntry : public MacroCatalogEntry { -public: - TableMacroCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateMacroInfo *info); - -public: - //! Serialize the meta information of the ScalarMacroCatalogEntry - void Serialize(Serializer &serializer) override; - //! Deserializes to a CreateMacroInfo - static unique_ptr Deserialize(Deserializer &source, ClientContext &context); -}; - -} // namespace duckdb - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/function/scalar_macro_function.hpp -// -// -//===----------------------------------------------------------------------===// - - -//! The SelectStatement of the view - - - - - - - - -namespace duckdb { - -class ScalarMacroFunction : public MacroFunction { -public: - ScalarMacroFunction(unique_ptr expression); - - ScalarMacroFunction(void); - //! The macro expression - unique_ptr expression; - -public: - unique_ptr Copy() override; - - string ToSQL(const string &schema, const string &name) override; -}; - -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/function/table_macro_function.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - - - - - -namespace duckdb { - -class TableMacroFunction : public MacroFunction { -public: - TableMacroFunction(unique_ptr query_node); - TableMacroFunction(void); - - //! The main query node - unique_ptr query_node; - -public: - unique_ptr Copy() override; - - string ToSQL(const string &schema, const string &name) override; +private: + //! Get the catalog set for the specified type + CatalogSet &GetCatalogSet(CatalogType type); }; - -} // namespace duckdb - - -namespace duckdb { - -MacroCatalogEntry::MacroCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateMacroInfo *info) - : StandardEntry( - (info->function->type == MacroType::SCALAR_MACRO ? CatalogType::MACRO_ENTRY : CatalogType::TABLE_MACRO_ENTRY), - schema, catalog, info->name), - function(move(info->function)) { - this->temporary = info->temporary; - this->internal = info->internal; -} - -ScalarMacroCatalogEntry::ScalarMacroCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateMacroInfo *info) - : MacroCatalogEntry(catalog, schema, info) { -} - -void ScalarMacroCatalogEntry::Serialize(Serializer &main_serializer) { - D_ASSERT(!internal); - auto &scalar_function = (ScalarMacroFunction &)*function; - FieldWriter writer(main_serializer); - writer.WriteString(schema->name); - writer.WriteString(name); - writer.WriteSerializable(*scalar_function.expression); - // writer.WriteSerializableList(function->parameters); - writer.WriteSerializableList(function->parameters); - writer.WriteField((uint32_t)function->default_parameters.size()); - auto &serializer = writer.GetSerializer(); - for (auto &kv : function->default_parameters) { - serializer.WriteString(kv.first); - kv.second->Serialize(serializer); - } - writer.Finalize(); -} - -unique_ptr ScalarMacroCatalogEntry::Deserialize(Deserializer &main_source, ClientContext &context) { - auto info = make_unique(CatalogType::MACRO_ENTRY); - FieldReader reader(main_source); - info->schema = reader.ReadRequired(); - info->name = reader.ReadRequired(); - auto expression = reader.ReadRequiredSerializable(); - auto func = make_unique(move(expression)); - info->function = move(func); - info->function->parameters = reader.ReadRequiredSerializableList(); - auto default_param_count = reader.ReadRequired(); - auto &source = reader.GetSource(); - for (idx_t i = 0; i < default_param_count; i++) { - auto name = source.Read(); - info->function->default_parameters[name] = ParsedExpression::Deserialize(source); - } - // dont like this - // info->type=CatalogType::MACRO_ENTRY; - reader.Finalize(); - return info; -} - -TableMacroCatalogEntry::TableMacroCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateMacroInfo *info) - : MacroCatalogEntry(catalog, schema, info) { -} - -void TableMacroCatalogEntry::Serialize(Serializer &main_serializer) { - D_ASSERT(!internal); - FieldWriter writer(main_serializer); - - auto &table_function = (TableMacroFunction &)*function; - writer.WriteString(schema->name); - writer.WriteString(name); - writer.WriteSerializable(*table_function.query_node); - writer.WriteSerializableList(function->parameters); - writer.WriteField((uint32_t)function->default_parameters.size()); - auto &serializer = writer.GetSerializer(); - for (auto &kv : function->default_parameters) { - serializer.WriteString(kv.first); - kv.second->Serialize(serializer); - } - writer.Finalize(); -} - -unique_ptr TableMacroCatalogEntry::Deserialize(Deserializer &main_source, ClientContext &context) { - auto info = make_unique(CatalogType::TABLE_MACRO_ENTRY); - FieldReader reader(main_source); - info->schema = reader.ReadRequired(); - info->name = reader.ReadRequired(); - auto query_node = reader.ReadRequiredSerializable(); - auto table_function = make_unique(move(query_node)); - info->function = move(table_function); - info->function->parameters = reader.ReadRequiredSerializableList(); - auto default_param_count = reader.ReadRequired(); - auto &source = reader.GetSource(); - for (idx_t i = 0; i < default_param_count; i++) { - auto name = source.Read(); - info->function->default_parameters[name] = ParsedExpression::Deserialize(source); - } - - reader.Finalize(); - - return info; -} - } // namespace duckdb - - - - - - - - - - - - - - - //===----------------------------------------------------------------------===// // DuckDB // @@ -9105,24 +9854,21 @@ class DefaultViewGenerator : public DefaultGenerator { } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/algorithm.hpp -// -// -//===----------------------------------------------------------------------===// -#include + + + + + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/parser/constraints/foreign_key_constraint.hpp +// duckdb/catalog/catalog_entry/macro_catalog_entry.hpp // // //===----------------------------------------------------------------------===// @@ -9132,40 +9878,98 @@ class DefaultViewGenerator : public DefaultGenerator { + namespace duckdb { -class ForeignKeyConstraint : public Constraint { +//! A macro function in the catalog +class TableMacroCatalogEntry : public MacroCatalogEntry { public: - DUCKDB_API ForeignKeyConstraint(vector pk_columns, vector fk_columns, ForeignKeyInfo info); - - //! The set of main key table's columns - vector pk_columns; - //! The set of foreign key table's columns - vector fk_columns; - ForeignKeyInfo info; + static constexpr const CatalogType Type = CatalogType::TABLE_MACRO_ENTRY; + static constexpr const char *Name = "table macro function"; public: - DUCKDB_API string ToString() const override; - - DUCKDB_API unique_ptr Copy() const override; + TableMacroCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateMacroInfo *info); - //! Serialize to a stand-alone binary blob - DUCKDB_API void Serialize(FieldWriter &writer) const override; - //! Deserializes a ParsedConstraint - DUCKDB_API static unique_ptr Deserialize(FieldReader &source); +public: + //! Serialize the meta information of the ScalarMacroCatalogEntry + void Serialize(Serializer &serializer) override; + //! Deserializes to a CreateMacroInfo + static unique_ptr Deserialize(Deserializer &source, ClientContext &context); }; } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/catalog/catalog_entry/dtable_catalog_entry.hpp +// +// +//===----------------------------------------------------------------------===// + + + + +namespace duckdb { +//! A table catalog entry +class DuckTableEntry : public TableCatalogEntry { +public: + //! Create a TableCatalogEntry and initialize storage for it + DuckTableEntry(Catalog *catalog, SchemaCatalogEntry *schema, BoundCreateTableInfo *info, + std::shared_ptr inherited_storage = nullptr); +public: + unique_ptr AlterEntry(ClientContext &context, AlterInfo *info) override; + void UndoAlter(ClientContext &context, AlterInfo *info) override; + //! Returns the underlying storage of the table + DataTable &GetStorage() override; + DataTable *GetStoragePtr() override; + //! Returns a list of the bound constraints of the table + const vector> &GetBoundConstraints() override; + //! Get statistics of a column (physical or virtual) within the table + unique_ptr GetStatistics(ClientContext &context, column_t column_id) override; + unique_ptr Copy(ClientContext &context) override; + void SetAsRoot() override; + void CommitAlter(AlterInfo &info); + void CommitDrop(); + TableFunction GetScanFunction(ClientContext &context, unique_ptr &bind_data) override; + TableStorageInfo GetStorageInfo(ClientContext &context) override; + + bool IsDuckTable() override { + return true; + } + +private: + unique_ptr RenameColumn(ClientContext &context, RenameColumnInfo &info); + unique_ptr AddColumn(ClientContext &context, AddColumnInfo &info); + unique_ptr RemoveColumn(ClientContext &context, RemoveColumnInfo &info); + unique_ptr SetDefault(ClientContext &context, SetDefaultInfo &info); + unique_ptr ChangeColumnType(ClientContext &context, ChangeColumnTypeInfo &info); + unique_ptr SetNotNull(ClientContext &context, SetNotNullInfo &info); + unique_ptr DropNotNull(ClientContext &context, DropNotNullInfo &info); + unique_ptr AddForeignKeyConstraint(ClientContext &context, AlterForeignKeyInfo &info); + unique_ptr DropForeignKeyConstraint(ClientContext &context, AlterForeignKeyInfo &info); + + void UpdateConstraintsOnColumnDrop(const LogicalIndex &removed_index, const vector &adjusted_indices, + const RemoveColumnInfo &info, CreateTableInfo &create_info, bool is_generated); + +private: + //! A reference to the underlying storage unit used for this table + std::shared_ptr storage; + //! A list of constraints that are part of this table + vector> bound_constraints; + //! Manages dependencies of the individual columns of the table + ColumnDependencyManager column_dependency_manager; +}; +} // namespace duckdb @@ -9189,8 +9993,8 @@ class BoundForeignKeyConstraint : public BoundConstraint { public: BoundForeignKeyConstraint(ForeignKeyInfo info_p, physical_index_set_t pk_key_set_p, physical_index_set_t fk_key_set_p) - : BoundConstraint(ConstraintType::FOREIGN_KEY), info(move(info_p)), pk_key_set(move(pk_key_set_p)), - fk_key_set(move(fk_key_set_p)) { + : BoundConstraint(ConstraintType::FOREIGN_KEY), info(std::move(info_p)), pk_key_set(std::move(pk_key_set_p)), + fk_key_set(std::move(fk_key_set_p)) { #ifdef DEBUG D_ASSERT(info.pk_keys.size() == pk_key_set.size()); for (auto &key : info.pk_keys) { @@ -9212,10 +10016,58 @@ class BoundForeignKeyConstraint : public BoundConstraint { } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/constraints/foreign_key_constraint.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +class ForeignKeyConstraint : public Constraint { +public: + DUCKDB_API ForeignKeyConstraint(vector pk_columns, vector fk_columns, ForeignKeyInfo info); + + //! The set of main key table's columns + vector pk_columns; + //! The set of foreign key table's columns + vector fk_columns; + ForeignKeyInfo info; + +public: + DUCKDB_API string ToString() const override; + + DUCKDB_API unique_ptr Copy() const override; + + //! Serialize to a stand-alone binary blob + DUCKDB_API void Serialize(FieldWriter &writer) const override; + //! Deserializes a ParsedConstraint + DUCKDB_API static unique_ptr Deserialize(FieldReader &source); +}; + +} // namespace duckdb + + + + + + + + + + + + -#include namespace duckdb { @@ -9225,16 +10077,18 @@ void FindForeignKeyInformation(CatalogEntry *entry, AlterForeignKeyType alter_fk return; } auto *table_entry = (TableCatalogEntry *)entry; - for (idx_t i = 0; i < table_entry->constraints.size(); i++) { - auto &cond = table_entry->constraints[i]; + auto &constraints = table_entry->GetConstraints(); + for (idx_t i = 0; i < constraints.size(); i++) { + auto &cond = constraints[i]; if (cond->type != ConstraintType::FOREIGN_KEY) { continue; } auto &fk = (ForeignKeyConstraint &)*cond; if (fk.info.type == ForeignKeyType::FK_TYPE_FOREIGN_KEY_TABLE) { - fk_arrays.push_back(make_unique(fk.info.schema, fk.info.table, false, entry->name, - fk.pk_columns, fk.fk_columns, fk.info.pk_keys, - fk.info.fk_keys, alter_fk_type)); + AlterEntryData alter_data(entry->catalog->GetName(), fk.info.schema, fk.info.table, false); + fk_arrays.push_back(make_unique(std::move(alter_data), entry->name, fk.pk_columns, + fk.fk_columns, fk.info.pk_keys, fk.info.fk_keys, + alter_fk_type)); } else if (fk.info.type == ForeignKeyType::FK_TYPE_PRIMARY_KEY_TABLE && alter_fk_type == AlterForeignKeyType::AFT_DELETE) { throw CatalogException("Could not drop the table because this table is main key table of the table \"%s\"", @@ -9243,42 +10097,36 @@ void FindForeignKeyInformation(CatalogEntry *entry, AlterForeignKeyType alter_fk } } -SchemaCatalogEntry::SchemaCatalogEntry(Catalog *catalog, string name_p, bool internal) - : CatalogEntry(CatalogType::SCHEMA_ENTRY, catalog, move(name_p)), +DuckSchemaEntry::DuckSchemaEntry(Catalog *catalog, string name_p, bool is_internal) + : SchemaCatalogEntry(catalog, std::move(name_p), is_internal), tables(*catalog, make_unique(*catalog, this)), indexes(*catalog), table_functions(*catalog), copy_functions(*catalog), pragma_functions(*catalog), functions(*catalog, make_unique(*catalog, this)), sequences(*catalog), collations(*catalog), types(*catalog, make_unique(*catalog, this)) { - this->internal = internal; } -CatalogEntry *SchemaCatalogEntry::AddEntry(ClientContext &context, unique_ptr entry, - OnCreateConflict on_conflict, unordered_set dependencies) { +CatalogEntry *DuckSchemaEntry::AddEntryInternal(CatalogTransaction transaction, unique_ptr entry, + OnCreateConflict on_conflict, DependencyList dependencies) { auto entry_name = entry->name; auto entry_type = entry->type; auto result = entry.get(); // first find the set for this entry auto &set = GetCatalogSet(entry_type); - - if (name != TEMP_SCHEMA) { - dependencies.insert(this); - } else { - entry->temporary = true; - } + dependencies.AddDependency(this); if (on_conflict == OnCreateConflict::REPLACE_ON_CONFLICT) { // CREATE OR REPLACE: first try to drop the entry - auto old_entry = set.GetEntry(context, entry_name); + auto old_entry = set.GetEntry(transaction, entry_name); if (old_entry) { if (old_entry->type != entry_type) { throw CatalogException("Existing object %s is of type %s, trying to replace with type %s", entry_name, CatalogTypeToString(old_entry->type), CatalogTypeToString(entry_type)); } - (void)set.DropEntry(context, entry_name, false); + (void)set.DropEntry(transaction, entry_name, false, entry->internal); } } // now try to add the entry - if (!set.CreateEntry(context, entry_name, move(entry), dependencies)) { + if (!set.CreateEntry(transaction, entry_name, std::move(entry), dependencies)) { // entry already exists! if (on_conflict == OnCreateConflict::ERROR_ON_CONFLICT) { throw CatalogException("%s with name \"%s\" already exists!", CatalogTypeToString(entry_type), entry_name); @@ -9289,27 +10137,12 @@ CatalogEntry *SchemaCatalogEntry::AddEntry(ClientContext &context, unique_ptr entry, - OnCreateConflict on_conflict) { - unordered_set dependencies; - return AddEntry(context, move(entry), on_conflict, dependencies); -} +CatalogEntry *DuckSchemaEntry::CreateTable(CatalogTransaction transaction, BoundCreateTableInfo *info) { + auto table = make_unique(catalog, this, info); + auto &storage = table->GetStorage(); + storage.info->cardinality = storage.GetTotalRows(); -CatalogEntry *SchemaCatalogEntry::CreateSequence(ClientContext &context, CreateSequenceInfo *info) { - auto sequence = make_unique(catalog, this, info); - return AddEntry(context, move(sequence), info->on_conflict); -} - -CatalogEntry *SchemaCatalogEntry::CreateType(ClientContext &context, CreateTypeInfo *info) { - auto type_entry = make_unique(catalog, this, info); - return AddEntry(context, move(type_entry), info->on_conflict); -} - -CatalogEntry *SchemaCatalogEntry::CreateTable(ClientContext &context, BoundCreateTableInfo *info) { - auto table = make_unique(catalog, this, info); - table->storage->info->cardinality = table->storage->GetTotalRows(); - - CatalogEntry *entry = AddEntry(context, move(table), info->Base().on_conflict, info->dependencies); + CatalogEntry *entry = AddEntryInternal(transaction, std::move(table), info->Base().on_conflict, info->dependencies); if (!entry) { return nullptr; } @@ -9320,56 +10153,24 @@ CatalogEntry *SchemaCatalogEntry::CreateTable(ClientContext &context, BoundCreat for (idx_t i = 0; i < fk_arrays.size(); i++) { // alter primary key table AlterForeignKeyInfo *fk_info = fk_arrays[i].get(); - catalog->Alter(context, fk_info); + catalog->Alter(transaction.GetContext(), fk_info); // make a dependency between this table and referenced table auto &set = GetCatalogSet(CatalogType::TABLE_ENTRY); - info->dependencies.insert(set.GetEntry(context, fk_info->name)); + info->dependencies.AddDependency(set.GetEntry(transaction, fk_info->name)); } return entry; } -CatalogEntry *SchemaCatalogEntry::CreateView(ClientContext &context, CreateViewInfo *info) { - auto view = make_unique(catalog, this, info); - return AddEntry(context, move(view), info->on_conflict); -} - -CatalogEntry *SchemaCatalogEntry::CreateIndex(ClientContext &context, CreateIndexInfo *info, TableCatalogEntry *table) { - unordered_set dependencies; - dependencies.insert(table); - auto index = make_unique(catalog, this, info); - return AddEntry(context, move(index), info->on_conflict, dependencies); -} - -CatalogEntry *SchemaCatalogEntry::CreateCollation(ClientContext &context, CreateCollationInfo *info) { - auto collation = make_unique(catalog, this, info); - return AddEntry(context, move(collation), info->on_conflict); -} - -CatalogEntry *SchemaCatalogEntry::CreateTableFunction(ClientContext &context, CreateTableFunctionInfo *info) { - auto table_function = make_unique(catalog, this, info); - return AddEntry(context, move(table_function), info->on_conflict); -} - -CatalogEntry *SchemaCatalogEntry::CreateCopyFunction(ClientContext &context, CreateCopyFunctionInfo *info) { - auto copy_function = make_unique(catalog, this, info); - return AddEntry(context, move(copy_function), info->on_conflict); -} - -CatalogEntry *SchemaCatalogEntry::CreatePragmaFunction(ClientContext &context, CreatePragmaFunctionInfo *info) { - auto pragma_function = make_unique(catalog, this, info); - return AddEntry(context, move(pragma_function), info->on_conflict); -} - -CatalogEntry *SchemaCatalogEntry::CreateFunction(ClientContext &context, CreateFunctionInfo *info) { +CatalogEntry *DuckSchemaEntry::CreateFunction(CatalogTransaction transaction, CreateFunctionInfo *info) { if (info->on_conflict == OnCreateConflict::ALTER_ON_CONFLICT) { // check if the original entry exists auto &catalog_set = GetCatalogSet(info->type); - auto current_entry = catalog_set.GetEntry(context, info->name); + auto current_entry = catalog_set.GetEntry(transaction, info->name); if (current_entry) { // the current entry exists - alter it instead auto alter_info = info->GetAlterInfo(); - Alter(context, alter_info.get()); + Alter(transaction.GetContext(), alter_info.get()); return nullptr; } } @@ -9397,120 +10198,128 @@ CatalogEntry *SchemaCatalogEntry::CreateFunction(ClientContext &context, CreateF default: throw InternalException("Unknown function type \"%s\"", CatalogTypeToString(info->type)); } - return AddEntry(context, move(function), info->on_conflict); + function->internal = info->internal; + return AddEntry(transaction, std::move(function), info->on_conflict); } -CatalogEntry *SchemaCatalogEntry::AddFunction(ClientContext &context, CreateFunctionInfo *info) { - auto entry = GetCatalogSet(info->type).GetEntry(context, info->name); - if (!entry) { - return CreateFunction(context, info); - } +CatalogEntry *DuckSchemaEntry::AddEntry(CatalogTransaction transaction, unique_ptr entry, + OnCreateConflict on_conflict) { + DependencyList dependencies; + return AddEntryInternal(transaction, std::move(entry), on_conflict, dependencies); +} - info->on_conflict = OnCreateConflict::REPLACE_ON_CONFLICT; - switch (info->type) { - case CatalogType::SCALAR_FUNCTION_ENTRY: { - auto scalar_info = (CreateScalarFunctionInfo *)info; - auto &scalars = *(ScalarFunctionCatalogEntry *)entry; - for (const auto &scalar : scalars.functions.functions) { - scalar_info->functions.AddFunction(scalar); - } - break; - } - case CatalogType::AGGREGATE_FUNCTION_ENTRY: { - auto agg_info = (CreateAggregateFunctionInfo *)info; - auto &aggs = *(AggregateFunctionCatalogEntry *)entry; - for (const auto &agg : aggs.functions.functions) { - agg_info->functions.AddFunction(agg); - } - break; - } - default: - // Macros can only be replaced because there is only one of each name. - throw InternalException("Unsupported function type \"%s\" for adding", CatalogTypeToString(info->type)); - } - return CreateFunction(context, info); +CatalogEntry *DuckSchemaEntry::CreateSequence(CatalogTransaction transaction, CreateSequenceInfo *info) { + auto sequence = make_unique(catalog, this, info); + return AddEntry(transaction, std::move(sequence), info->on_conflict); } -void SchemaCatalogEntry::DropEntry(ClientContext &context, DropInfo *info) { - auto &set = GetCatalogSet(info->type); +CatalogEntry *DuckSchemaEntry::CreateType(CatalogTransaction transaction, CreateTypeInfo *info) { + auto type_entry = make_unique(catalog, this, info); + return AddEntry(transaction, std::move(type_entry), info->on_conflict); +} - // first find the entry - auto existing_entry = set.GetEntry(context, info->name); - if (!existing_entry) { - if (!info->if_exists) { - throw CatalogException("%s with name \"%s\" does not exist!", CatalogTypeToString(info->type), info->name); - } - return; - } - if (existing_entry->type != info->type) { - throw CatalogException("Existing object %s is of type %s, trying to replace with type %s", info->name, - CatalogTypeToString(existing_entry->type), CatalogTypeToString(info->type)); - } +CatalogEntry *DuckSchemaEntry::CreateView(CatalogTransaction transaction, CreateViewInfo *info) { + auto view = make_unique(catalog, this, info); + return AddEntry(transaction, std::move(view), info->on_conflict); +} - // if there is a foreign key constraint, get that information - vector> fk_arrays; - FindForeignKeyInformation(existing_entry, AlterForeignKeyType::AFT_DELETE, fk_arrays); +CatalogEntry *DuckSchemaEntry::CreateIndex(ClientContext &context, CreateIndexInfo *info, TableCatalogEntry *table) { + DependencyList dependencies; + dependencies.AddDependency(table); + auto index = make_unique(catalog, this, info); + return AddEntryInternal(GetCatalogTransaction(context), std::move(index), info->on_conflict, dependencies); +} - if (!set.DropEntry(context, info->name, info->cascade)) { - throw InternalException("Could not drop element because of an internal error"); - } +CatalogEntry *DuckSchemaEntry::CreateCollation(CatalogTransaction transaction, CreateCollationInfo *info) { + auto collation = make_unique(catalog, this, info); + collation->internal = info->internal; + return AddEntry(transaction, std::move(collation), info->on_conflict); +} - // remove the foreign key constraint in main key table if main key table's name is valid - for (idx_t i = 0; i < fk_arrays.size(); i++) { - // alter primary key tablee - Catalog::GetCatalog(context).Alter(context, fk_arrays[i].get()); - } +CatalogEntry *DuckSchemaEntry::CreateTableFunction(CatalogTransaction transaction, CreateTableFunctionInfo *info) { + auto table_function = make_unique(catalog, this, info); + table_function->internal = info->internal; + return AddEntry(transaction, std::move(table_function), info->on_conflict); +} + +CatalogEntry *DuckSchemaEntry::CreateCopyFunction(CatalogTransaction transaction, CreateCopyFunctionInfo *info) { + auto copy_function = make_unique(catalog, this, info); + copy_function->internal = info->internal; + return AddEntry(transaction, std::move(copy_function), info->on_conflict); +} + +CatalogEntry *DuckSchemaEntry::CreatePragmaFunction(CatalogTransaction transaction, CreatePragmaFunctionInfo *info) { + auto pragma_function = make_unique(catalog, this, info); + pragma_function->internal = info->internal; + return AddEntry(transaction, std::move(pragma_function), info->on_conflict); } -void SchemaCatalogEntry::Alter(ClientContext &context, AlterInfo *info) { +void DuckSchemaEntry::Alter(ClientContext &context, AlterInfo *info) { CatalogType type = info->GetCatalogType(); auto &set = GetCatalogSet(type); + auto transaction = GetCatalogTransaction(context); if (info->type == AlterType::CHANGE_OWNERSHIP) { - if (!set.AlterOwnership(context, (ChangeOwnershipInfo *)info)) { + if (!set.AlterOwnership(transaction, (ChangeOwnershipInfo *)info)) { throw CatalogException("Couldn't change ownership!"); } } else { string name = info->name; - if (!set.AlterEntry(context, name, info)) { + if (!set.AlterEntry(transaction, name, info)) { throw CatalogException("Entry with name \"%s\" does not exist!", name); } } } -void SchemaCatalogEntry::Scan(ClientContext &context, CatalogType type, - const std::function &callback) { +void DuckSchemaEntry::Scan(ClientContext &context, CatalogType type, + const std::function &callback) { auto &set = GetCatalogSet(type); - set.Scan(context, callback); + set.Scan(GetCatalogTransaction(context), callback); } -void SchemaCatalogEntry::Scan(CatalogType type, const std::function &callback) { +void DuckSchemaEntry::Scan(CatalogType type, const std::function &callback) { auto &set = GetCatalogSet(type); set.Scan(callback); } -void SchemaCatalogEntry::Serialize(Serializer &serializer) { - FieldWriter writer(serializer); - writer.WriteString(name); - writer.Finalize(); -} +void DuckSchemaEntry::DropEntry(ClientContext &context, DropInfo *info) { + auto &set = GetCatalogSet(info->type); -unique_ptr SchemaCatalogEntry::Deserialize(Deserializer &source) { - auto info = make_unique(); + // first find the entry + auto transaction = GetCatalogTransaction(context); + auto existing_entry = set.GetEntry(transaction, info->name); + if (!existing_entry) { + throw InternalException("Failed to drop entry \"%s\" - entry could not be found", info->name); + } + if (existing_entry->type != info->type) { + throw CatalogException("Existing object %s is of type %s, trying to replace with type %s", info->name, + CatalogTypeToString(existing_entry->type), CatalogTypeToString(info->type)); + } - FieldReader reader(source); - info->schema = reader.ReadRequired(); - reader.Finalize(); + // if there is a foreign key constraint, get that information + vector> fk_arrays; + FindForeignKeyInformation(existing_entry, AlterForeignKeyType::AFT_DELETE, fk_arrays); - return info; + if (!set.DropEntry(transaction, info->name, info->cascade, info->allow_drop_internal)) { + throw InternalException("Could not drop element because of an internal error"); + } + + // remove the foreign key constraint in main key table if main key table's name is valid + for (idx_t i = 0; i < fk_arrays.size(); i++) { + // alter primary key table + catalog->Alter(context, fk_arrays[i].get()); + } } -string SchemaCatalogEntry::ToSQL() { - std::stringstream ss; - ss << "CREATE SCHEMA " << name << ";"; - return ss.str(); +CatalogEntry *DuckSchemaEntry::GetEntry(CatalogTransaction transaction, CatalogType type, const string &name) { + return GetCatalogSet(type).GetEntry(transaction, name); +} + +SimilarCatalogEntry DuckSchemaEntry::GetSimilarEntry(CatalogTransaction transaction, CatalogType type, + const string &name) { + return GetCatalogSet(type).SimilarEntry(transaction, name); } -CatalogSet &SchemaCatalogEntry::GetCatalogSet(CatalogType type) { +CatalogSet &DuckSchemaEntry::GetCatalogSet(CatalogType type) { switch (type) { case CatalogType::VIEW_ENTRY: case CatalogType::TABLE_ENTRY: @@ -9539,227 +10348,19 @@ CatalogSet &SchemaCatalogEntry::GetCatalogSet(CatalogType type) { } } -} // namespace duckdb - - - - - - - - -#include -#include - -namespace duckdb { - -SequenceCatalogEntry::SequenceCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateSequenceInfo *info) - : StandardEntry(CatalogType::SEQUENCE_ENTRY, schema, catalog, info->name), usage_count(info->usage_count), - counter(info->start_value), increment(info->increment), start_value(info->start_value), - min_value(info->min_value), max_value(info->max_value), cycle(info->cycle) { - this->temporary = info->temporary; -} - -void SequenceCatalogEntry::Serialize(Serializer &serializer) { - FieldWriter writer(serializer); - writer.WriteString(schema->name); - writer.WriteString(name); - writer.WriteField(usage_count); - writer.WriteField(increment); - writer.WriteField(min_value); - writer.WriteField(max_value); - writer.WriteField(counter); - writer.WriteField(cycle); - writer.Finalize(); -} - -unique_ptr SequenceCatalogEntry::Deserialize(Deserializer &source) { - auto info = make_unique(); +void DuckSchemaEntry::Verify(Catalog &catalog) { + CatalogEntry::Verify(catalog); - FieldReader reader(source); - info->schema = reader.ReadRequired(); - info->name = reader.ReadRequired(); - info->usage_count = reader.ReadRequired(); - info->increment = reader.ReadRequired(); - info->min_value = reader.ReadRequired(); - info->max_value = reader.ReadRequired(); - info->start_value = reader.ReadRequired(); - info->cycle = reader.ReadRequired(); - reader.Finalize(); - - return info; -} - -string SequenceCatalogEntry::ToSQL() { - std::stringstream ss; - ss << "CREATE SEQUENCE "; - ss << name; - ss << " INCREMENT BY " << increment; - ss << " MINVALUE " << min_value; - ss << " MAXVALUE " << max_value; - ss << " START " << counter; - ss << " " << (cycle ? "CYCLE" : "NO CYCLE") << ";"; - return ss.str(); + tables.Verify(catalog); + indexes.Verify(catalog); + table_functions.Verify(catalog); + copy_functions.Verify(catalog); + pragma_functions.Verify(catalog); + functions.Verify(catalog); + sequences.Verify(catalog); + collations.Verify(catalog); + types.Verify(catalog); } -} // namespace duckdb - - - - - - - - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/constraints/check_constraint.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - -namespace duckdb { - -//! The CheckConstraint contains an expression that must evaluate to TRUE for -//! every row in a table -class CheckConstraint : public Constraint { -public: - DUCKDB_API explicit CheckConstraint(unique_ptr expression); - - unique_ptr expression; - -public: - DUCKDB_API string ToString() const override; - - DUCKDB_API unique_ptr Copy() const override; - - DUCKDB_API void Serialize(FieldWriter &writer) const override; - DUCKDB_API static unique_ptr Deserialize(FieldReader &source); -}; - -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/constraints/not_null_constraint.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { - -class NotNullConstraint : public Constraint { -public: - DUCKDB_API explicit NotNullConstraint(LogicalIndex index); - DUCKDB_API ~NotNullConstraint() override; - - //! Column index this constraint pertains to - LogicalIndex index; - -public: - DUCKDB_API string ToString() const override; - - DUCKDB_API unique_ptr Copy() const override; - - //! Serialize to a stand-alone binary blob - DUCKDB_API void Serialize(FieldWriter &writer) const override; - //! Deserializes a NotNullConstraint - DUCKDB_API static unique_ptr Deserialize(FieldReader &source); -}; - -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/constraints/unique_constraint.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -namespace duckdb { - -class UniqueConstraint : public Constraint { -public: - DUCKDB_API UniqueConstraint(LogicalIndex index, bool is_primary_key); - DUCKDB_API UniqueConstraint(vector columns, bool is_primary_key); - - //! The index of the column for which this constraint holds. Only used when the constraint relates to a single - //! column, equal to DConstants::INVALID_INDEX if not used - LogicalIndex index; - //! The set of columns for which this constraint holds by name. Only used when the index field is not used. - vector columns; - //! Whether or not this is a PRIMARY KEY constraint, or a UNIQUE constraint. - bool is_primary_key; - -public: - DUCKDB_API string ToString() const override; - - DUCKDB_API unique_ptr Copy() const override; - - //! Serialize to a stand-alone binary blob - DUCKDB_API void Serialize(FieldWriter &writer) const override; - //! Deserializes a ParsedConstraint - DUCKDB_API static unique_ptr Deserialize(FieldReader &source); -}; - -} // namespace duckdb - - - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/parsed_expression_iterator.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -#include - -namespace duckdb { - -class ParsedExpressionIterator { -public: - static void EnumerateChildren(const ParsedExpression &expression, - const std::function &callback); - static void EnumerateChildren(ParsedExpression &expr, const std::function &callback); - static void EnumerateChildren(ParsedExpression &expr, - const std::function &child)> &callback); - - static void EnumerateTableRefChildren(TableRef &ref, - const std::function &child)> &callback); - static void EnumerateQueryNodeChildren(QueryNode &node, - const std::function &child)> &callback); - - static void EnumerateQueryNodeModifiers(QueryNode &node, - const std::function &child)> &callback); -}; } // namespace duckdb @@ -9841,7 +10442,7 @@ namespace duckdb { class BoundUniqueConstraint : public BoundConstraint { public: BoundUniqueConstraint(vector keys, logical_index_set_t key_set, bool is_primary_key) - : BoundConstraint(ConstraintType::UNIQUE), keys(move(keys)), key_set(move(key_set)), + : BoundConstraint(ConstraintType::UNIQUE), keys(std::move(keys)), key_set(std::move(key_set)), is_primary_key(is_primary_key) { #ifdef DEBUG D_ASSERT(keys.size() == key_set.size()); @@ -10065,6 +10666,7 @@ namespace duckdb { struct AlterInfo; +class AttachedDatabase; class BufferedSerializer; class Catalog; class DatabaseInstance; @@ -10079,13 +10681,14 @@ class TransactionManager; class ReplayState { public: - ReplayState(DatabaseInstance &db, ClientContext &context, Deserializer &source) - : db(db), context(context), source(source), current_table(nullptr), deserialize_only(false), - checkpoint_id(INVALID_BLOCK) { + ReplayState(AttachedDatabase &db, ClientContext &context, Deserializer &source) + : db(db), context(context), catalog(db.GetCatalog()), source(source), current_table(nullptr), + deserialize_only(false), checkpoint_id(INVALID_BLOCK) { } - DatabaseInstance &db; + AttachedDatabase &db; ClientContext &context; + Catalog &catalog; Deserializer &source; TableCatalogEntry *current_table; bool deserialize_only; @@ -10132,7 +10735,7 @@ class ReplayState { class WriteAheadLog { public: //! Initialize the WAL in the specified directory - explicit WriteAheadLog(DatabaseInstance &database, const string &path); + explicit WriteAheadLog(AttachedDatabase &database, const string &path); virtual ~WriteAheadLog(); //! Skip writing to the WAL @@ -10140,7 +10743,7 @@ class WriteAheadLog { public: //! Replay the WAL - static bool Replay(DatabaseInstance &database, string &path); + static bool Replay(AttachedDatabase &database, string &path); //! Returns the current size of the WAL in bytes int64_t GetWALSize(); @@ -10194,21 +10797,26 @@ class WriteAheadLog { void WriteCheckpoint(block_id_t meta_block); protected: - DatabaseInstance &database; + AttachedDatabase &database; unique_ptr writer; string wal_path; }; } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/storage/database_size.hpp +// +// +//===----------------------------------------------------------------------===// + + + + namespace duckdb { -class BlockManager; -class Catalog; -class CheckpointWriter; -class DatabaseInstance; -class TransactionManager; -class TableCatalogEntry; struct DatabaseSize { idx_t total_blocks = 0; @@ -10219,6 +10827,17 @@ struct DatabaseSize { idx_t wal_size = 0; }; +} // namespace duckdb + + +namespace duckdb { +class BlockManager; +class Catalog; +class CheckpointWriter; +class DatabaseInstance; +class TransactionManager; +class TableCatalogEntry; + class StorageCommitState { public: // Destruction of this object, without prior call to FlushCommit, @@ -10234,22 +10853,18 @@ class StorageCommitState { //! database on disk class StorageManager { public: - StorageManager(DatabaseInstance &db, string path, bool read_only); + StorageManager(AttachedDatabase &db, string path, bool read_only); virtual ~StorageManager(); - //! The BufferManager of the database - unique_ptr buffer_manager; - //! The database this storagemanager belongs to - DatabaseInstance &db; - public: - static StorageManager &GetStorageManager(ClientContext &context); - static StorageManager &GetStorageManager(DatabaseInstance &db); + static StorageManager &Get(AttachedDatabase &db); + static StorageManager &Get(Catalog &catalog); //! Initialize a database or load an existing database from the given path void Initialize(); - DatabaseInstance &GetDatabase() { + DatabaseInstance &GetDatabase(); + AttachedDatabase &GetAttached() { return db; } @@ -10272,13 +10887,14 @@ class StorageManager { protected: virtual void LoadDatabase() = 0; - virtual void CreateBufferManager(); +protected: + //! The database this storagemanager belongs to + AttachedDatabase &db; //! The path of the database string path; //! The WriteAheadLog of the storage manager unique_ptr wal; - //! Whether or not the database is opened in read-only mode bool read_only; }; @@ -10286,7 +10902,7 @@ class StorageManager { //! Stores database in a single file. class SingleFileStorageManager : public StorageManager { public: - SingleFileStorageManager(DatabaseInstance &db, string path, bool read_only); + SingleFileStorageManager(AttachedDatabase &db, string path, bool read_only); //! The BlockManager to read/store meta information and data in blocks unique_ptr block_manager; @@ -10308,24 +10924,255 @@ class SingleFileStorageManager : public StorageManager { -#include +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/parsed_expression_iterator.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +#include namespace duckdb { -bool TableCatalogEntry::HasGeneratedColumns() const { - return columns.LogicalColumnCount() != columns.PhysicalColumnCount(); -} +class ParsedExpressionIterator { +public: + static void EnumerateChildren(const ParsedExpression &expression, + const std::function &callback); + static void EnumerateChildren(ParsedExpression &expr, const std::function &callback); + static void EnumerateChildren(ParsedExpression &expr, + const std::function &child)> &callback); -LogicalIndex TableCatalogEntry::GetColumnIndex(string &column_name, bool if_exists) { - auto entry = columns.GetColumnIndex(column_name); - if (!entry.IsValid()) { - if (if_exists) { - return entry; - } - throw BinderException("Table \"%s\" does not have a column with name \"%s\"", name, column_name); + static void EnumerateTableRefChildren(TableRef &ref, + const std::function &child)> &callback); + static void EnumerateQueryNodeChildren(QueryNode &node, + const std::function &child)> &callback); + + static void EnumerateQueryNodeModifiers(QueryNode &node, + const std::function &child)> &callback); +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/constraints/check_constraint.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + +namespace duckdb { + +//! The CheckConstraint contains an expression that must evaluate to TRUE for +//! every row in a table +class CheckConstraint : public Constraint { +public: + DUCKDB_API explicit CheckConstraint(unique_ptr expression); + + unique_ptr expression; + +public: + DUCKDB_API string ToString() const override; + + DUCKDB_API unique_ptr Copy() const override; + + DUCKDB_API void Serialize(FieldWriter &writer) const override; + DUCKDB_API static unique_ptr Deserialize(FieldReader &source); +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/constraints/not_null_constraint.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +class NotNullConstraint : public Constraint { +public: + DUCKDB_API explicit NotNullConstraint(LogicalIndex index); + DUCKDB_API ~NotNullConstraint() override; + + //! Column index this constraint pertains to + LogicalIndex index; + +public: + DUCKDB_API string ToString() const override; + + DUCKDB_API unique_ptr Copy() const override; + + //! Serialize to a stand-alone binary blob + DUCKDB_API void Serialize(FieldWriter &writer) const override; + //! Deserializes a NotNullConstraint + DUCKDB_API static unique_ptr Deserialize(FieldReader &source); +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/constraints/unique_constraint.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +class UniqueConstraint : public Constraint { +public: + DUCKDB_API UniqueConstraint(LogicalIndex index, bool is_primary_key); + DUCKDB_API UniqueConstraint(vector columns, bool is_primary_key); + + //! The index of the column for which this constraint holds. Only used when the constraint relates to a single + //! column, equal to DConstants::INVALID_INDEX if not used + LogicalIndex index; + //! The set of columns for which this constraint holds by name. Only used when the index field is not used. + vector columns; + //! Whether or not this is a PRIMARY KEY constraint, or a UNIQUE constraint. + bool is_primary_key; + +public: + DUCKDB_API string ToString() const override; + + DUCKDB_API unique_ptr Copy() const override; + + //! Serialize to a stand-alone binary blob + DUCKDB_API void Serialize(FieldWriter &writer) const override; + //! Deserializes a ParsedConstraint + DUCKDB_API static unique_ptr Deserialize(FieldReader &source); +}; + +} // namespace duckdb + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/function/table/table_scan.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + +namespace duckdb { +class DuckTableEntry; +class TableCatalogEntry; + +struct TableScanBindData : public TableFunctionData { + explicit TableScanBindData(DuckTableEntry *table) : table(table), is_index_scan(false), is_create_index(false) { } - return entry; -} + + //! The table to scan + DuckTableEntry *table; + + //! Whether or not the table scan is an index scan + bool is_index_scan; + //! Whether or not the table scan is for index creation + bool is_create_index; + //! The row ids to fetch (in case of an index scan) + vector result_ids; + +public: + bool Equals(const FunctionData &other_p) const override { + auto &other = (const TableScanBindData &)other_p; + return other.table == table && result_ids == other.result_ids; + } +}; + +//! The table scan function represents a sequential scan over one of DuckDB's base tables. +struct TableScanFunction { + static void RegisterFunction(BuiltinFunctions &set); + static TableFunction GetFunction(); + static TableFunction GetIndexScanFunction(); + static TableCatalogEntry *GetTableEntry(const TableFunction &function, const FunctionData *bind_data); +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/storage/table_storage_info.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +struct ColumnSegmentInfo { + idx_t row_group_index; + idx_t column_id; + string column_path; + idx_t segment_idx; + string segment_type; + idx_t segment_start; + idx_t segment_count; + string compression_type; + string segment_stats; + bool has_updates; + bool persistent; + block_id_t block_id; + idx_t block_offset; +}; + +struct IndexInfo { + bool is_unique; + bool is_primary; + bool is_foreign; + unordered_set column_set; +}; + +class TableStorageInfo { +public: + //! The (estimated) cardinality of the table + idx_t cardinality = DConstants::INVALID_INDEX; + //! Info of the indexes of a table + vector index_info; + //! Info of the column segments of the table + vector column_segments; +}; + +} // namespace duckdb + + +namespace duckdb { void AddDataTableIndex(DataTable *storage, const ColumnList &columns, const vector &keys, IndexConstraintType constraint_type, BlockPointer *index_block = nullptr) { @@ -10347,16 +11194,16 @@ void AddDataTableIndex(DataTable *storage, const ColumnList &columns, const vect unique_ptr art; // create an adaptive radix tree around the expressions if (index_block) { - art = make_unique(column_ids, TableIOManager::Get(*storage), move(unbound_expressions), constraint_type, - storage->db, index_block->block_id, index_block->offset); + art = make_unique(column_ids, TableIOManager::Get(*storage), std::move(unbound_expressions), + constraint_type, storage->db, true, index_block->block_id, index_block->offset); } else { - art = make_unique(column_ids, TableIOManager::Get(*storage), move(unbound_expressions), constraint_type, - storage->db); + art = make_unique(column_ids, TableIOManager::Get(*storage), std::move(unbound_expressions), + constraint_type, storage->db, true); if (!storage->IsRoot()) { throw TransactionException("Transaction conflict: cannot add an index to a table that has been altered!"); } } - storage->info->indexes.AddIndex(move(art)); + storage->info->indexes.AddIndex(std::move(art)); } void AddDataTableIndex(DataTable *storage, const ColumnList &columns, vector &keys, @@ -10369,22 +11216,19 @@ void AddDataTableIndex(DataTable *storage, const ColumnList &columns, vector inherited_storage) - : StandardEntry(CatalogType::TABLE_ENTRY, schema, catalog, info->Base().table), storage(move(inherited_storage)), - columns(move(info->Base().columns)), constraints(move(info->Base().constraints)), - bound_constraints(move(info->bound_constraints)), - column_dependency_manager(move(info->column_dependency_manager)) { - this->temporary = info->Base().temporary; +DuckTableEntry::DuckTableEntry(Catalog *catalog, SchemaCatalogEntry *schema, BoundCreateTableInfo *info, + std::shared_ptr inherited_storage) + : TableCatalogEntry(catalog, schema, info->Base()), storage(std::move(inherited_storage)), + bound_constraints(std::move(info->bound_constraints)), + column_dependency_manager(std::move(info->column_dependency_manager)) { if (!storage) { // create the physical storage vector storage_columns; for (auto &col_def : columns.Physical()) { storage_columns.push_back(col_def.Copy()); } - storage = - make_shared(catalog->db, StorageManager::GetStorageManager(catalog->db).GetTableIOManager(info), - schema->name, name, move(storage_columns), move(info->data)); + storage = make_shared(catalog->GetAttached(), StorageManager::Get(*catalog).GetTableIOManager(info), + schema->name, name, std::move(storage_columns), std::move(info->data)); // create the unique indexes for the UNIQUE and PRIMARY KEY and FOREIGN KEY constraints idx_t indexes_idx = 0; @@ -10420,11 +11264,7 @@ TableCatalogEntry::TableCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schem } } -bool TableCatalogEntry::ColumnExists(const string &name) { - return columns.ColumnExists(name); -} - -unique_ptr TableCatalogEntry::GetStatistics(ClientContext &context, column_t column_id) { +unique_ptr DuckTableEntry::GetStatistics(ClientContext &context, column_t column_id) { if (column_id == COLUMN_IDENTIFIER_ROW_ID) { return nullptr; } @@ -10435,7 +11275,7 @@ unique_ptr TableCatalogEntry::GetStatistics(ClientContext &conte return storage->GetStatistics(context, column.StorageOid()); } -unique_ptr TableCatalogEntry::AlterEntry(ClientContext &context, AlterInfo *info) { +unique_ptr DuckTableEntry::AlterEntry(ClientContext &context, AlterInfo *info) { D_ASSERT(!internal); if (info->type != AlterType::ALTER_TABLE) { throw CatalogException("Can only modify table with ALTER TABLE statement"); @@ -10490,7 +11330,7 @@ unique_ptr TableCatalogEntry::AlterEntry(ClientContext &context, A } } -void TableCatalogEntry::UndoAlter(ClientContext &context, AlterInfo *info) { +void DuckTableEntry::UndoAlter(ClientContext &context, AlterInfo *info) { D_ASSERT(!internal); D_ASSERT(info->type == AlterType::ALTER_TABLE); auto table_info = (AlterTableInfo *)info; @@ -10515,12 +11355,12 @@ static void RenameExpression(ParsedExpression &expr, RenameColumnInfo &info) { expr, [&](const ParsedExpression &child) { RenameExpression((ParsedExpression &)child, info); }); } -unique_ptr TableCatalogEntry::RenameColumn(ClientContext &context, RenameColumnInfo &info) { +unique_ptr DuckTableEntry::RenameColumn(ClientContext &context, RenameColumnInfo &info) { auto rename_idx = GetColumnIndex(info.old_name); if (rename_idx.index == COLUMN_IDENTIFIER_ROW_ID) { throw CatalogException("Cannot rename rowid column"); } - auto create_info = make_unique(schema->name, name); + auto create_info = make_unique(schema, name); create_info->temporary = temporary; for (auto &col : columns.Logical()) { auto copy = col.Copy(); @@ -10530,7 +11370,7 @@ unique_ptr TableCatalogEntry::RenameColumn(ClientContext &context, if (col.Generated() && column_dependency_manager.IsDependencyOf(col.Logical(), rename_idx)) { RenameExpression(copy.GeneratedExpressionMutable(), info); } - create_info->columns.AddColumn(move(copy)); + create_info->columns.AddColumn(std::move(copy)); } for (idx_t c_idx = 0; c_idx < constraints.size(); c_idx++) { auto copy = constraints[c_idx]->Copy(); @@ -10577,14 +11417,14 @@ unique_ptr TableCatalogEntry::RenameColumn(ClientContext &context, default: throw InternalException("Unsupported constraint for entry!"); } - create_info->constraints.push_back(move(copy)); + create_info->constraints.push_back(std::move(copy)); } auto binder = Binder::CreateBinder(context); - auto bound_create_info = binder->BindCreateTableInfo(move(create_info)); - return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), storage); + auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info)); + return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), storage); } -unique_ptr TableCatalogEntry::AddColumn(ClientContext &context, AddColumnInfo &info) { +unique_ptr DuckTableEntry::AddColumn(ClientContext &context, AddColumnInfo &info) { auto col_name = info.new_column.GetName(); // We're checking for the opposite condition (ADD COLUMN IF _NOT_ EXISTS ...). @@ -10592,7 +11432,7 @@ unique_ptr TableCatalogEntry::AddColumn(ClientContext &context, Ad return nullptr; } - auto create_info = make_unique(schema->name, name); + auto create_info = make_unique(schema, name); create_info->temporary = temporary; for (auto &col : columns.Logical()) { @@ -10601,52 +11441,27 @@ unique_ptr TableCatalogEntry::AddColumn(ClientContext &context, Ad for (auto &constraint : constraints) { create_info->constraints.push_back(constraint->Copy()); } - Binder::BindLogicalType(context, info.new_column.TypeMutable(), schema->name); + Binder::BindLogicalType(context, info.new_column.TypeMutable(), catalog, schema->name); info.new_column.SetOid(columns.LogicalColumnCount()); info.new_column.SetStorageOid(columns.PhysicalColumnCount()); auto col = info.new_column.Copy(); - create_info->columns.AddColumn(move(col)); + create_info->columns.AddColumn(std::move(col)); auto binder = Binder::CreateBinder(context); - auto bound_create_info = binder->BindCreateTableInfo(move(create_info)); + auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info)); auto new_storage = make_shared(context, *storage, info.new_column, bound_create_info->bound_defaults.back().get()); - return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), - new_storage); + return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), new_storage); } -unique_ptr TableCatalogEntry::RemoveColumn(ClientContext &context, RemoveColumnInfo &info) { - auto removed_index = GetColumnIndex(info.removed_column, info.if_column_exists); - if (!removed_index.IsValid()) { - if (!info.if_column_exists) { - throw CatalogException("Cannot drop column: rowid column cannot be dropped"); - } - return nullptr; - } - - auto create_info = make_unique(schema->name, name); - create_info->temporary = temporary; - - logical_index_set_t removed_columns; - if (column_dependency_manager.HasDependents(removed_index)) { - removed_columns = column_dependency_manager.GetDependents(removed_index); - } - if (!removed_columns.empty() && !info.cascade) { - throw CatalogException("Cannot drop column: column is a dependency of 1 or more generated column(s)"); - } - for (auto &col : columns.Logical()) { - if (col.Logical() == removed_index || removed_columns.count(col.Logical())) { - continue; - } - create_info->columns.AddColumn(col.Copy()); - } - if (create_info->columns.empty()) { - throw CatalogException("Cannot drop column: table only has one column remaining!"); - } - auto adjusted_indices = column_dependency_manager.RemoveColumn(removed_index, columns.LogicalColumnCount()); +void DuckTableEntry::UpdateConstraintsOnColumnDrop(const LogicalIndex &removed_index, + const vector &adjusted_indices, + const RemoveColumnInfo &info, CreateTableInfo &create_info, + bool is_generated) { // handle constraints for the new table D_ASSERT(constraints.size() == bound_constraints.size()); + for (idx_t constr_idx = 0; constr_idx < constraints.size(); constr_idx++) { auto &constraint = constraints[constr_idx]; auto &bound_constraint = bound_constraints[constr_idx]; @@ -10658,14 +11473,20 @@ unique_ptr TableCatalogEntry::RemoveColumn(ClientContext &context, // the constraint is not about this column: we need to copy it // we might need to shift the index back by one though, to account for the removed column auto new_index = adjusted_indices[not_null_index.index]; - create_info->constraints.push_back(make_unique(new_index)); + create_info.constraints.push_back(make_unique(new_index)); } break; } case ConstraintType::CHECK: { + // Generated columns can not be part of an index // CHECK constraint auto &bound_check = (BoundCheckConstraint &)*bound_constraint; // check if the removed column is part of the check constraint + if (is_generated) { + // generated columns can not be referenced by constraints, we can just add the constraint back + create_info.constraints.push_back(constraint->Copy()); + break; + } auto physical_index = columns.LogicalToPhysical(removed_index); if (bound_check.bound_columns.find(physical_index) != bound_check.bound_columns.end()) { if (bound_check.bound_columns.size() > 1) { @@ -10678,7 +11499,7 @@ unique_ptr TableCatalogEntry::RemoveColumn(ClientContext &context, } } else { // check constraint does not concern the removed column: simply re-add it - create_info->constraints.push_back(constraint->Copy()); + create_info.constraints.push_back(constraint->Copy()); } break; } @@ -10693,7 +11514,7 @@ unique_ptr TableCatalogEntry::RemoveColumn(ClientContext &context, } unique.index = adjusted_indices[unique.index.index]; } - create_info->constraints.push_back(move(copy)); + create_info.constraints.push_back(std::move(copy)); break; } case ConstraintType::FOREIGN_KEY: { @@ -10714,28 +11535,63 @@ unique_ptr TableCatalogEntry::RemoveColumn(ClientContext &context, info.removed_column); } } - create_info->constraints.push_back(move(copy)); + create_info.constraints.push_back(std::move(copy)); break; } default: throw InternalException("Unsupported constraint for entry!"); } } +} + +unique_ptr DuckTableEntry::RemoveColumn(ClientContext &context, RemoveColumnInfo &info) { + auto removed_index = GetColumnIndex(info.removed_column, info.if_column_exists); + if (!removed_index.IsValid()) { + if (!info.if_column_exists) { + throw CatalogException("Cannot drop column: rowid column cannot be dropped"); + } + return nullptr; + } + + auto create_info = make_unique(schema, name); + create_info->temporary = temporary; + + logical_index_set_t removed_columns; + if (column_dependency_manager.HasDependents(removed_index)) { + removed_columns = column_dependency_manager.GetDependents(removed_index); + } + if (!removed_columns.empty() && !info.cascade) { + throw CatalogException("Cannot drop column: column is a dependency of 1 or more generated column(s)"); + } + bool dropped_column_is_generated = false; + for (auto &col : columns.Logical()) { + if (col.Logical() == removed_index || removed_columns.count(col.Logical())) { + if (col.Generated()) { + dropped_column_is_generated = true; + } + continue; + } + create_info->columns.AddColumn(col.Copy()); + } + if (create_info->columns.empty()) { + throw CatalogException("Cannot drop column: table only has one column remaining!"); + } + auto adjusted_indices = column_dependency_manager.RemoveColumn(removed_index, columns.LogicalColumnCount()); + + UpdateConstraintsOnColumnDrop(removed_index, adjusted_indices, info, *create_info, dropped_column_is_generated); auto binder = Binder::CreateBinder(context); - auto bound_create_info = binder->BindCreateTableInfo(move(create_info)); + auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info)); if (columns.GetColumn(LogicalIndex(removed_index)).Generated()) { - return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), - storage); + return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), storage); } auto new_storage = make_shared(context, *storage, columns.LogicalToPhysical(LogicalIndex(removed_index)).index); - return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), - new_storage); + return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), new_storage); } -unique_ptr TableCatalogEntry::SetDefault(ClientContext &context, SetDefaultInfo &info) { - auto create_info = make_unique(schema->name, name); +unique_ptr DuckTableEntry::SetDefault(ClientContext &context, SetDefaultInfo &info) { + auto create_info = make_unique(schema, name); auto default_idx = GetColumnIndex(info.column_name); if (default_idx.index == COLUMN_IDENTIFIER_ROW_ID) { throw CatalogException("Cannot SET DEFAULT for rowid column"); @@ -10751,22 +11607,22 @@ unique_ptr TableCatalogEntry::SetDefault(ClientContext &context, S } copy.SetDefaultValue(info.expression ? info.expression->Copy() : nullptr); } - create_info->columns.AddColumn(move(copy)); + create_info->columns.AddColumn(std::move(copy)); } // Copy all the constraints for (idx_t i = 0; i < constraints.size(); i++) { auto constraint = constraints[i]->Copy(); - create_info->constraints.push_back(move(constraint)); + create_info->constraints.push_back(std::move(constraint)); } auto binder = Binder::CreateBinder(context); - auto bound_create_info = binder->BindCreateTableInfo(move(create_info)); - return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), storage); + auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info)); + return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), storage); } -unique_ptr TableCatalogEntry::SetNotNull(ClientContext &context, SetNotNullInfo &info) { +unique_ptr DuckTableEntry::SetNotNull(ClientContext &context, SetNotNullInfo &info) { - auto create_info = make_unique(schema->name, name); + auto create_info = make_unique(schema, name); create_info->columns = columns.Copy(); auto not_null_idx = GetColumnIndex(info.column_name); @@ -10782,29 +11638,27 @@ unique_ptr TableCatalogEntry::SetNotNull(ClientContext &context, S has_not_null = true; } } - create_info->constraints.push_back(move(constraint)); + create_info->constraints.push_back(std::move(constraint)); } if (!has_not_null) { create_info->constraints.push_back(make_unique(not_null_idx)); } auto binder = Binder::CreateBinder(context); - auto bound_create_info = binder->BindCreateTableInfo(move(create_info)); + auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info)); // Early return if (has_not_null) { - return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), - storage); + return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), storage); } // Return with new storage info. Note that we need the bound column index here. auto new_storage = make_shared( context, *storage, make_unique(columns.LogicalToPhysical(LogicalIndex(not_null_idx)))); - return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), - new_storage); + return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), new_storage); } -unique_ptr TableCatalogEntry::DropNotNull(ClientContext &context, DropNotNullInfo &info) { - auto create_info = make_unique(schema->name, name); +unique_ptr DuckTableEntry::DropNotNull(ClientContext &context, DropNotNullInfo &info) { + auto create_info = make_unique(schema, name); create_info->columns = columns.Copy(); auto not_null_idx = GetColumnIndex(info.column_name); @@ -10817,21 +11671,21 @@ unique_ptr TableCatalogEntry::DropNotNull(ClientContext &context, continue; } } - create_info->constraints.push_back(move(constraint)); + create_info->constraints.push_back(std::move(constraint)); } auto binder = Binder::CreateBinder(context); - auto bound_create_info = binder->BindCreateTableInfo(move(create_info)); - return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), storage); + auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info)); + return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), storage); } -unique_ptr TableCatalogEntry::ChangeColumnType(ClientContext &context, ChangeColumnTypeInfo &info) { +unique_ptr DuckTableEntry::ChangeColumnType(ClientContext &context, ChangeColumnTypeInfo &info) { if (info.target_type.id() == LogicalTypeId::USER) { - auto &catalog = Catalog::GetCatalog(context); - info.target_type = catalog.GetType(context, schema->name, UserType::GetTypeName(info.target_type)); + info.target_type = + Catalog::GetType(context, catalog->GetName(), schema->name, UserType::GetTypeName(info.target_type)); } auto change_idx = GetColumnIndex(info.column_name); - auto create_info = make_unique(schema->name, name); + auto create_info = make_unique(schema, name); create_info->temporary = temporary; for (auto &col : columns.Logical()) { @@ -10849,7 +11703,7 @@ unique_ptr TableCatalogEntry::ChangeColumnType(ClientContext &cont "This column is referenced by the generated column \"%s\", so its type can not be changed", copy.Name()); } - create_info->columns.AddColumn(move(copy)); + create_info->columns.AddColumn(std::move(copy)); } for (idx_t i = 0; i < constraints.size(); i++) { @@ -10891,7 +11745,7 @@ unique_ptr TableCatalogEntry::ChangeColumnType(ClientContext &cont default: throw InternalException("Unsupported constraint for entry!"); } - create_info->constraints.push_back(move(constraint)); + create_info->constraints.push_back(std::move(constraint)); } auto binder = Binder::CreateBinder(context); @@ -10900,7 +11754,7 @@ unique_ptr TableCatalogEntry::ChangeColumnType(ClientContext &cont AlterBinder expr_binder(*binder, context, *this, bound_columns, info.target_type); auto expression = info.expression->Copy(); auto bound_expression = expr_binder.Bind(expression); - auto bound_create_info = binder->BindCreateTableInfo(move(create_info)); + auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info)); vector storage_oids; for (idx_t i = 0; i < bound_columns.size(); i++) { storage_oids.push_back(columns.LogicalToPhysical(bound_columns[i]).index); @@ -10911,15 +11765,15 @@ unique_ptr TableCatalogEntry::ChangeColumnType(ClientContext &cont auto new_storage = make_shared(context, *storage, columns.LogicalToPhysical(LogicalIndex(change_idx)).index, - info.target_type, move(storage_oids), *bound_expression); + info.target_type, std::move(storage_oids), *bound_expression); auto result = - make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), new_storage); - return move(result); + make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), new_storage); + return std::move(result); } -unique_ptr TableCatalogEntry::AddForeignKeyConstraint(ClientContext &context, AlterForeignKeyInfo &info) { +unique_ptr DuckTableEntry::AddForeignKeyConstraint(ClientContext &context, AlterForeignKeyInfo &info) { D_ASSERT(info.type == AlterForeignKeyType::AFT_ADD); - auto create_info = make_unique(schema->name, name); + auto create_info = make_unique(schema, name); create_info->temporary = temporary; create_info->columns = columns.Copy(); @@ -10933,18 +11787,17 @@ unique_ptr TableCatalogEntry::AddForeignKeyConstraint(ClientContex fk_info.pk_keys = info.pk_keys; fk_info.fk_keys = info.fk_keys; create_info->constraints.push_back( - make_unique(info.pk_columns, info.fk_columns, move(fk_info))); + make_unique(info.pk_columns, info.fk_columns, std::move(fk_info))); auto binder = Binder::CreateBinder(context); - auto bound_create_info = binder->BindCreateTableInfo(move(create_info)); + auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info)); - return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), storage); + return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), storage); } -unique_ptr TableCatalogEntry::DropForeignKeyConstraint(ClientContext &context, - AlterForeignKeyInfo &info) { +unique_ptr DuckTableEntry::DropForeignKeyConstraint(ClientContext &context, AlterForeignKeyInfo &info) { D_ASSERT(info.type == AlterForeignKeyType::AFT_DELETE); - auto create_info = make_unique(schema->name, name); + auto create_info = make_unique(schema, name); create_info->temporary = temporary; create_info->columns = columns.Copy(); @@ -10956,17 +11809,712 @@ unique_ptr TableCatalogEntry::DropForeignKeyConstraint(ClientConte continue; } } - create_info->constraints.push_back(move(constraint)); + create_info->constraints.push_back(std::move(constraint)); } auto binder = Binder::CreateBinder(context); - auto bound_create_info = binder->BindCreateTableInfo(move(create_info)); + auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info)); - return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), storage); + return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), storage); } -ColumnDefinition &TableCatalogEntry::GetColumn(const string &name) { - return columns.GetColumnMutable(name); +unique_ptr DuckTableEntry::Copy(ClientContext &context) { + auto create_info = make_unique(schema, name); + create_info->columns = columns.Copy(); + + for (idx_t i = 0; i < constraints.size(); i++) { + auto constraint = constraints[i]->Copy(); + create_info->constraints.push_back(std::move(constraint)); + } + + auto binder = Binder::CreateBinder(context); + auto bound_create_info = binder->BindCreateTableInfo(std::move(create_info)); + return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), storage); +} + +void DuckTableEntry::SetAsRoot() { + storage->SetAsRoot(); + storage->info->table = name; +} + +void DuckTableEntry::CommitAlter(AlterInfo &info) { + D_ASSERT(info.type == AlterType::ALTER_TABLE); + auto &alter_table = (AlterTableInfo &)info; + string column_name; + switch (alter_table.alter_table_type) { + case AlterTableType::REMOVE_COLUMN: { + auto &remove_info = (RemoveColumnInfo &)alter_table; + column_name = remove_info.removed_column; + break; + } + case AlterTableType::ALTER_COLUMN_TYPE: { + auto &change_info = (ChangeColumnTypeInfo &)alter_table; + column_name = change_info.column_name; + break; + } + default: + break; + } + if (column_name.empty()) { + return; + } + idx_t removed_index = DConstants::INVALID_INDEX; + for (auto &col : columns.Logical()) { + if (col.Name() == column_name) { + // No need to alter storage, removed column is generated column + if (col.Generated()) { + return; + } + removed_index = col.Oid(); + break; + } + } + D_ASSERT(removed_index != DConstants::INVALID_INDEX); + storage->CommitDropColumn(columns.LogicalToPhysical(LogicalIndex(removed_index)).index); +} + +void DuckTableEntry::CommitDrop() { + storage->CommitDropTable(); +} + +DataTable &DuckTableEntry::GetStorage() { + return *storage; +} + +DataTable *DuckTableEntry::GetStoragePtr() { + return storage.get(); +} + +const vector> &DuckTableEntry::GetBoundConstraints() { + return bound_constraints; +} + +TableFunction DuckTableEntry::GetScanFunction(ClientContext &context, unique_ptr &bind_data) { + bind_data = make_unique(this); + return TableScanFunction::GetFunction(); +} + +TableStorageInfo DuckTableEntry::GetStorageInfo(ClientContext &context) { + TableStorageInfo result; + result.cardinality = storage->info->cardinality.load(); + storage->GetStorageInfo(result); + storage->info->indexes.Scan([&](Index &index) { + IndexInfo info; + info.is_primary = index.IsPrimary(); + info.is_unique = index.IsUnique(); + info.is_foreign = index.IsForeign(); + index.column_id_set = index.column_id_set; + result.index_info.push_back(std::move(info)); + return false; + }); + return result; +} + +} // namespace duckdb + + + + +namespace duckdb { + +IndexCatalogEntry::IndexCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateIndexInfo *info) + : StandardEntry(CatalogType::INDEX_ENTRY, schema, catalog, info->index_name), index(nullptr), sql(info->sql) { + this->temporary = info->temporary; +} + +string IndexCatalogEntry::ToSQL() { + if (sql.empty()) { + return sql; + } + if (sql[sql.size() - 1] != ';') { + sql += ";"; + } + return sql; +} + +void IndexCatalogEntry::Serialize(duckdb::MetaBlockWriter &serializer) { + // Here we serialize the index metadata in the following order: + // schema name, table name, index name, sql, index type, index constraint type, expression list. + // column_ids, unbound_expression + FieldWriter writer(serializer); + writer.WriteString(GetSchemaName()); + writer.WriteString(GetTableName()); + writer.WriteString(name); + writer.WriteString(sql); + writer.WriteField(index->type); + writer.WriteField(index->constraint_type); + writer.WriteSerializableList(expressions); + writer.WriteSerializableList(parsed_expressions); + writer.WriteList(index->column_ids); + writer.Finalize(); +} + +unique_ptr IndexCatalogEntry::Deserialize(Deserializer &source, ClientContext &context) { + // Here we deserialize the index metadata in the following order: + // root block, root offset, schema name, table name, index name, sql, index type, index constraint type, expression + // list. + + auto create_index_info = make_unique(); + + FieldReader reader(source); + + create_index_info->schema = reader.ReadRequired(); + create_index_info->table = make_unique(); + create_index_info->table->schema_name = create_index_info->schema; + create_index_info->table->table_name = reader.ReadRequired(); + create_index_info->index_name = reader.ReadRequired(); + create_index_info->sql = reader.ReadRequired(); + create_index_info->index_type = IndexType(reader.ReadRequired()); + create_index_info->constraint_type = IndexConstraintType(reader.ReadRequired()); + create_index_info->expressions = reader.ReadRequiredSerializableList(); + create_index_info->parsed_expressions = reader.ReadRequiredSerializableList(); + + create_index_info->column_ids = reader.ReadRequiredList(); + reader.Finalize(); + return create_index_info; +} + +} // namespace duckdb + + + +namespace duckdb { + +PragmaFunctionCatalogEntry::PragmaFunctionCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, + CreatePragmaFunctionInfo *info) + : StandardEntry(CatalogType::PRAGMA_FUNCTION_ENTRY, schema, catalog, info->name), + functions(std::move(info->functions)) { +} + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/parsed_data/alter_function_info.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + +namespace duckdb { + +//===--------------------------------------------------------------------===// +// Alter Table +//===--------------------------------------------------------------------===// +enum class AlterFunctionType : uint8_t { INVALID = 0, ADD_FUNCTION_OVERLOADS = 1 }; + +struct AlterFunctionInfo : public AlterInfo { + AlterFunctionInfo(AlterFunctionType type, AlterEntryData data); + virtual ~AlterFunctionInfo() override; + + AlterFunctionType alter_function_type; + +public: + CatalogType GetCatalogType() const override; + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(FieldReader &reader); +}; + +//===--------------------------------------------------------------------===// +// AddFunctionOverloadInfo +//===--------------------------------------------------------------------===// +struct AddFunctionOverloadInfo : public AlterFunctionInfo { + AddFunctionOverloadInfo(AlterEntryData data, ScalarFunctionSet new_overloads); + ~AddFunctionOverloadInfo() override; + + ScalarFunctionSet new_overloads; + +public: + unique_ptr Copy() const override; +}; + +} // namespace duckdb + + +namespace duckdb { + +ScalarFunctionCatalogEntry::ScalarFunctionCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, + CreateScalarFunctionInfo *info) + : StandardEntry(CatalogType::SCALAR_FUNCTION_ENTRY, schema, catalog, info->name), functions(info->functions) { +} + +unique_ptr ScalarFunctionCatalogEntry::AlterEntry(ClientContext &context, AlterInfo *info) { + if (info->type != AlterType::ALTER_FUNCTION) { + throw InternalException("Attempting to alter ScalarFunctionCatalogEntry with unsupported alter type"); + } + auto &function_info = (AlterFunctionInfo &)*info; + if (function_info.alter_function_type != AlterFunctionType::ADD_FUNCTION_OVERLOADS) { + throw InternalException("Attempting to alter ScalarFunctionCatalogEntry with unsupported alter function type"); + } + auto &add_overloads = (AddFunctionOverloadInfo &)function_info; + + ScalarFunctionSet new_set = functions; + if (!new_set.MergeFunctionSet(add_overloads.new_overloads)) { + throw BinderException("Failed to add new function overloads to function \"%s\": function already exists", name); + } + CreateScalarFunctionInfo new_info(std::move(new_set)); + return make_unique(catalog, schema, &new_info); +} + +} // namespace duckdb + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/function/scalar_macro_function.hpp +// +// +//===----------------------------------------------------------------------===// + + +//! The SelectStatement of the view + + + + + + + + +namespace duckdb { + +class ScalarMacroFunction : public MacroFunction { +public: + ScalarMacroFunction(unique_ptr expression); + + ScalarMacroFunction(void); + //! The macro expression + unique_ptr expression; + +public: + unique_ptr Copy() override; + + string ToSQL(const string &schema, const string &name) override; +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/function/table_macro_function.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + + + + + +namespace duckdb { + +class TableMacroFunction : public MacroFunction { +public: + TableMacroFunction(unique_ptr query_node); + TableMacroFunction(void); + + //! The main query node + unique_ptr query_node; + +public: + unique_ptr Copy() override; + + string ToSQL(const string &schema, const string &name) override; +}; + +} // namespace duckdb + + +namespace duckdb { + +MacroCatalogEntry::MacroCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateMacroInfo *info) + : StandardEntry( + (info->function->type == MacroType::SCALAR_MACRO ? CatalogType::MACRO_ENTRY : CatalogType::TABLE_MACRO_ENTRY), + schema, catalog, info->name), + function(std::move(info->function)) { + this->temporary = info->temporary; + this->internal = info->internal; +} + +ScalarMacroCatalogEntry::ScalarMacroCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateMacroInfo *info) + : MacroCatalogEntry(catalog, schema, info) { +} + +void ScalarMacroCatalogEntry::Serialize(Serializer &main_serializer) { + D_ASSERT(!internal); + auto &scalar_function = (ScalarMacroFunction &)*function; + FieldWriter writer(main_serializer); + writer.WriteString(schema->name); + writer.WriteString(name); + writer.WriteSerializable(*scalar_function.expression); + // writer.WriteSerializableList(function->parameters); + writer.WriteSerializableList(function->parameters); + writer.WriteField((uint32_t)function->default_parameters.size()); + auto &serializer = writer.GetSerializer(); + for (auto &kv : function->default_parameters) { + serializer.WriteString(kv.first); + kv.second->Serialize(serializer); + } + writer.Finalize(); +} + +unique_ptr ScalarMacroCatalogEntry::Deserialize(Deserializer &main_source, ClientContext &context) { + auto info = make_unique(CatalogType::MACRO_ENTRY); + FieldReader reader(main_source); + info->schema = reader.ReadRequired(); + info->name = reader.ReadRequired(); + auto expression = reader.ReadRequiredSerializable(); + auto func = make_unique(std::move(expression)); + info->function = std::move(func); + info->function->parameters = reader.ReadRequiredSerializableList(); + auto default_param_count = reader.ReadRequired(); + auto &source = reader.GetSource(); + for (idx_t i = 0; i < default_param_count; i++) { + auto name = source.Read(); + info->function->default_parameters[name] = ParsedExpression::Deserialize(source); + } + // dont like this + // info->type=CatalogType::MACRO_ENTRY; + reader.Finalize(); + return info; +} + +TableMacroCatalogEntry::TableMacroCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateMacroInfo *info) + : MacroCatalogEntry(catalog, schema, info) { +} + +void TableMacroCatalogEntry::Serialize(Serializer &main_serializer) { + D_ASSERT(!internal); + FieldWriter writer(main_serializer); + + auto &table_function = (TableMacroFunction &)*function; + writer.WriteString(schema->name); + writer.WriteString(name); + writer.WriteSerializable(*table_function.query_node); + writer.WriteSerializableList(function->parameters); + writer.WriteField((uint32_t)function->default_parameters.size()); + auto &serializer = writer.GetSerializer(); + for (auto &kv : function->default_parameters) { + serializer.WriteString(kv.first); + kv.second->Serialize(serializer); + } + writer.Finalize(); +} + +unique_ptr TableMacroCatalogEntry::Deserialize(Deserializer &main_source, ClientContext &context) { + auto info = make_unique(CatalogType::TABLE_MACRO_ENTRY); + FieldReader reader(main_source); + info->schema = reader.ReadRequired(); + info->name = reader.ReadRequired(); + auto query_node = reader.ReadRequiredSerializable(); + auto table_function = make_unique(std::move(query_node)); + info->function = std::move(table_function); + info->function->parameters = reader.ReadRequiredSerializableList(); + auto default_param_count = reader.ReadRequired(); + auto &source = reader.GetSource(); + for (idx_t i = 0; i < default_param_count; i++) { + auto name = source.Read(); + info->function->default_parameters[name] = ParsedExpression::Deserialize(source); + } + + reader.Finalize(); + + return info; +} + +} // namespace duckdb + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/algorithm.hpp +// +// +//===----------------------------------------------------------------------===// + + + +#include + + + + + + +#include + +namespace duckdb { + +SchemaCatalogEntry::SchemaCatalogEntry(Catalog *catalog, string name_p, bool internal) + : CatalogEntry(CatalogType::SCHEMA_ENTRY, catalog, std::move(name_p)) { + this->internal = internal; +} + +CatalogTransaction SchemaCatalogEntry::GetCatalogTransaction(ClientContext &context) { + return CatalogTransaction(*catalog, context); +} + +SimilarCatalogEntry SchemaCatalogEntry::GetSimilarEntry(CatalogTransaction transaction, CatalogType type, + const string &name) { + SimilarCatalogEntry result; + Scan(transaction.GetContext(), type, [&](CatalogEntry *entry) { + auto ldist = StringUtil::LevenshteinDistance(entry->name, name); + if (ldist < result.distance) { + result.distance = ldist; + result.name = entry->name; + } + }); + return result; +} + +void SchemaCatalogEntry::Serialize(Serializer &serializer) { + FieldWriter writer(serializer); + writer.WriteString(name); + writer.Finalize(); +} + +unique_ptr SchemaCatalogEntry::Deserialize(Deserializer &source) { + auto info = make_unique(); + + FieldReader reader(source); + info->schema = reader.ReadRequired(); + reader.Finalize(); + + return info; +} + +string SchemaCatalogEntry::ToSQL() { + std::stringstream ss; + ss << "CREATE SCHEMA " << name << ";"; + return ss.str(); +} + +} // namespace duckdb + + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/catalog/dependency_manager.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/catalog/dependency.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { +class CatalogEntry; + +enum class DependencyType { + DEPENDENCY_REGULAR = 0, + DEPENDENCY_AUTOMATIC = 1, + DEPENDENCY_OWNS = 2, + DEPENDENCY_OWNED_BY = 3 +}; + +struct Dependency { + Dependency(CatalogEntry *entry, DependencyType dependency_type = DependencyType::DEPENDENCY_REGULAR) + : // NOLINT: Allow implicit conversion from `CatalogEntry` + entry(entry), dependency_type(dependency_type) { + } + + //! The catalog entry this depends on + CatalogEntry *entry; + //! The type of dependency + DependencyType dependency_type; +}; + +struct DependencyHashFunction { + uint64_t operator()(const Dependency &a) const { + std::hash hash_func; + return hash_func((void *)a.entry); + } +}; + +struct DependencyEquality { + bool operator()(const Dependency &a, const Dependency &b) const { + return a.entry == b.entry; + } +}; + +using dependency_set_t = unordered_set; + +} // namespace duckdb + + + +#include + +namespace duckdb { +class DuckCatalog; +class ClientContext; +class DependencyList; + +//! The DependencyManager is in charge of managing dependencies between catalog entries +class DependencyManager { + friend class CatalogSet; + +public: + explicit DependencyManager(DuckCatalog &catalog); + + //! Erase the object from the DependencyManager; this should only happen when the object itself is destroyed + void EraseObject(CatalogEntry *object); + + //! Scans all dependencies, returning pairs of (object, dependent) + void Scan(const std::function &callback); + + void AddOwnership(CatalogTransaction transaction, CatalogEntry *owner, CatalogEntry *entry); + +private: + DuckCatalog &catalog; + //! Map of objects that DEPEND on [object], i.e. [object] can only be deleted when all entries in the dependency map + //! are deleted. + unordered_map dependents_map; + //! Map of objects that the source object DEPENDS on, i.e. when any of the entries in the vector perform a CASCADE + //! drop then [object] is deleted as well + unordered_map> dependencies_map; + +private: + void AddObject(CatalogTransaction transaction, CatalogEntry *object, DependencyList &dependencies); + void DropObject(CatalogTransaction transaction, CatalogEntry *object, bool cascade); + void AlterObject(CatalogTransaction transaction, CatalogEntry *old_obj, CatalogEntry *new_obj); + void EraseObjectInternal(CatalogEntry *object); +}; +} // namespace duckdb + + +#include +#include + +namespace duckdb { + +SequenceCatalogEntry::SequenceCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateSequenceInfo *info) + : StandardEntry(CatalogType::SEQUENCE_ENTRY, schema, catalog, info->name), usage_count(info->usage_count), + counter(info->start_value), increment(info->increment), start_value(info->start_value), + min_value(info->min_value), max_value(info->max_value), cycle(info->cycle) { + this->temporary = info->temporary; +} + +void SequenceCatalogEntry::Serialize(Serializer &serializer) { + FieldWriter writer(serializer); + writer.WriteString(schema->name); + writer.WriteString(name); + writer.WriteField(usage_count); + writer.WriteField(increment); + writer.WriteField(min_value); + writer.WriteField(max_value); + writer.WriteField(counter); + writer.WriteField(cycle); + writer.Finalize(); +} + +unique_ptr SequenceCatalogEntry::Deserialize(Deserializer &source) { + auto info = make_unique(); + + FieldReader reader(source); + info->schema = reader.ReadRequired(); + info->name = reader.ReadRequired(); + info->usage_count = reader.ReadRequired(); + info->increment = reader.ReadRequired(); + info->min_value = reader.ReadRequired(); + info->max_value = reader.ReadRequired(); + info->start_value = reader.ReadRequired(); + info->cycle = reader.ReadRequired(); + reader.Finalize(); + + return info; +} + +string SequenceCatalogEntry::ToSQL() { + std::stringstream ss; + ss << "CREATE SEQUENCE "; + ss << name; + ss << " INCREMENT BY " << increment; + ss << " MINVALUE " << min_value; + ss << " MAXVALUE " << max_value; + ss << " START " << counter; + ss << " " << (cycle ? "CYCLE" : "NO CYCLE") << ";"; + return ss.str(); +} +} // namespace duckdb + + + + + + + + + + + + +#include + +namespace duckdb { + +TableCatalogEntry::TableCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateTableInfo &info) + : StandardEntry(CatalogType::TABLE_ENTRY, schema, catalog, info.table), columns(std::move(info.columns)), + constraints(std::move(info.constraints)) { + this->temporary = info.temporary; +} + +bool TableCatalogEntry::HasGeneratedColumns() const { + return columns.LogicalColumnCount() != columns.PhysicalColumnCount(); +} + +LogicalIndex TableCatalogEntry::GetColumnIndex(string &column_name, bool if_exists) { + auto entry = columns.GetColumnIndex(column_name); + if (!entry.IsValid()) { + if (if_exists) { + return entry; + } + throw BinderException("Table \"%s\" does not have a column with name \"%s\"", name, column_name); + } + return entry; +} + +bool TableCatalogEntry::ColumnExists(const string &name) { + return columns.ColumnExists(name); +} + +const ColumnDefinition &TableCatalogEntry::GetColumn(const string &name) { + return columns.GetColumn(name); } vector TableCatalogEntry::GetTypes() { @@ -11001,16 +12549,10 @@ unique_ptr TableCatalogEntry::Deserialize(Deserializer &source, return info; } -string TableCatalogEntry::ToSQL() { +string TableCatalogEntry::ColumnsToSQL(const ColumnList &columns, const vector> &constraints) { std::stringstream ss; - ss << "CREATE TABLE "; - - if (schema->name != DEFAULT_SCHEMA) { - ss << KeywordHelper::WriteOptionallyQuoted(schema->name) << "."; - } - - ss << KeywordHelper::WriteOptionallyQuoted(name) << "("; + ss << "("; // find all columns that have NOT NULL specified, but are NOT primary key columns logical_index_set_t not_null_columns; @@ -11088,69 +12630,53 @@ string TableCatalogEntry::ToSQL() { ss << extra_constraint; } - ss << ");"; + ss << ")"; return ss.str(); } -unique_ptr TableCatalogEntry::Copy(ClientContext &context) { - auto create_info = make_unique(schema->name, name); - create_info->columns = columns.Copy(); +string TableCatalogEntry::ToSQL() { + std::stringstream ss; - for (idx_t i = 0; i < constraints.size(); i++) { - auto constraint = constraints[i]->Copy(); - create_info->constraints.push_back(move(constraint)); + ss << "CREATE TABLE "; + + if (schema->name != DEFAULT_SCHEMA) { + ss << KeywordHelper::WriteOptionallyQuoted(schema->name) << "."; } - auto binder = Binder::CreateBinder(context); - auto bound_create_info = binder->BindCreateTableInfo(move(create_info)); - return make_unique(catalog, schema, (BoundCreateTableInfo *)bound_create_info.get(), storage); + ss << KeywordHelper::WriteOptionallyQuoted(name); + ss << ColumnsToSQL(columns, constraints); + ss << ";"; + + return ss.str(); } -void TableCatalogEntry::SetAsRoot() { - storage->SetAsRoot(); - storage->info->table = name; +const ColumnList &TableCatalogEntry::GetColumns() const { + return columns; } -void TableCatalogEntry::CommitAlter(AlterInfo &info) { - D_ASSERT(info.type == AlterType::ALTER_TABLE); - auto &alter_table = (AlterTableInfo &)info; - string column_name; - switch (alter_table.alter_table_type) { - case AlterTableType::REMOVE_COLUMN: { - auto &remove_info = (RemoveColumnInfo &)alter_table; - column_name = remove_info.removed_column; - break; - } - case AlterTableType::ALTER_COLUMN_TYPE: { - auto &change_info = (ChangeColumnTypeInfo &)alter_table; - column_name = change_info.column_name; - break; - } - default: - break; - } - if (column_name.empty()) { - return; - } - idx_t removed_index = DConstants::INVALID_INDEX; - for (auto &col : columns.Logical()) { - if (col.Name() == column_name) { - // No need to alter storage, removed column is generated column - if (col.Generated()) { - return; - } - removed_index = col.Oid(); - break; - } - } - D_ASSERT(removed_index != DConstants::INVALID_INDEX); - storage->CommitDropColumn(columns.LogicalToPhysical(LogicalIndex(removed_index)).index); +ColumnList &TableCatalogEntry::GetColumnsMutable() { + return columns; } -void TableCatalogEntry::CommitDrop() { - storage->CommitDropTable(); +const ColumnDefinition &TableCatalogEntry::GetColumn(LogicalIndex idx) { + return columns.GetColumn(idx); +} + +const vector> &TableCatalogEntry::GetConstraints() { + return constraints; +} + +DataTable &TableCatalogEntry::GetStorage() { + throw InternalException("Calling GetStorage on a TableCatalogEntry that is not a DTableCatalogEntry"); +} + +DataTable *TableCatalogEntry::GetStoragePtr() { + throw InternalException("Calling GetStoragePtr on a TableCatalogEntry that is not a DTableCatalogEntry"); } +const vector> &TableCatalogEntry::GetBoundConstraints() { + throw InternalException("Calling GetBoundConstraints on a TableCatalogEntry that is not a DTableCatalogEntry"); +} } // namespace duckdb @@ -11159,7 +12685,8 @@ namespace duckdb { TableFunctionCatalogEntry::TableFunctionCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateTableFunctionInfo *info) - : StandardEntry(CatalogType::TABLE_FUNCTION_ENTRY, schema, catalog, info->name), functions(move(info->functions)) { + : StandardEntry(CatalogType::TABLE_FUNCTION_ENTRY, schema, catalog, info->name), + functions(std::move(info->functions)) { D_ASSERT(this->functions.Size() > 0); } @@ -11246,7 +12773,7 @@ string TypeCatalogEntry::ToSQL() { namespace duckdb { void ViewCatalogEntry::Initialize(CreateViewInfo *info) { - query = move(info->query); + query = std::move(info->query); this->aliases = info->aliases; this->types = info->types; this->temporary = info->temporary; @@ -11314,7 +12841,7 @@ string ViewCatalogEntry::ToSQL() { unique_ptr ViewCatalogEntry::Copy(ClientContext &context) { D_ASSERT(!internal); - auto create_info = make_unique(schema->name, name); + auto create_info = make_unique(schema, name); create_info->query = unique_ptr_cast(query->Copy()); for (idx_t i = 0; i < aliases.size(); i++) { create_info->aliases.push_back(aliases[i]); @@ -11336,8 +12863,8 @@ unique_ptr ViewCatalogEntry::Copy(ClientContext &context) { namespace duckdb { CatalogEntry::CatalogEntry(CatalogType type, Catalog *catalog_p, string name_p) - : oid(catalog_p->ModifyCatalog()), type(type), catalog(catalog_p), set(nullptr), name(move(name_p)), deleted(false), - temporary(false), internal(false), parent(nullptr) { + : oid(catalog_p ? catalog_p->ModifyCatalog() : 0), type(type), catalog(catalog_p), set(nullptr), + name(std::move(name_p)), deleted(false), temporary(false), internal(false), parent(nullptr) { } CatalogEntry::~CatalogEntry() { @@ -11363,6 +12890,10 @@ string CatalogEntry::ToSQL() { } // LCOV_EXCL_STOP +void CatalogEntry::Verify(Catalog &catalog_p) { + D_ASSERT(&catalog_p == catalog); +} + } // namespace duckdb @@ -11374,62 +12905,296 @@ string CatalogEntry::ToSQL() { namespace duckdb { +CatalogSearchEntry::CatalogSearchEntry(string catalog_p, string schema_p) + : catalog(std::move(catalog_p)), schema(std::move(schema_p)) { +} + +string CatalogSearchEntry::ToString() const { + if (catalog.empty()) { + return WriteOptionallyQuoted(schema); + } else { + return WriteOptionallyQuoted(catalog) + "." + WriteOptionallyQuoted(schema); + } +} + +string CatalogSearchEntry::WriteOptionallyQuoted(const string &input) { + for (idx_t i = 0; i < input.size(); i++) { + if (input[i] == '.' || input[i] == ',') { + return "\"" + input + "\""; + } + } + return input; +} + +string CatalogSearchEntry::ListToString(const vector &input) { + string result; + for (auto &entry : input) { + if (!result.empty()) { + result += ","; + } + result += entry.ToString(); + } + return result; +} + +CatalogSearchEntry CatalogSearchEntry::ParseInternal(const string &input, idx_t &idx) { + string catalog; + string schema; + string entry; + bool finished = false; +normal: + for (; idx < input.size(); idx++) { + if (input[idx] == '"') { + idx++; + goto quoted; + } else if (input[idx] == '.') { + goto separator; + } else if (input[idx] == ',') { + finished = true; + goto separator; + } + entry += input[idx]; + } + finished = true; + goto separator; +quoted: + //! look for another quote + for (; idx < input.size(); idx++) { + if (input[idx] == '"') { + //! unquote + idx++; + goto normal; + } + entry += input[idx]; + } + throw ParserException("Unterminated quote in qualified name!"); +separator: + if (entry.empty()) { + throw ParserException("Unexpected dot - empty CatalogSearchEntry"); + } + if (schema.empty()) { + // if we parse one entry it is the schema + schema = std::move(entry); + } else if (catalog.empty()) { + // if we parse two entries it is [catalog.schema] + catalog = std::move(schema); + schema = std::move(entry); + } else { + throw ParserException("Too many dots - expected [schema] or [catalog.schema] for CatalogSearchEntry"); + } + entry = ""; + idx++; + if (finished) { + goto final; + } + goto normal; +final: + if (schema.empty()) { + throw ParserException("Unexpected end of entry - empty CatalogSearchEntry"); + } + return CatalogSearchEntry(std::move(catalog), std::move(schema)); +} + +CatalogSearchEntry CatalogSearchEntry::Parse(const string &input) { + idx_t pos = 0; + auto result = ParseInternal(input, pos); + if (pos < input.size()) { + throw ParserException("Failed to convert entry \"%s\" to CatalogSearchEntry - expected a single entry", input); + } + return result; +} + +vector CatalogSearchEntry::ParseList(const string &input) { + idx_t pos = 0; + vector result; + while (pos < input.size()) { + auto entry = ParseInternal(input, pos); + result.push_back(entry); + } + return result; +} + CatalogSearchPath::CatalogSearchPath(ClientContext &context_p) : context(context_p) { - SetPaths(ParsePaths("")); + Reset(); +} + +void CatalogSearchPath::Reset() { + vector empty; + SetPaths(empty); } -void CatalogSearchPath::Set(vector &new_paths, bool is_set_schema) { +void CatalogSearchPath::Set(vector new_paths, bool is_set_schema) { if (is_set_schema && new_paths.size() != 1) { throw CatalogException("SET schema can set only 1 schema. This has %d", new_paths.size()); } - auto &catalog = Catalog::GetCatalog(context); - for (const auto &path : new_paths) { - if (!catalog.GetSchema(context, StringUtil::Lower(path), true)) { - throw CatalogException("SET %s: No schema named %s found.", is_set_schema ? "schema" : "search_path", path); + for (auto &path : new_paths) { + if (!Catalog::GetSchema(context, path.catalog, path.schema, true)) { + if (path.catalog.empty()) { + // only schema supplied - check if this is a database instead + auto schema = Catalog::GetSchema(context, path.schema, DEFAULT_SCHEMA, true); + if (schema) { + path.catalog = std::move(path.schema); + path.schema = schema->name; + continue; + } + } + throw CatalogException("SET %s: No catalog + schema named %s found.", + is_set_schema ? "schema" : "search_path", path.ToString()); } } - this->set_paths = move(new_paths); + this->set_paths = std::move(new_paths); SetPaths(set_paths); } -void CatalogSearchPath::Set(const string &new_value, bool is_set_schema) { - auto new_paths = ParsePaths(new_value); - Set(new_paths, is_set_schema); +void CatalogSearchPath::Set(CatalogSearchEntry new_value, bool is_set_schema) { + vector new_paths {std::move(new_value)}; + Set(std::move(new_paths), is_set_schema); } -const vector &CatalogSearchPath::Get() { +const vector &CatalogSearchPath::Get() { return paths; } -const string &CatalogSearchPath::GetOrDefault(const string &name) { - return name == INVALID_SCHEMA ? GetDefault() : name; // NOLINT +string CatalogSearchPath::GetDefaultSchema(const string &catalog) { + for (auto &path : paths) { + if (path.catalog == TEMP_CATALOG) { + continue; + } + if (StringUtil::CIEquals(path.catalog, catalog)) { + return path.schema; + } + } + return DEFAULT_SCHEMA; +} + +string CatalogSearchPath::GetDefaultCatalog(const string &schema) { + for (auto &path : paths) { + if (path.catalog == TEMP_CATALOG) { + continue; + } + if (StringUtil::CIEquals(path.schema, schema)) { + return path.catalog; + } + } + return INVALID_CATALOG; +} + +vector CatalogSearchPath::GetCatalogsForSchema(const string &schema) { + vector schemas; + for (auto &path : paths) { + if (StringUtil::CIEquals(path.schema, schema)) { + schemas.push_back(path.catalog); + } + } + return schemas; +} + +vector CatalogSearchPath::GetSchemasForCatalog(const string &catalog) { + vector schemas; + for (auto &path : paths) { + if (StringUtil::CIEquals(path.catalog, catalog)) { + schemas.push_back(path.schema); + } + } + return schemas; } -const string &CatalogSearchPath::GetDefault() { +const CatalogSearchEntry &CatalogSearchPath::GetDefault() { const auto &paths = Get(); D_ASSERT(paths.size() >= 2); - D_ASSERT(paths[0] == TEMP_SCHEMA); return paths[1]; } -void CatalogSearchPath::SetPaths(vector new_paths) { +void CatalogSearchPath::SetPaths(vector new_paths) { paths.clear(); paths.reserve(new_paths.size() + 3); - paths.emplace_back(TEMP_SCHEMA); + paths.emplace_back(TEMP_CATALOG, DEFAULT_SCHEMA); for (auto &path : new_paths) { - paths.push_back(move(path)); + paths.push_back(std::move(path)); } - paths.emplace_back(DEFAULT_SCHEMA); - paths.emplace_back("pg_catalog"); -} - -vector CatalogSearchPath::ParsePaths(const string &value) { - return StringUtil::SplitWithQuote(StringUtil::Lower(value)); + paths.emplace_back(INVALID_CATALOG, DEFAULT_SCHEMA); + paths.emplace_back(SYSTEM_CATALOG, DEFAULT_SCHEMA); + paths.emplace_back(SYSTEM_CATALOG, "pg_catalog"); } } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/catalog/dcatalog.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +//! The Catalog object represents the catalog of the database. +class DuckCatalog : public Catalog { +public: + explicit DuckCatalog(AttachedDatabase &db); + ~DuckCatalog(); + +public: + bool IsDuckCatalog() override; + void Initialize(bool load_builtin) override; + string GetCatalogType() override { + return "duckdb"; + } + + DependencyManager &GetDependencyManager() { + return *dependency_manager; + } + mutex &GetWriteLock() { + return write_lock; + } + +public: + DUCKDB_API CatalogEntry *CreateSchema(CatalogTransaction transaction, CreateSchemaInfo *info) override; + DUCKDB_API void ScanSchemas(ClientContext &context, std::function callback) override; + DUCKDB_API void ScanSchemas(std::function callback); + + DUCKDB_API SchemaCatalogEntry *GetSchema(CatalogTransaction transaction, const string &schema_name, + bool if_exists = false, + QueryErrorContext error_context = QueryErrorContext()) override; + + DUCKDB_API unique_ptr PlanCreateTableAs(ClientContext &context, LogicalCreateTable &op, + unique_ptr plan) override; + DUCKDB_API unique_ptr PlanInsert(ClientContext &context, LogicalInsert &op, + unique_ptr plan) override; + DUCKDB_API unique_ptr PlanDelete(ClientContext &context, LogicalDelete &op, + unique_ptr plan) override; + DUCKDB_API unique_ptr PlanUpdate(ClientContext &context, LogicalUpdate &op, + unique_ptr plan) override; + DUCKDB_API unique_ptr BindCreateIndex(Binder &binder, CreateStatement &stmt, + TableCatalogEntry &table, + unique_ptr plan) override; + + DatabaseSize GetDatabaseSize(ClientContext &context) override; + + DUCKDB_API bool InMemory() override; + DUCKDB_API string GetDBPath() override; + +private: + DUCKDB_API void DropSchema(ClientContext &context, DropInfo *info) override; + + void Verify() override; + +private: + //! The DependencyManager manages dependencies between different catalog objects + unique_ptr dependency_manager; + //! Write lock for the catalog + mutex write_lock; + //! The catalog set holding the schemas + unique_ptr schemas; +}; + +} // namespace duckdb //===----------------------------------------------------------------------===// @@ -11451,6 +13216,7 @@ vector CatalogSearchPath::ParsePaths(const string &value) { namespace duckdb { +class AttachedDatabase; class ClientContext; class Catalog; struct ClientLockWrapper; @@ -11460,67 +13226,101 @@ class Transaction; //! The Transaction Manager is responsible for creating and managing //! transactions class TransactionManager { - friend struct CheckpointLock; - public: - explicit TransactionManager(DatabaseInstance &db); - ~TransactionManager(); + explicit TransactionManager(AttachedDatabase &db); + virtual ~TransactionManager(); //! Start a new transaction - Transaction *StartTransaction(ClientContext &context); - //! Commit the given transaction - string CommitTransaction(ClientContext &context, Transaction *transaction); + virtual Transaction *StartTransaction(ClientContext &context) = 0; + //! Commit the given transaction. Returns a non-empty error message on failure. + virtual string CommitTransaction(ClientContext &context, Transaction *transaction) = 0; //! Rollback the given transaction - void RollbackTransaction(Transaction *transaction); + virtual void RollbackTransaction(Transaction *transaction) = 0; - transaction_t GetQueryNumber() { - return current_query_number++; - } - transaction_t LowestActiveId() { - return lowest_active_id; + virtual void Checkpoint(ClientContext &context, bool force = false) = 0; + + static TransactionManager &Get(AttachedDatabase &db); + + virtual bool IsDuckTransactionManager() { + return false; } - transaction_t LowestActiveStart() { - return lowest_active_start; + + AttachedDatabase &GetDB() { + return db; } - void Checkpoint(ClientContext &context, bool force = false); +protected: + //! The attached database + AttachedDatabase &db; +}; - static TransactionManager &Get(ClientContext &context); - static TransactionManager &Get(DatabaseInstance &db); +} // namespace duckdb - void SetBaseCommitId(transaction_t base) { - D_ASSERT(base >= TRANSACTION_ID_START); - current_transaction_id = base; - } +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/transaction/duck_transaction.hpp +// +// +//===----------------------------------------------------------------------===// -private: - bool CanCheckpoint(Transaction *current = nullptr); - //! Remove the given transaction from the list of active transactions - void RemoveTransaction(Transaction *transaction) noexcept; - void LockClients(vector &client_locks, ClientContext &context); - //! The database instance - DatabaseInstance &db; - //! The current query number - atomic current_query_number; - //! The current start timestamp used by transactions - transaction_t current_start_timestamp; - //! The current transaction ID used by transactions - transaction_t current_transaction_id; - //! The lowest active transaction id - atomic lowest_active_id; - //! The lowest active transaction timestamp - atomic lowest_active_start; - //! Set of currently running transactions - vector> active_transactions; - //! Set of recently committed transactions - vector> recently_committed_transactions; - //! Transactions awaiting GC - vector> old_transactions; - //! The lock used for transaction operations - mutex transaction_lock; - bool thread_is_checkpointing; + + +namespace duckdb { + +class DuckTransaction : public Transaction { +public: + DuckTransaction(TransactionManager &manager, ClientContext &context, transaction_t start_time, + transaction_t transaction_id); + ~DuckTransaction(); + + //! The start timestamp of this transaction + transaction_t start_time; + //! The transaction id of this transaction + transaction_t transaction_id; + //! The commit id of this transaction, if it has successfully been committed + transaction_t commit_id; + //! Map of all sequences that were used during the transaction and the value they had in this transaction + unordered_map sequence_usage; + //! Highest active query when the transaction finished, used for cleaning up + transaction_t highest_active_query; + +public: + static DuckTransaction &Get(ClientContext &context, AttachedDatabase &db); + static DuckTransaction &Get(ClientContext &context, Catalog &catalog); + LocalStorage &GetLocalStorage(); + + void PushCatalogEntry(CatalogEntry *entry, data_ptr_t extra_data = nullptr, idx_t extra_data_size = 0); + + //! Commit the current transaction with the given commit identifier. Returns an error message if the transaction + //! commit failed, or an empty string if the commit was sucessful + string Commit(AttachedDatabase &db, transaction_t commit_id, bool checkpoint) noexcept; + //! Returns whether or not a commit of this transaction should trigger an automatic checkpoint + bool AutomaticCheckpoint(AttachedDatabase &db); + + //! Rollback + void Rollback() noexcept; + //! Cleanup the undo buffer + void Cleanup(); + + bool ChangesMade(); + + void PushDelete(DataTable *table, ChunkVectorInfo *vinfo, row_t rows[], idx_t count, idx_t base_row); + void PushAppend(DataTable *table, idx_t row_start, idx_t row_count); + UpdateInfo *CreateUpdateInfo(idx_t type_size, idx_t entries); + + bool IsDuckTransaction() const override { + return true; + } + +private: + //! The undo buffer is used to store old versions of rows that are updated + //! or deleted + UndoBuffer undo_buffer; + //! The set of uncommitted appends for the transaction + unique_ptr storage; }; } // namespace duckdb @@ -11531,7 +13331,6 @@ class TransactionManager { - //===----------------------------------------------------------------------===// // DuckDB // @@ -11612,7 +13411,8 @@ struct EntryIndex { }; struct MappingValue { - explicit MappingValue(EntryIndex index_p) : index(move(index_p)), timestamp(0), deleted(false), parent(nullptr) { + explicit MappingValue(EntryIndex index_p) + : index(std::move(index_p)), timestamp(0), deleted(false), parent(nullptr) { } EntryIndex index; @@ -11625,6 +13425,7 @@ struct MappingValue { } // namespace duckdb + namespace duckdb { //! Class responsible to keep track of state when removing entries from the catalog. @@ -11652,8 +13453,9 @@ class EntryDropper { EntryIndex &entry_index; }; -CatalogSet::CatalogSet(Catalog &catalog, unique_ptr defaults) - : catalog(catalog), defaults(move(defaults)) { +CatalogSet::CatalogSet(Catalog &catalog_p, unique_ptr defaults) + : catalog((DuckCatalog &)catalog_p), defaults(std::move(defaults)) { + D_ASSERT(catalog_p.IsDuckCatalog()); } CatalogSet::~CatalogSet() { } @@ -11662,7 +13464,7 @@ EntryIndex CatalogSet::PutEntry(idx_t entry_index, unique_ptr entr if (entries.find(entry_index) != entries.end()) { throw InternalException("Entry with entry index \"%llu\" already exists", entry_index); } - entries.insert(make_pair(entry_index, EntryValue(move(entry)))); + entries.insert(make_pair(entry_index, EntryValue(std::move(entry)))); return EntryIndex(*this, entry_index); } @@ -11671,27 +13473,45 @@ void CatalogSet::PutEntry(EntryIndex index, unique_ptr catalog_ent if (entry == entries.end()) { throw InternalException("Entry with entry index \"%llu\" does not exist", index.GetIndex()); } - catalog_entry->child = move(entry->second.entry); + catalog_entry->child = std::move(entry->second.entry); catalog_entry->child->parent = catalog_entry.get(); - entry->second.entry = move(catalog_entry); + entry->second.entry = std::move(catalog_entry); } -bool CatalogSet::CreateEntry(ClientContext &context, const string &name, unique_ptr value, - unordered_set &dependencies) { - auto &transaction = Transaction::GetTransaction(context); +bool CatalogSet::CreateEntry(CatalogTransaction transaction, const string &name, unique_ptr value, + DependencyList &dependencies) { + if (value->internal && !catalog.IsSystemCatalog() && name != DEFAULT_SCHEMA) { + throw InternalException("Attempting to create internal entry \"%s\" in non-system catalog - internal entries " + "can only be created in the system catalog", + name); + } + if (!value->internal) { + if (!value->temporary && catalog.IsSystemCatalog()) { + throw InternalException( + "Attempting to create non-internal entry \"%s\" in system catalog - the system catalog " + "can only contain internal entries", + name); + } + if (value->temporary && !catalog.IsTemporaryCatalog()) { + throw InternalException("Attempting to create temporary entry \"%s\" in non-temporary catalog", name); + } + if (!value->temporary && catalog.IsTemporaryCatalog() && name != DEFAULT_SCHEMA) { + throw InternalException("Attempting to create non-temporary entry \"%s\" in temporary catalog", name); + } + } // lock the catalog for writing - lock_guard write_lock(catalog.write_lock); + lock_guard write_lock(catalog.GetWriteLock()); // lock this catalog set to disallow reading unique_lock read_lock(catalog_lock); // first check if the entry exists in the unordered set idx_t index; - auto mapping_value = GetMapping(context, name); + auto mapping_value = GetMapping(transaction, name); if (mapping_value == nullptr || mapping_value->deleted) { // if it does not: entry has never been created // check if there is a default entry - auto entry = CreateDefaultEntry(context, name, read_lock); + auto entry = CreateDefaultEntry(transaction, name, read_lock); if (entry) { return false; } @@ -11704,14 +13524,14 @@ bool CatalogSet::CreateEntry(ClientContext &context, const string &name, unique_ dummy_node->deleted = true; dummy_node->set = this; - auto entry_index = PutEntry(current_entry++, move(dummy_node)); + auto entry_index = PutEntry(current_entry++, std::move(dummy_node)); index = entry_index.GetIndex(); - PutMapping(context, name, move(entry_index)); + PutMapping(transaction, name, std::move(entry_index)); } else { index = mapping_value->index.GetIndex(); auto ¤t = *mapping_value->index.GetEntry(); // if it does, we have to check version numbers - if (HasConflict(context, current.timestamp)) { + if (HasConflict(transaction, current.timestamp)) { // current version has been written to by a currently active // transaction throw TransactionException("Catalog write-write conflict on create with \"%s\"", current.name); @@ -11729,20 +13549,29 @@ bool CatalogSet::CreateEntry(ClientContext &context, const string &name, unique_ value->set = this; // now add the dependency set of this object to the dependency manager - catalog.dependency_manager->AddObject(context, value.get(), dependencies); + catalog.GetDependencyManager().AddObject(transaction, value.get(), dependencies); auto value_ptr = value.get(); EntryIndex entry_index(*this, index); - PutEntry(move(entry_index), move(value)); + PutEntry(std::move(entry_index), std::move(value)); // push the old entry in the undo buffer for this transaction - transaction.PushCatalogEntry(value_ptr->child.get()); + if (transaction.transaction) { + auto &dtransaction = (DuckTransaction &)*transaction.transaction; + dtransaction.PushCatalogEntry(value_ptr->child.get()); + } return true; } -bool CatalogSet::GetEntryInternal(ClientContext &context, EntryIndex &entry_index, CatalogEntry *&catalog_entry) { +bool CatalogSet::CreateEntry(ClientContext &context, const string &name, unique_ptr value, + DependencyList &dependencies) { + return CreateEntry(catalog.GetCatalogTransaction(context), name, std::move(value), dependencies); +} + +bool CatalogSet::GetEntryInternal(CatalogTransaction transaction, EntryIndex &entry_index, + CatalogEntry *&catalog_entry) { catalog_entry = entry_index.GetEntry().get(); // if it does: we have to retrieve the entry and to check version numbers - if (HasConflict(context, catalog_entry->timestamp)) { + if (HasConflict(transaction, catalog_entry->timestamp)) { // current version has been written to by a currently active // transaction throw TransactionException("Catalog write-write conflict on alter with \"%s\"", catalog_entry->name); @@ -11756,9 +13585,9 @@ bool CatalogSet::GetEntryInternal(ClientContext &context, EntryIndex &entry_inde return true; } -bool CatalogSet::GetEntryInternal(ClientContext &context, const string &name, EntryIndex *entry_index, +bool CatalogSet::GetEntryInternal(CatalogTransaction transaction, const string &name, EntryIndex *entry_index, CatalogEntry *&catalog_entry) { - auto mapping_value = GetMapping(context, name); + auto mapping_value = GetMapping(transaction, name); if (mapping_value == nullptr || mapping_value->deleted) { // the entry does not exist, check if we can create a default entry return false; @@ -11766,37 +13595,36 @@ bool CatalogSet::GetEntryInternal(ClientContext &context, const string &name, En if (entry_index) { *entry_index = mapping_value->index.Copy(); } - return GetEntryInternal(context, mapping_value->index, catalog_entry); + return GetEntryInternal(transaction, mapping_value->index, catalog_entry); } -bool CatalogSet::AlterOwnership(ClientContext &context, ChangeOwnershipInfo *info) { +bool CatalogSet::AlterOwnership(CatalogTransaction transaction, ChangeOwnershipInfo *info) { CatalogEntry *entry; - if (!GetEntryInternal(context, info->name, nullptr, entry)) { + if (!GetEntryInternal(transaction, info->name, nullptr, entry)) { return false; } - auto owner_entry = catalog.GetEntry(context, info->owner_schema, info->owner_name); + auto owner_entry = catalog.GetEntry(transaction.GetContext(), info->owner_schema, info->owner_name); if (!owner_entry) { return false; } - catalog.dependency_manager->AddOwnership(context, owner_entry, entry); + catalog.GetDependencyManager().AddOwnership(transaction, owner_entry, entry); return true; } -bool CatalogSet::AlterEntry(ClientContext &context, const string &name, AlterInfo *alter_info) { - auto &transaction = Transaction::GetTransaction(context); +bool CatalogSet::AlterEntry(CatalogTransaction transaction, const string &name, AlterInfo *alter_info) { // lock the catalog for writing - lock_guard write_lock(catalog.write_lock); + lock_guard write_lock(catalog.GetWriteLock()); // first check if the entry exists in the unordered set EntryIndex entry_index; CatalogEntry *entry; - if (!GetEntryInternal(context, name, &entry_index, entry)) { + if (!GetEntryInternal(transaction, name, &entry_index, entry)) { return false; } - if (entry->internal) { + if (!alter_info->allow_internal && entry->internal) { throw CatalogException("Cannot alter entry \"%s\" because it is an internal system entry", entry->name); } @@ -11807,6 +13635,10 @@ bool CatalogSet::AlterEntry(ClientContext &context, const string &name, AlterInf // set the timestamp to the timestamp of the current transaction // and point it to the updated table node string original_name = entry->name; + if (!transaction.context) { + throw InternalException("Cannot AlterEntry without client context"); + } + auto &context = *transaction.context; auto value = entry->AlterEntry(context, alter_info); if (!value) { // alter failed, but did not result in an error @@ -11814,9 +13646,9 @@ bool CatalogSet::AlterEntry(ClientContext &context, const string &name, AlterInf } if (value->name != original_name) { - auto mapping_value = GetMapping(context, value->name); + auto mapping_value = GetMapping(transaction, value->name); if (mapping_value && !mapping_value->deleted) { - auto original_entry = GetEntryForTransaction(context, mapping_value->index.GetEntry().get()); + auto original_entry = GetEntryForTransaction(transaction, mapping_value->index.GetEntry().get()); if (!original_entry->deleted) { entry->UndoAlter(context, alter_info); string rename_err_msg = @@ -11828,14 +13660,14 @@ bool CatalogSet::AlterEntry(ClientContext &context, const string &name, AlterInf if (value->name != original_name) { // Do PutMapping and DeleteMapping after dependency check - PutMapping(context, value->name, entry_index.Copy()); - DeleteMapping(context, original_name); + PutMapping(transaction, value->name, entry_index.Copy()); + DeleteMapping(transaction, original_name); } value->timestamp = transaction.transaction_id; value->set = this; auto new_entry = value.get(); - PutEntry(move(entry_index), move(value)); + PutEntry(std::move(entry_index), std::move(value)); // serialize the AlterInfo into a temporary buffer BufferedSerializer serializer; @@ -11843,18 +13675,21 @@ bool CatalogSet::AlterEntry(ClientContext &context, const string &name, AlterInf BinaryData serialized_alter = serializer.GetData(); // push the old entry in the undo buffer for this transaction - transaction.PushCatalogEntry(new_entry->child.get(), serialized_alter.data.get(), serialized_alter.size); + if (transaction.transaction) { + auto &dtransaction = (DuckTransaction &)*transaction.transaction; + dtransaction.PushCatalogEntry(new_entry->child.get(), serialized_alter.data.get(), serialized_alter.size); + } // Check the dependency manager to verify that there are no conflicting dependencies with this alter // Note that we do this AFTER the new entry has been entirely set up in the catalog set // that is because in case the alter fails because of a dependency conflict, we need to be able to cleanly roll back // to the old entry. - catalog.dependency_manager->AlterObject(context, entry, new_entry); + catalog.GetDependencyManager().AlterObject(transaction, entry, new_entry); return true; } -void CatalogSet::DropEntryDependencies(ClientContext &context, EntryIndex &entry_index, CatalogEntry &entry, +void CatalogSet::DropEntryDependencies(CatalogTransaction transaction, EntryIndex &entry_index, CatalogEntry &entry, bool cascade) { // Stores the deleted value of the entry before starting the process EntryDropper dropper(entry_index); @@ -11863,17 +13698,17 @@ void CatalogSet::DropEntryDependencies(ClientContext &context, EntryIndex &entry entry_index.GetEntry()->deleted = true; // check any dependencies of this object - entry.catalog->dependency_manager->DropObject(context, &entry, cascade); + D_ASSERT(entry.catalog->IsDuckCatalog()); + ((DuckCatalog &)*entry.catalog).GetDependencyManager().DropObject(transaction, &entry, cascade); // dropper destructor is called here // the destructor makes sure to return the value to the previous state // dropper.~EntryDropper() } -void CatalogSet::DropEntryInternal(ClientContext &context, EntryIndex entry_index, CatalogEntry &entry, bool cascade) { - auto &transaction = Transaction::GetTransaction(context); - - DropEntryDependencies(context, entry_index, entry, cascade); +void CatalogSet::DropEntryInternal(CatalogTransaction transaction, EntryIndex entry_index, CatalogEntry &entry, + bool cascade) { + DropEntryDependencies(transaction, entry_index, entry, cascade); // create a new entry and replace the currently stored one // set the timestamp to the timestamp of the current transaction @@ -11883,41 +13718,54 @@ void CatalogSet::DropEntryInternal(ClientContext &context, EntryIndex entry_inde value->set = this; value->deleted = true; auto value_ptr = value.get(); - PutEntry(move(entry_index), move(value)); + PutEntry(std::move(entry_index), std::move(value)); // push the old entry in the undo buffer for this transaction - transaction.PushCatalogEntry(value_ptr->child.get()); + if (transaction.transaction) { + auto &dtransaction = (DuckTransaction &)*transaction.transaction; + dtransaction.PushCatalogEntry(value_ptr->child.get()); + } } -bool CatalogSet::DropEntry(ClientContext &context, const string &name, bool cascade) { +bool CatalogSet::DropEntry(CatalogTransaction transaction, const string &name, bool cascade, bool allow_drop_internal) { // lock the catalog for writing - lock_guard write_lock(catalog.write_lock); + lock_guard write_lock(catalog.GetWriteLock()); // we can only delete an entry that exists EntryIndex entry_index; CatalogEntry *entry; - if (!GetEntryInternal(context, name, &entry_index, entry)) { + if (!GetEntryInternal(transaction, name, &entry_index, entry)) { return false; } - if (entry->internal) { + if (entry->internal && !allow_drop_internal) { throw CatalogException("Cannot drop entry \"%s\" because it is an internal system entry", entry->name); } lock_guard read_lock(catalog_lock); - DropEntryInternal(context, move(entry_index), *entry, cascade); + DropEntryInternal(transaction, std::move(entry_index), *entry, cascade); return true; } +bool CatalogSet::DropEntry(ClientContext &context, const string &name, bool cascade, bool allow_drop_internal) { + return DropEntry(catalog.GetCatalogTransaction(context), name, cascade, allow_drop_internal); +} + +DuckCatalog &CatalogSet::GetCatalog() { + return catalog; +} + void CatalogSet::CleanupEntry(CatalogEntry *catalog_entry) { // destroy the backed up entry: it is no longer required D_ASSERT(catalog_entry->parent); if (catalog_entry->parent->type != CatalogType::UPDATED_ENTRY) { + lock_guard write_lock(catalog.GetWriteLock()); lock_guard lock(catalog_lock); if (!catalog_entry->deleted) { // delete the entry from the dependency manager, if it is not deleted yet - catalog_entry->catalog->dependency_manager->EraseObject(catalog_entry); + D_ASSERT(catalog_entry->catalog->IsDuckCatalog()); + ((DuckCatalog &)*catalog_entry->catalog).GetDependencyManager().EraseObject(catalog_entry); } auto parent = catalog_entry->parent; - parent->child = move(catalog_entry->child); + parent->child = std::move(catalog_entry->child); if (parent->deleted && !parent->child && !parent->parent) { auto mapping_entry = mapping.find(parent->name); D_ASSERT(mapping_entry != mapping.end()); @@ -11930,13 +13778,12 @@ void CatalogSet::CleanupEntry(CatalogEntry *catalog_entry) { } } -bool CatalogSet::HasConflict(ClientContext &context, transaction_t timestamp) { - auto &transaction = Transaction::GetTransaction(context); +bool CatalogSet::HasConflict(CatalogTransaction transaction, transaction_t timestamp) { return (timestamp >= TRANSACTION_ID_START && timestamp != transaction.transaction_id) || (timestamp < TRANSACTION_ID_START && timestamp > transaction.start_time); } -MappingValue *CatalogSet::GetMapping(ClientContext &context, const string &name, bool get_latest) { +MappingValue *CatalogSet::GetMapping(CatalogTransaction transaction, const string &name, bool get_latest) { MappingValue *mapping_value; auto entry = mapping.find(name); if (entry != mapping.end()) { @@ -11949,7 +13796,7 @@ MappingValue *CatalogSet::GetMapping(ClientContext &context, const string &name, return mapping_value; } while (mapping_value->child) { - if (UseTimestamp(context, mapping_value->timestamp)) { + if (UseTimestamp(transaction, mapping_value->timestamp)) { break; } mapping_value = mapping_value->child.get(); @@ -11958,33 +13805,32 @@ MappingValue *CatalogSet::GetMapping(ClientContext &context, const string &name, return mapping_value; } -void CatalogSet::PutMapping(ClientContext &context, const string &name, EntryIndex entry_index) { +void CatalogSet::PutMapping(CatalogTransaction transaction, const string &name, EntryIndex entry_index) { auto entry = mapping.find(name); - auto new_value = make_unique(move(entry_index)); - new_value->timestamp = Transaction::GetTransaction(context).transaction_id; + auto new_value = make_unique(std::move(entry_index)); + new_value->timestamp = transaction.transaction_id; if (entry != mapping.end()) { - if (HasConflict(context, entry->second->timestamp)) { + if (HasConflict(transaction, entry->second->timestamp)) { throw TransactionException("Catalog write-write conflict on name \"%s\"", name); } - new_value->child = move(entry->second); + new_value->child = std::move(entry->second); new_value->child->parent = new_value.get(); } - mapping[name] = move(new_value); + mapping[name] = std::move(new_value); } -void CatalogSet::DeleteMapping(ClientContext &context, const string &name) { +void CatalogSet::DeleteMapping(CatalogTransaction transaction, const string &name) { auto entry = mapping.find(name); D_ASSERT(entry != mapping.end()); auto delete_marker = make_unique(entry->second->index.Copy()); delete_marker->deleted = true; - delete_marker->timestamp = Transaction::GetTransaction(context).transaction_id; - delete_marker->child = move(entry->second); + delete_marker->timestamp = transaction.transaction_id; + delete_marker->child = std::move(entry->second); delete_marker->child->parent = delete_marker.get(); - mapping[name] = move(delete_marker); + mapping[name] = std::move(delete_marker); } -bool CatalogSet::UseTimestamp(ClientContext &context, transaction_t timestamp) { - auto &transaction = Transaction::GetTransaction(context); +bool CatalogSet::UseTimestamp(CatalogTransaction transaction, transaction_t timestamp) { if (timestamp == transaction.transaction_id) { // we created this version return true; @@ -11996,9 +13842,9 @@ bool CatalogSet::UseTimestamp(ClientContext &context, transaction_t timestamp) { return false; } -CatalogEntry *CatalogSet::GetEntryForTransaction(ClientContext &context, CatalogEntry *current) { +CatalogEntry *CatalogSet::GetEntryForTransaction(CatalogTransaction transaction, CatalogEntry *current) { while (current->child) { - if (UseTimestamp(context, current->timestamp)) { + if (UseTimestamp(transaction, current->timestamp)) { break; } current = current->child.get(); @@ -12019,26 +13865,25 @@ CatalogEntry *CatalogSet::GetCommittedEntry(CatalogEntry *current) { return current; } -pair CatalogSet::SimilarEntry(ClientContext &context, const string &name) { +SimilarCatalogEntry CatalogSet::SimilarEntry(CatalogTransaction transaction, const string &name) { unique_lock lock(catalog_lock); - CreateDefaultEntries(context, lock); + CreateDefaultEntries(transaction, lock); - string result; - idx_t current_score = (idx_t)-1; + SimilarCatalogEntry result; for (auto &kv : mapping) { - auto mapping_value = GetMapping(context, kv.first); + auto mapping_value = GetMapping(transaction, kv.first); if (mapping_value && !mapping_value->deleted) { auto ldist = StringUtil::LevenshteinDistance(kv.first, name); - if (ldist < current_score) { - current_score = ldist; - result = kv.first; + if (ldist < result.distance) { + result.distance = ldist; + result.name = kv.first; } } } - return {result, current_score}; + return result; } -CatalogEntry *CatalogSet::CreateEntryInternal(ClientContext &context, unique_ptr entry) { +CatalogEntry *CatalogSet::CreateEntryInternal(CatalogTransaction transaction, unique_ptr entry) { if (mapping.find(entry->name) != mapping.end()) { return nullptr; } @@ -12048,13 +13893,14 @@ CatalogEntry *CatalogSet::CreateEntryInternal(ClientContext &context, unique_ptr entry->set = this; entry->timestamp = 0; - auto entry_index = PutEntry(current_entry++, move(entry)); - PutMapping(context, name, move(entry_index)); + auto entry_index = PutEntry(current_entry++, std::move(entry)); + PutMapping(transaction, name, std::move(entry_index)); mapping[name]->timestamp = 0; return catalog_entry; } -CatalogEntry *CatalogSet::CreateDefaultEntry(ClientContext &context, const string &name, unique_lock &lock) { +CatalogEntry *CatalogSet::CreateDefaultEntry(CatalogTransaction transaction, const string &name, + unique_lock &lock) { // no entry found with this name, check for defaults if (!defaults || defaults->created_all_entries) { // no defaults either: return null @@ -12062,8 +13908,12 @@ CatalogEntry *CatalogSet::CreateDefaultEntry(ClientContext &context, const strin } // this catalog set has a default map defined // check if there is a default entry that we can create with this name + if (!transaction.context) { + // no context - cannot create default entry + return nullptr; + } lock.unlock(); - auto entry = defaults->CreateDefaultEntry(context, name); + auto entry = defaults->CreateDefaultEntry(*transaction.context, name); lock.lock(); if (!entry) { @@ -12071,7 +13921,7 @@ CatalogEntry *CatalogSet::CreateDefaultEntry(ClientContext &context, const strin return nullptr; } // there is a default entry! create it - auto result = CreateEntryInternal(context, move(entry)); + auto result = CreateEntryInternal(transaction, std::move(entry)); if (result) { return result; } @@ -12079,24 +13929,28 @@ CatalogEntry *CatalogSet::CreateDefaultEntry(ClientContext &context, const strin // this means somebody else created the entry first // just retry? lock.unlock(); - return GetEntry(context, name); + return GetEntry(transaction, name); } -CatalogEntry *CatalogSet::GetEntry(ClientContext &context, const string &name) { +CatalogEntry *CatalogSet::GetEntry(CatalogTransaction transaction, const string &name) { unique_lock lock(catalog_lock); - auto mapping_value = GetMapping(context, name); + auto mapping_value = GetMapping(transaction, name); if (mapping_value != nullptr && !mapping_value->deleted) { // we found an entry for this name // check the version numbers auto catalog_entry = mapping_value->index.GetEntry().get(); - CatalogEntry *current = GetEntryForTransaction(context, catalog_entry); - if (current->deleted || (current->name != name && !UseTimestamp(context, mapping_value->timestamp))) { + CatalogEntry *current = GetEntryForTransaction(transaction, catalog_entry); + if (current->deleted || (current->name != name && !UseTimestamp(transaction, mapping_value->timestamp))) { return nullptr; } return current; } - return CreateDefaultEntry(context, name, lock); + return CreateDefaultEntry(transaction, name, lock); +} + +CatalogEntry *CatalogSet::GetEntry(ClientContext &context, const string &name) { + return GetEntry(catalog.GetCatalogTransaction(context), name); } void CatalogSet::UpdateTimestamp(CatalogEntry *entry, transaction_t timestamp) { @@ -12107,12 +13961,13 @@ void CatalogSet::UpdateTimestamp(CatalogEntry *entry, transaction_t timestamp) { void CatalogSet::AdjustUserDependency(CatalogEntry *entry, ColumnDefinition &column, bool remove) { CatalogEntry *user_type_catalog = (CatalogEntry *)LogicalType::GetCatalog(column.Type()); if (user_type_catalog) { + auto &dependency_manager = catalog.GetDependencyManager(); if (remove) { - catalog.dependency_manager->dependents_map[user_type_catalog].erase(entry->parent); - catalog.dependency_manager->dependencies_map[entry->parent].erase(user_type_catalog); + dependency_manager.dependents_map[user_type_catalog].erase(entry->parent); + dependency_manager.dependencies_map[entry->parent].erase(user_type_catalog); } else { - catalog.dependency_manager->dependents_map[user_type_catalog].insert(entry); - catalog.dependency_manager->dependencies_map[entry].insert(user_type_catalog); + dependency_manager.dependents_map[user_type_catalog].insert(entry); + dependency_manager.dependencies_map[entry].insert(user_type_catalog); } } } @@ -12121,7 +13976,7 @@ void CatalogSet::AdjustDependency(CatalogEntry *entry, TableCatalogEntry *table, bool remove) { bool found = false; if (column.Type().id() == LogicalTypeId::ENUM) { - for (auto &old_column : table->columns.Logical()) { + for (auto &old_column : table->GetColumns().Logical()) { if (old_column.Name() == column.Name() && old_column.Type().id() != LogicalTypeId::ENUM) { AdjustUserDependency(entry, column, remove); found = true; @@ -12132,7 +13987,7 @@ void CatalogSet::AdjustDependency(CatalogEntry *entry, TableCatalogEntry *table, } } else if (!(column.Type().GetAlias().empty())) { auto alias = column.Type().GetAlias(); - for (auto &old_column : table->columns.Logical()) { + for (auto &old_column : table->GetColumns().Logical()) { auto old_alias = old_column.Type().GetAlias(); if (old_column.Name() == column.Name() && old_alias != alias) { AdjustUserDependency(entry, column, remove); @@ -12151,20 +14006,19 @@ void CatalogSet::AdjustTableDependencies(CatalogEntry *entry) { auto old_table = (TableCatalogEntry *)entry->parent; auto new_table = (TableCatalogEntry *)entry; - for (idx_t i = 0; i < new_table->columns.LogicalColumnCount(); i++) { - auto &new_column = new_table->columns.GetColumnMutable(LogicalIndex(i)); + for (idx_t i = 0; i < new_table->GetColumns().LogicalColumnCount(); i++) { + auto &new_column = new_table->GetColumnsMutable().GetColumnMutable(LogicalIndex(i)); AdjustDependency(entry, old_table, new_column, false); } - for (idx_t i = 0; i < old_table->columns.LogicalColumnCount(); i++) { - auto &old_column = old_table->columns.GetColumnMutable(LogicalIndex(i)); + for (idx_t i = 0; i < old_table->GetColumns().LogicalColumnCount(); i++) { + auto &old_column = old_table->GetColumnsMutable().GetColumnMutable(LogicalIndex(i)); AdjustDependency(entry, new_table, old_column, true); } } } void CatalogSet::Undo(CatalogEntry *entry) { - lock_guard write_lock(catalog.write_lock); - + lock_guard write_lock(catalog.GetWriteLock()); lock_guard lock(catalog_lock); // entry has to be restored @@ -12177,14 +14031,15 @@ void CatalogSet::Undo(CatalogEntry *entry) { if (!to_be_removed_node->deleted) { // delete the entry from the dependency manager as well - catalog.dependency_manager->EraseObject(to_be_removed_node); + auto &dependency_manager = catalog.GetDependencyManager(); + dependency_manager.EraseObject(to_be_removed_node); } if (entry->name != to_be_removed_node->name) { // rename: clean up the new name when the rename is rolled back auto removed_entry = mapping.find(to_be_removed_node->name); if (removed_entry->second->child) { removed_entry->second->child->parent = nullptr; - mapping[to_be_removed_node->name] = move(removed_entry->second->child); + mapping[to_be_removed_node->name] = std::move(removed_entry->second->child); } else { mapping.erase(removed_entry); } @@ -12192,13 +14047,13 @@ void CatalogSet::Undo(CatalogEntry *entry) { if (to_be_removed_node->parent) { // if the to be removed node has a parent, set the child pointer to the // to be restored node - to_be_removed_node->parent->child = move(to_be_removed_node->child); + to_be_removed_node->parent->child = std::move(to_be_removed_node->child); entry->parent = to_be_removed_node->parent; } else { // otherwise we need to update the base entry tables auto &name = entry->name; to_be_removed_node->child->SetAsRoot(); - mapping[name]->index.GetEntry() = move(to_be_removed_node->child); + mapping[name]->index.GetEntry() = std::move(to_be_removed_node->child); entry->parent = nullptr; } @@ -12207,7 +14062,7 @@ void CatalogSet::Undo(CatalogEntry *entry) { if (restored_entry->second->deleted || entry->type == CatalogType::INVALID) { if (restored_entry->second->child) { restored_entry->second->child->parent = nullptr; - mapping[entry->name] = move(restored_entry->second->child); + mapping[entry->name] = std::move(restored_entry->second->child); } else { mapping.erase(restored_entry); } @@ -12216,8 +14071,8 @@ void CatalogSet::Undo(CatalogEntry *entry) { catalog.ModifyCatalog(); } -void CatalogSet::CreateDefaultEntries(ClientContext &context, unique_lock &lock) { - if (!defaults || defaults->created_all_entries) { +void CatalogSet::CreateDefaultEntries(CatalogTransaction transaction, unique_lock &lock) { + if (!defaults || defaults->created_all_entries || !transaction.context) { return; } // this catalog set has a default set defined: @@ -12228,32 +14083,36 @@ void CatalogSet::CreateDefaultEntries(ClientContext &context, unique_lock // we unlock during the CreateEntry, since it might reference other catalog sets... // specifically for views this can happen since the view will be bound lock.unlock(); - auto entry = defaults->CreateDefaultEntry(context, default_entry); + auto entry = defaults->CreateDefaultEntry(*transaction.context, default_entry); if (!entry) { throw InternalException("Failed to create default entry for %s", default_entry); } lock.lock(); - CreateEntryInternal(context, move(entry)); + CreateEntryInternal(transaction, std::move(entry)); } } defaults->created_all_entries = true; } -void CatalogSet::Scan(ClientContext &context, const std::function &callback) { +void CatalogSet::Scan(CatalogTransaction transaction, const std::function &callback) { // lock the catalog set unique_lock lock(catalog_lock); - CreateDefaultEntries(context, lock); + CreateDefaultEntries(transaction, lock); for (auto &kv : entries) { auto entry = kv.second.entry.get(); - entry = GetEntryForTransaction(context, entry); + entry = GetEntryForTransaction(transaction, entry); if (!entry->deleted) { callback(entry); } } } +void CatalogSet::Scan(ClientContext &context, const std::function &callback) { + Scan(catalog.GetCatalogTransaction(context), callback); +} + void CatalogSet::Scan(const std::function &callback) { // lock the catalog set lock_guard lock(catalog_lock); @@ -12265,6 +14124,50 @@ void CatalogSet::Scan(const std::function &callback) { } } } + +void CatalogSet::Verify(Catalog &catalog_p) { + D_ASSERT(&catalog_p == &catalog); + vector entries; + Scan([&](CatalogEntry *entry) { entries.push_back(entry); }); + for (auto &entry : entries) { + entry->Verify(catalog_p); + } +} + +} // namespace duckdb + + + + + +namespace duckdb { + +CatalogTransaction::CatalogTransaction(Catalog &catalog, ClientContext &context) { + auto &transaction = Transaction::Get(context, catalog); + this->db = &DatabaseInstance::GetDatabase(context); + if (!transaction.IsDuckTransaction()) { + this->transaction_id = transaction_t(-1); + this->start_time = transaction_t(-1); + } else { + auto &dtransaction = (DuckTransaction &)transaction; + this->transaction_id = dtransaction.transaction_id; + this->start_time = dtransaction.start_time; + } + this->transaction = &transaction; + this->context = &context; +} + +CatalogTransaction::CatalogTransaction(DatabaseInstance &db, transaction_t transaction_id_p, transaction_t start_time_p) + : db(&db), context(nullptr), transaction(nullptr), transaction_id(transaction_id_p), start_time(start_time_p) { +} + +ClientContext &CatalogTransaction::GetContext() { + if (!context) { + throw InternalException("Attempting to get a context in a CatalogTransaction without a context"); + } + return *context; +} + } // namespace duckdb //===----------------------------------------------------------------------===// @@ -12391,8 +14294,7 @@ namespace duckdb { static DefaultMacro internal_macros[] = { {DEFAULT_SCHEMA, "current_user", {nullptr}, "'duckdb'"}, // user name of current execution context - {DEFAULT_SCHEMA, "current_catalog", {nullptr}, "'duckdb'"}, // name of current database (called "catalog" in the SQL standard) - {DEFAULT_SCHEMA, "current_database", {nullptr}, "'duckdb'"}, // name of current database + {DEFAULT_SCHEMA, "current_catalog", {nullptr}, "current_database()"}, // name of current database (called "catalog" in the SQL standard) {DEFAULT_SCHEMA, "user", {nullptr}, "current_user"}, // equivalent to current_user {DEFAULT_SCHEMA, "session_user", {nullptr}, "'duckdb'"}, // session user name {"pg_catalog", "inet_client_addr", {nullptr}, "NULL"}, // address of the remote connection @@ -12435,7 +14337,7 @@ static DefaultMacro internal_macros[] = { {"pg_catalog", "pg_get_viewdef", {"oid", nullptr}, "(select sql from duckdb_views() v where v.view_oid=oid)"}, {"pg_catalog", "pg_get_constraintdef", {"constraint_oid", "pretty_bool", nullptr}, "(select constraint_text from duckdb_constraints() d_constraint where d_constraint.table_oid=constraint_oid/1000000 and d_constraint.constraint_index=constraint_oid%1000000)"}, {"pg_catalog", "pg_get_expr", {"pg_node_tree", "relation_oid", nullptr}, "pg_node_tree"}, - {"pg_catalog", "format_pg_type", {"type_name", nullptr}, "case when logical_type='FLOAT' then 'real' when logical_type='DOUBLE' then 'double precision' when logical_type='DECIMAL' then 'numeric' when logical_type='VARCHAR' then 'character varying' when logical_type='BLOB' then 'bytea' when logical_type='TIMESTAMP' then 'timestamp without time zone' when logical_type='TIME' then 'time without time zone' else lower(logical_type) end"}, + {"pg_catalog", "format_pg_type", {"type_name", nullptr}, "case when logical_type='FLOAT' then 'real' when logical_type='DOUBLE' then 'double precision' when logical_type='DECIMAL' then 'numeric' when logical_type='ENUM' then lower(type_name) when logical_type='VARCHAR' then 'character varying' when logical_type='BLOB' then 'bytea' when logical_type='TIMESTAMP' then 'timestamp without time zone' when logical_type='TIME' then 'time without time zone' else lower(logical_type) end"}, {"pg_catalog", "format_type", {"type_oid", "typemod", nullptr}, "(select format_pg_type(type_name) from duckdb_types() t where t.type_oid=type_oid) || case when typemod>0 then concat('(', typemod/1000, ',', typemod%1000, ')') else '' end"}, {"pg_catalog", "pg_has_role", {"user", "role", "privilege", nullptr}, "true"}, //boolean //does user have privilege for role @@ -12473,6 +14375,7 @@ static DefaultMacro internal_macros[] = { {DEFAULT_SCHEMA, "generate_subscripts", {"arr", "dim", nullptr}, "unnest(generate_series(1, array_length(arr, dim)))"}, {DEFAULT_SCHEMA, "fdiv", {"x", "y", nullptr}, "floor(x/y)"}, {DEFAULT_SCHEMA, "fmod", {"x", "y", nullptr}, "(x-y*floor(x/y))"}, + {DEFAULT_SCHEMA, "count_if", {"l", nullptr}, "sum(if(l, 1, 0))"}, // algebraic list aggregates {DEFAULT_SCHEMA, "list_avg", {"l", nullptr}, "list_aggr(l, 'avg')"}, @@ -12525,7 +14428,7 @@ unique_ptr DefaultFunctionGenerator::CreateInternalTableMacroIn bind_info->temporary = true; bind_info->internal = true; bind_info->type = function->type == MacroType::TABLE_MACRO ? CatalogType::TABLE_MACRO_ENTRY : CatalogType::MACRO_ENTRY; - bind_info->function = move(function); + bind_info->function = std::move(function); return bind_info; } @@ -12535,8 +14438,8 @@ unique_ptr DefaultFunctionGenerator::CreateInternalMacroInfo(De auto expressions = Parser::ParseExpressionList(default_macro.macro); D_ASSERT(expressions.size() == 1); - auto result = make_unique(move(expressions[0])); - return CreateInternalTableMacroInfo(default_macro, move(result)); + auto result = make_unique(std::move(expressions[0])); + return CreateInternalTableMacroInfo(default_macro, std::move(result)); } unique_ptr DefaultFunctionGenerator::CreateInternalTableMacroInfo(DefaultMacro &default_macro) { @@ -12546,8 +14449,8 @@ unique_ptr DefaultFunctionGenerator::CreateInternalTableMacroIn D_ASSERT(parser.statements[0]->type == StatementType::SELECT_STATEMENT); auto &select = (SelectStatement &) *parser.statements[0]; - auto result = make_unique(move(select.node)); - return CreateInternalTableMacroInfo(default_macro, move(result)); + auto result = make_unique(std::move(select.node)); + return CreateInternalTableMacroInfo(default_macro, std::move(result)); } static unique_ptr GetDefaultFunction(const string &input_schema, const string &input_name) { @@ -12612,7 +14515,7 @@ DefaultSchemaGenerator::DefaultSchemaGenerator(Catalog &catalog) : DefaultGenera unique_ptr DefaultSchemaGenerator::CreateDefaultEntry(ClientContext &context, const string &entry_name) { if (GetDefaultSchema(entry_name)) { - return make_unique_base(&catalog, StringUtil::Lower(entry_name), true); + return make_unique_base(&catalog, StringUtil::Lower(entry_name), true); } return nullptr; } @@ -12656,6 +14559,8 @@ static DefaultType internal_types[] = {{"int", LogicalTypeId::INTEGER}, {"blob", LogicalTypeId::BLOB}, {"varbinary", LogicalTypeId::BLOB}, {"binary", LogicalTypeId::BLOB}, + {"bit", LogicalTypeId::BIT}, + {"bitstring", LogicalTypeId::BIT}, {"int8", LogicalTypeId::BIGINT}, {"bigint", LogicalTypeId::BIGINT}, {"int64", LogicalTypeId::BIGINT}, @@ -12706,7 +14611,7 @@ static DefaultType internal_types[] = {{"int", LogicalTypeId::INTEGER}, {"union", LogicalTypeId::UNION}, {"timestamptz", LogicalTypeId::TIMESTAMP_TZ}, {"timetz", LogicalTypeId::TIME_TZ}, - {"json", LogicalTypeId::JSON}, + {"enum", LogicalTypeId::ENUM}, {"null", LogicalTypeId::SQLNULL}, {nullptr, LogicalTypeId::INVALID}}; @@ -12758,8 +14663,6 @@ vector DefaultTypeGenerator::GetDefaultEntries() { - - namespace duckdb { struct DefaultView { @@ -12769,13 +14672,14 @@ struct DefaultView { }; static DefaultView internal_views[] = { - {DEFAULT_SCHEMA, "pragma_database_list", "SELECT * FROM pragma_database_list()"}, + {DEFAULT_SCHEMA, "pragma_database_list", "SELECT database_oid AS seq, database_name AS name, path AS file FROM duckdb_databases() WHERE NOT internal ORDER BY 1"}, {DEFAULT_SCHEMA, "sqlite_master", "select 'table' \"type\", table_name \"name\", table_name \"tbl_name\", 0 rootpage, sql from duckdb_tables union all select 'view' \"type\", view_name \"name\", view_name \"tbl_name\", 0 rootpage, sql from duckdb_views union all select 'index' \"type\", index_name \"name\", table_name \"tbl_name\", 0 rootpage, sql from duckdb_indexes;"}, {DEFAULT_SCHEMA, "sqlite_schema", "SELECT * FROM sqlite_master"}, {DEFAULT_SCHEMA, "sqlite_temp_master", "SELECT * FROM sqlite_master"}, {DEFAULT_SCHEMA, "sqlite_temp_schema", "SELECT * FROM sqlite_master"}, {DEFAULT_SCHEMA, "duckdb_constraints", "SELECT * FROM duckdb_constraints()"}, {DEFAULT_SCHEMA, "duckdb_columns", "SELECT * FROM duckdb_columns() WHERE NOT internal"}, + {DEFAULT_SCHEMA, "duckdb_databases", "SELECT * FROM duckdb_databases() WHERE NOT internal"}, {DEFAULT_SCHEMA, "duckdb_indexes", "SELECT * FROM duckdb_indexes()"}, {DEFAULT_SCHEMA, "duckdb_schemas", "SELECT * FROM duckdb_schemas() WHERE NOT internal"}, {DEFAULT_SCHEMA, "duckdb_tables", "SELECT * FROM duckdb_tables() WHERE NOT internal"}, @@ -12786,43 +14690,39 @@ static DefaultView internal_views[] = { {"pg_catalog", "pg_attrdef", "SELECT column_index oid, table_oid adrelid, column_index adnum, column_default adbin from duckdb_columns() where column_default is not null;"}, {"pg_catalog", "pg_class", "SELECT table_oid oid, table_name relname, schema_oid relnamespace, 0 reltype, 0 reloftype, 0 relowner, 0 relam, 0 relfilenode, 0 reltablespace, 0 relpages, estimated_size::real reltuples, 0 relallvisible, 0 reltoastrelid, 0 reltoastidxid, index_count > 0 relhasindex, false relisshared, case when temporary then 't' else 'p' end relpersistence, 'r' relkind, column_count relnatts, check_constraint_count relchecks, false relhasoids, has_primary_key relhaspkey, false relhasrules, false relhastriggers, false relhassubclass, false relrowsecurity, true relispopulated, NULL relreplident, false relispartition, 0 relrewrite, 0 relfrozenxid, NULL relminmxid, NULL relacl, NULL reloptions, NULL relpartbound FROM duckdb_tables() UNION ALL SELECT view_oid oid, view_name relname, schema_oid relnamespace, 0 reltype, 0 reloftype, 0 relowner, 0 relam, 0 relfilenode, 0 reltablespace, 0 relpages, 0 reltuples, 0 relallvisible, 0 reltoastrelid, 0 reltoastidxid, false relhasindex, false relisshared, case when temporary then 't' else 'p' end relpersistence, 'v' relkind, column_count relnatts, 0 relchecks, false relhasoids, false relhaspkey, false relhasrules, false relhastriggers, false relhassubclass, false relrowsecurity, true relispopulated, NULL relreplident, false relispartition, 0 relrewrite, 0 relfrozenxid, NULL relminmxid, NULL relacl, NULL reloptions, NULL relpartbound FROM duckdb_views() UNION ALL SELECT sequence_oid oid, sequence_name relname, schema_oid relnamespace, 0 reltype, 0 reloftype, 0 relowner, 0 relam, 0 relfilenode, 0 reltablespace, 0 relpages, 0 reltuples, 0 relallvisible, 0 reltoastrelid, 0 reltoastidxid, false relhasindex, false relisshared, case when temporary then 't' else 'p' end relpersistence, 'S' relkind, 0 relnatts, 0 relchecks, false relhasoids, false relhaspkey, false relhasrules, false relhastriggers, false relhassubclass, false relrowsecurity, true relispopulated, NULL relreplident, false relispartition, 0 relrewrite, 0 relfrozenxid, NULL relminmxid, NULL relacl, NULL reloptions, NULL relpartbound FROM duckdb_sequences() UNION ALL SELECT index_oid oid, index_name relname, schema_oid relnamespace, 0 reltype, 0 reloftype, 0 relowner, 0 relam, 0 relfilenode, 0 reltablespace, 0 relpages, 0 reltuples, 0 relallvisible, 0 reltoastrelid, 0 reltoastidxid, false relhasindex, false relisshared, 't' relpersistence, 'i' relkind, NULL relnatts, 0 relchecks, false relhasoids, false relhaspkey, false relhasrules, false relhastriggers, false relhassubclass, false relrowsecurity, true relispopulated, NULL relreplident, false relispartition, 0 relrewrite, 0 relfrozenxid, NULL relminmxid, NULL relacl, NULL reloptions, NULL relpartbound FROM duckdb_indexes()"}, {"pg_catalog", "pg_constraint", "SELECT table_oid*1000000+constraint_index oid, constraint_text conname, schema_oid connamespace, CASE constraint_type WHEN 'CHECK' then 'c' WHEN 'UNIQUE' then 'u' WHEN 'PRIMARY KEY' THEN 'p' WHEN 'FOREIGN KEY' THEN 'f' ELSE 'x' END contype, false condeferrable, false condeferred, true convalidated, table_oid conrelid, 0 contypid, 0 conindid, 0 conparentid, 0 confrelid, NULL confupdtype, NULL confdeltype, NULL confmatchtype, true conislocal, 0 coninhcount, false connoinherit, constraint_column_indexes conkey, NULL confkey, NULL conpfeqop, NULL conppeqop, NULL conffeqop, NULL conexclop, expression conbin FROM duckdb_constraints()"}, - {"pg_catalog", "pg_database", "SELECT 0 oid, 'main' datname"}, + {"pg_catalog", "pg_database", "SELECT database_oid oid, database_name datname FROM duckdb_databases()"}, {"pg_catalog", "pg_depend", "SELECT * FROM duckdb_dependencies()"}, {"pg_catalog", "pg_description", "SELECT NULL objoid, NULL classoid, NULL objsubid, NULL description WHERE 1=0"}, - {"pg_catalog", "pg_enum", "SELECT NULL oid, NULL enumtypid, NULL enumsortorder, NULL enumlabel WHERE 1=0"}, + {"pg_catalog", "pg_enum", "SELECT NULL oid, a.type_oid enumtypid, list_position(b.labels, a.elabel) enumsortorder, a.elabel enumlabel FROM (SELECT UNNEST(labels) elabel, type_oid FROM duckdb_types() WHERE logical_type='ENUM') a JOIN duckdb_types() b ON a.type_oid=b.type_oid;"}, {"pg_catalog", "pg_index", "SELECT index_oid indexrelid, table_oid indrelid, 0 indnatts, 0 indnkeyatts, is_unique indisunique, is_primary indisprimary, false indisexclusion, true indimmediate, false indisclustered, true indisvalid, false indcheckxmin, true indisready, true indislive, false indisreplident, NULL::INT[] indkey, NULL::OID[] indcollation, NULL::OID[] indclass, NULL::INT[] indoption, expressions indexprs, NULL indpred FROM duckdb_indexes()"}, {"pg_catalog", "pg_indexes", "SELECT schema_name schemaname, table_name tablename, index_name indexname, NULL \"tablespace\", sql indexdef FROM duckdb_indexes()"}, {"pg_catalog", "pg_namespace", "SELECT oid, schema_name nspname, 0 nspowner, NULL nspacl FROM duckdb_schemas()"}, - {"pg_catalog", "pg_proc", "SELECT f.function_oid oid, function_name proname, s.oid pronamespace FROM duckdb_functions() f LEFT JOIN duckdb_schemas() s USING (schema_name)"}, + {"pg_catalog", "pg_proc", "SELECT f.function_oid oid, function_name proname, s.oid pronamespace, varargs provariadic, function_type = 'aggregate' proisagg, function_type = 'table' proretset, return_type prorettype, parameter_types proargtypes, parameters proargnames FROM duckdb_functions() f LEFT JOIN duckdb_schemas() s USING (database_name, schema_name)"}, {"pg_catalog", "pg_sequence", "SELECT sequence_oid seqrelid, 0 seqtypid, start_value seqstart, increment_by seqincrement, max_value seqmax, min_value seqmin, 0 seqcache, cycle seqcycle FROM duckdb_sequences()"}, {"pg_catalog", "pg_sequences", "SELECT schema_name schemaname, sequence_name sequencename, 'duckdb' sequenceowner, 0 data_type, start_value, min_value, max_value, increment_by, cycle, 0 cache_size, last_value FROM duckdb_sequences()"}, {"pg_catalog", "pg_settings", "SELECT name, value setting, description short_desc, CASE WHEN input_type = 'VARCHAR' THEN 'string' WHEN input_type = 'BOOLEAN' THEN 'bool' WHEN input_type IN ('BIGINT', 'UBIGINT') THEN 'integer' ELSE input_type END vartype FROM duckdb_settings()"}, {"pg_catalog", "pg_tables", "SELECT schema_name schemaname, table_name tablename, 'duckdb' tableowner, NULL \"tablespace\", index_count > 0 hasindexes, false hasrules, false hastriggers FROM duckdb_tables()"}, {"pg_catalog", "pg_tablespace", "SELECT 0 oid, 'pg_default' spcname, 0 spcowner, NULL spcacl, NULL spcoptions"}, - {"pg_catalog", "pg_type", "SELECT type_oid oid, format_pg_type(type_name) typname, schema_oid typnamespace, 0 typowner, type_size typlen, false typbyval, 'b' typtype, CASE WHEN type_category='NUMERIC' THEN 'N' WHEN type_category='STRING' THEN 'S' WHEN type_category='DATETIME' THEN 'D' WHEN type_category='BOOLEAN' THEN 'B' WHEN type_category='COMPOSITE' THEN 'C' WHEN type_category='USER' THEN 'U' ELSE 'X' END typcategory, false typispreferred, true typisdefined, NULL typdelim, NULL typrelid, NULL typsubscript, NULL typelem, NULL typarray, NULL typinput, NULL typoutput, NULL typreceive, NULL typsend, NULL typmodin, NULL typmodout, NULL typanalyze, 'd' typalign, 'p' typstorage, NULL typnotnull, NULL typbasetype, NULL typtypmod, NULL typndims, NULL typcollation, NULL typdefaultbin, NULL typdefault, NULL typacl FROM duckdb_types();"}, + {"pg_catalog", "pg_type", "SELECT type_oid oid, format_pg_type(type_name) typname, schema_oid typnamespace, 0 typowner, type_size typlen, false typbyval, CASE WHEN logical_type='ENUM' THEN 'e' else 'b' end typtype, CASE WHEN type_category='NUMERIC' THEN 'N' WHEN type_category='STRING' THEN 'S' WHEN type_category='DATETIME' THEN 'D' WHEN type_category='BOOLEAN' THEN 'B' WHEN type_category='COMPOSITE' THEN 'C' WHEN type_category='USER' THEN 'U' ELSE 'X' END typcategory, false typispreferred, true typisdefined, NULL typdelim, NULL typrelid, NULL typsubscript, NULL typelem, NULL typarray, NULL typinput, NULL typoutput, NULL typreceive, NULL typsend, NULL typmodin, NULL typmodout, NULL typanalyze, 'd' typalign, 'p' typstorage, NULL typnotnull, NULL typbasetype, NULL typtypmod, NULL typndims, NULL typcollation, NULL typdefaultbin, NULL typdefault, NULL typacl FROM duckdb_types() WHERE type_size IS NOT NULL;"}, {"pg_catalog", "pg_views", "SELECT schema_name schemaname, view_name viewname, 'duckdb' viewowner, sql definition FROM duckdb_views()"}, - {"information_schema", "columns", "SELECT NULL table_catalog, schema_name table_schema, table_name, column_name, column_index ordinal_position, column_default, CASE WHEN is_nullable THEN 'YES' ELSE 'NO' END is_nullable, data_type, character_maximum_length, NULL character_octet_length, numeric_precision, numeric_precision_radix, numeric_scale, NULL datetime_precision, NULL interval_type, NULL interval_precision, NULL character_set_catalog, NULL character_set_schema, NULL character_set_name, NULL collation_catalog, NULL collation_schema, NULL collation_name, NULL domain_catalog, NULL domain_schema, NULL domain_name, NULL udt_catalog, NULL udt_schema, NULL udt_name, NULL scope_catalog, NULL scope_schema, NULL scope_name, NULL maximum_cardinality, NULL dtd_identifier, NULL is_self_referencing, NULL is_identity, NULL identity_generation, NULL identity_start, NULL identity_increment, NULL identity_maximum, NULL identity_minimum, NULL identity_cycle, NULL is_generated, NULL generation_expression, NULL is_updatable FROM duckdb_columns;"}, - {"information_schema", "schemata", "SELECT NULL catalog_name, schema_name, 'duckdb' schema_owner, NULL default_character_set_catalog, NULL default_character_set_schema, NULL default_character_set_name, sql sql_path FROM duckdb_schemas()"}, - {"information_schema", "tables", "SELECT NULL table_catalog, schema_name table_schema, table_name, CASE WHEN temporary THEN 'LOCAL TEMPORARY' ELSE 'BASE TABLE' END table_type, NULL self_referencing_column_name, NULL reference_generation, NULL user_defined_type_catalog, NULL user_defined_type_schema, NULL user_defined_type_name, 'YES' is_insertable_into, 'NO' is_typed, CASE WHEN temporary THEN 'PRESERVE' ELSE NULL END commit_action FROM duckdb_tables() UNION ALL SELECT NULL table_catalog, schema_name table_schema, view_name table_name, 'VIEW' table_type, NULL self_referencing_column_name, NULL reference_generation, NULL user_defined_type_catalog, NULL user_defined_type_schema, NULL user_defined_type_name, 'NO' is_insertable_into, 'NO' is_typed, NULL commit_action FROM duckdb_views;"}, + {"information_schema", "columns", "SELECT database_name table_catalog, schema_name table_schema, table_name, column_name, column_index ordinal_position, column_default, CASE WHEN is_nullable THEN 'YES' ELSE 'NO' END is_nullable, data_type, character_maximum_length, NULL character_octet_length, numeric_precision, numeric_precision_radix, numeric_scale, NULL datetime_precision, NULL interval_type, NULL interval_precision, NULL character_set_catalog, NULL character_set_schema, NULL character_set_name, NULL collation_catalog, NULL collation_schema, NULL collation_name, NULL domain_catalog, NULL domain_schema, NULL domain_name, NULL udt_catalog, NULL udt_schema, NULL udt_name, NULL scope_catalog, NULL scope_schema, NULL scope_name, NULL maximum_cardinality, NULL dtd_identifier, NULL is_self_referencing, NULL is_identity, NULL identity_generation, NULL identity_start, NULL identity_increment, NULL identity_maximum, NULL identity_minimum, NULL identity_cycle, NULL is_generated, NULL generation_expression, NULL is_updatable FROM duckdb_columns;"}, + {"information_schema", "schemata", "SELECT database_name catalog_name, schema_name, 'duckdb' schema_owner, NULL default_character_set_catalog, NULL default_character_set_schema, NULL default_character_set_name, sql sql_path FROM duckdb_schemas()"}, + {"information_schema", "tables", "SELECT database_name table_catalog, schema_name table_schema, table_name, CASE WHEN temporary THEN 'LOCAL TEMPORARY' ELSE 'BASE TABLE' END table_type, NULL self_referencing_column_name, NULL reference_generation, NULL user_defined_type_catalog, NULL user_defined_type_schema, NULL user_defined_type_name, 'YES' is_insertable_into, 'NO' is_typed, CASE WHEN temporary THEN 'PRESERVE' ELSE NULL END commit_action FROM duckdb_tables() UNION ALL SELECT NULL table_catalog, schema_name table_schema, view_name table_name, 'VIEW' table_type, NULL self_referencing_column_name, NULL reference_generation, NULL user_defined_type_catalog, NULL user_defined_type_schema, NULL user_defined_type_name, 'NO' is_insertable_into, 'NO' is_typed, NULL commit_action FROM duckdb_views;"}, {nullptr, nullptr, nullptr}}; -static unique_ptr GetDefaultView(const string &input_schema, const string &input_name) { +static unique_ptr GetDefaultView(ClientContext &context, const string &input_schema, const string &input_name) { auto schema = StringUtil::Lower(input_schema); auto name = StringUtil::Lower(input_name); for (idx_t index = 0; internal_views[index].name != nullptr; index++) { if (internal_views[index].schema == schema && internal_views[index].name == name) { auto result = make_unique(); result->schema = schema; + result->view_name = name; result->sql = internal_views[index].sql; - - Parser parser; - parser.ParseQuery(internal_views[index].sql); - D_ASSERT(parser.statements.size() == 1 && parser.statements[0]->type == StatementType::SELECT_STATEMENT); - result->query = unique_ptr_cast(move(parser.statements[0])); result->temporary = true; result->internal = true; - result->view_name = name; - return result; + + return CreateViewInfo::FromSelect(context, std::move(result)); } } return nullptr; @@ -12833,11 +14733,8 @@ DefaultViewGenerator::DefaultViewGenerator(Catalog &catalog, SchemaCatalogEntry } unique_ptr DefaultViewGenerator::CreateDefaultEntry(ClientContext &context, const string &entry_name) { - auto info = GetDefaultView(schema->name, entry_name); + auto info = GetDefaultView(context, schema->name, entry_name); if (info) { - auto binder = Binder::CreateBinder(context); - binder->BindCreateViewInfo(*info); - return make_unique_base(&catalog, schema, info.get()); } return nullptr; @@ -12857,6 +14754,20 @@ vector DefaultViewGenerator::GetDefaultEntries() { +namespace duckdb { + +void DependencyList::AddDependency(CatalogEntry *entry) { + if (entry->internal) { + return; + } + set.insert(entry); +} + +} // namespace duckdb + + + + @@ -12866,18 +14777,23 @@ vector DefaultViewGenerator::GetDefaultEntries() { namespace duckdb { -DependencyManager::DependencyManager(Catalog &catalog) : catalog(catalog) { +DependencyManager::DependencyManager(DuckCatalog &catalog) : catalog(catalog) { } -void DependencyManager::AddObject(ClientContext &context, CatalogEntry *object, - unordered_set &dependencies) { +void DependencyManager::AddObject(CatalogTransaction transaction, CatalogEntry *object, DependencyList &dependencies) { // check for each object in the sources if they were not deleted yet - for (auto &dependency : dependencies) { + for (auto &dependency : dependencies.set) { CatalogEntry *catalog_entry; + if (dependency->catalog != object->catalog) { + throw DependencyException( + "Error adding dependency for object \"%s\" - dependency \"%s\" is in catalog " + "\"%s\", which does not match the catalog \"%s\".\nCross catalog dependencies are not supported.", + object->name, dependency->name, dependency->catalog->GetName(), object->catalog->GetName()); + } if (!dependency->set) { throw InternalException("Dependency has no set"); } - if (!dependency->set->GetEntryInternal(context, dependency->name, nullptr, catalog_entry)) { + if (!dependency->set->GetEntryInternal(transaction, dependency->name, nullptr, catalog_entry)) { throw InternalException("Dependency has already been deleted?"); } } @@ -12885,15 +14801,15 @@ void DependencyManager::AddObject(ClientContext &context, CatalogEntry *object, auto dependency_type = object->type == CatalogType::INDEX_ENTRY ? DependencyType::DEPENDENCY_AUTOMATIC : DependencyType::DEPENDENCY_REGULAR; // add the object to the dependents_map of each object that it depends on - for (auto &dependency : dependencies) { + for (auto &dependency : dependencies.set) { dependents_map[dependency].insert(Dependency(object, dependency_type)); } // create the dependents map for this object: it starts out empty dependents_map[object] = dependency_set_t(); - dependencies_map[object] = dependencies; + dependencies_map[object] = dependencies.set; } -void DependencyManager::DropObject(ClientContext &context, CatalogEntry *object, bool cascade) { +void DependencyManager::DropObject(CatalogTransaction transaction, CatalogEntry *object, bool cascade) { D_ASSERT(dependents_map.find(object) != dependents_map.end()); // first check the objects that depend on this object @@ -12901,13 +14817,13 @@ void DependencyManager::DropObject(ClientContext &context, CatalogEntry *object, for (auto &dep : dependent_objects) { // look up the entry in the catalog set auto &catalog_set = *dep.entry->set; - auto mapping_value = catalog_set.GetMapping(context, dep.entry->name, true /* get_latest */); + auto mapping_value = catalog_set.GetMapping(transaction, dep.entry->name, true /* get_latest */); if (mapping_value == nullptr) { continue; } CatalogEntry *dependency_entry; - if (!catalog_set.GetEntryInternal(context, mapping_value->index, dependency_entry)) { + if (!catalog_set.GetEntryInternal(transaction, mapping_value->index, dependency_entry)) { // the dependent object was already deleted, no conflict continue; } @@ -12915,7 +14831,7 @@ void DependencyManager::DropObject(ClientContext &context, CatalogEntry *object, if (cascade || dep.dependency_type == DependencyType::DEPENDENCY_AUTOMATIC || dep.dependency_type == DependencyType::DEPENDENCY_OWNS) { // cascade: drop the dependent object - catalog_set.DropEntryInternal(context, mapping_value->index.Copy(), *dependency_entry, cascade); + catalog_set.DropEntryInternal(transaction, mapping_value->index.Copy(), *dependency_entry, cascade); } else { // no cascade and there are objects that depend on this object: throw error throw DependencyException("Cannot drop entry \"%s\" because there are entries that " @@ -12925,7 +14841,7 @@ void DependencyManager::DropObject(ClientContext &context, CatalogEntry *object, } } -void DependencyManager::AlterObject(ClientContext &context, CatalogEntry *old_obj, CatalogEntry *new_obj) { +void DependencyManager::AlterObject(CatalogTransaction transaction, CatalogEntry *old_obj, CatalogEntry *new_obj) { D_ASSERT(dependents_map.find(old_obj) != dependents_map.end()); D_ASSERT(dependencies_map.find(old_obj) != dependencies_map.end()); @@ -12936,7 +14852,7 @@ void DependencyManager::AlterObject(ClientContext &context, CatalogEntry *old_ob // look up the entry in the catalog set auto &catalog_set = *dep.entry->set; CatalogEntry *dependency_entry; - if (!catalog_set.GetEntryInternal(context, dep.entry->name, nullptr, dependency_entry)) { + if (!catalog_set.GetEntryInternal(transaction, dep.entry->name, nullptr, dependency_entry)) { // the dependent object was already deleted, no conflict continue; } @@ -12959,7 +14875,7 @@ void DependencyManager::AlterObject(ClientContext &context, CatalogEntry *old_ob auto user_type = (TypeCatalogEntry *)dependency; auto table = (TableCatalogEntry *)new_obj; bool deleted_dependency = true; - for (auto &column : table->columns.Logical()) { + for (auto &column : table->GetColumns().Logical()) { if (column.Type() == user_type->user_type) { deleted_dependency = false; break; @@ -12981,7 +14897,7 @@ void DependencyManager::AlterObject(ClientContext &context, CatalogEntry *old_ob vector to_add; if (new_obj->type == CatalogType::TABLE_ENTRY) { auto table = (TableCatalogEntry *)new_obj; - for (auto &column : table->columns.Logical()) { + for (auto &column : table->GetColumns().Logical()) { auto user_type_catalog = LogicalType::GetCatalog(column.Type()); if (user_type_catalog) { to_add.push_back(user_type_catalog); @@ -13030,7 +14946,7 @@ void DependencyManager::EraseObjectInternal(CatalogEntry *object) { } void DependencyManager::Scan(const std::function &callback) { - lock_guard write_lock(catalog.write_lock); + lock_guard write_lock(catalog.GetWriteLock()); for (auto &entry : dependents_map) { for (auto &dependent : entry.second) { callback(entry.first, dependent.entry, dependent.dependency_type); @@ -13038,9 +14954,9 @@ void DependencyManager::Scan(const std::function write_lock(catalog.write_lock); + lock_guard write_lock(catalog.GetWriteLock()); // If the owner is already owned by something else, throw an error for (auto &dep : dependents_map[owner]) { @@ -13077,61 +14993,198 @@ void DependencyManager::AddOwnership(ClientContext &context, CatalogEntry *owner -#include -#ifdef DUCKDB_DEBUG_ALLOCATION +namespace duckdb { -#include -#endif +DuckCatalog::DuckCatalog(AttachedDatabase &db) + : Catalog(db), dependency_manager(make_unique(*this)), + schemas(make_unique(*this, make_unique(*this))) { +} -#if defined(BUILD_JEMALLOC_EXTENSION) && !defined(WIN32) -#include "jemalloc-extension.hpp" -#endif +DuckCatalog::~DuckCatalog() { +} -namespace duckdb { +void DuckCatalog::Initialize(bool load_builtin) { + // first initialize the base system catalogs + // these are never written to the WAL + // we start these at 1 because deleted entries default to 0 + CatalogTransaction data(GetDatabase(), 1, 1); -AllocatedData::AllocatedData() : allocator(nullptr), pointer(nullptr), allocated_size(0) { -} + // create the default schema + CreateSchemaInfo info; + info.schema = DEFAULT_SCHEMA; + info.internal = true; + CreateSchema(data, &info); -AllocatedData::AllocatedData(Allocator &allocator, data_ptr_t pointer, idx_t allocated_size) - : allocator(&allocator), pointer(pointer), allocated_size(allocated_size) { - if (!pointer) { - throw InternalException("AllocatedData object constructed with nullptr"); + if (load_builtin) { + // initialize default functions + BuiltinFunctions builtin(data, *this); + builtin.Initialize(); } -} -AllocatedData::~AllocatedData() { - Reset(); + + Verify(); } -AllocatedData::AllocatedData(AllocatedData &&other) noexcept - : allocator(other.allocator), pointer(nullptr), allocated_size(0) { - std::swap(pointer, other.pointer); - std::swap(allocated_size, other.allocated_size); +bool DuckCatalog::IsDuckCatalog() { + return true; } -AllocatedData &AllocatedData::operator=(AllocatedData &&other) noexcept { - std::swap(allocator, other.allocator); - std::swap(pointer, other.pointer); - std::swap(allocated_size, other.allocated_size); - return *this; +//===--------------------------------------------------------------------===// +// Schema +//===--------------------------------------------------------------------===// +CatalogEntry *DuckCatalog::CreateSchema(CatalogTransaction transaction, CreateSchemaInfo *info) { + D_ASSERT(!info->schema.empty()); + DependencyList dependencies; + auto entry = make_unique(this, info->schema, info->internal); + auto result = entry.get(); + if (!schemas->CreateEntry(transaction, info->schema, std::move(entry), dependencies)) { + if (info->on_conflict == OnCreateConflict::ERROR_ON_CONFLICT) { + throw CatalogException("Schema with name %s already exists!", info->schema); + } else { + D_ASSERT(info->on_conflict == OnCreateConflict::IGNORE_ON_CONFLICT); + } + return nullptr; + } + return result; } -void AllocatedData::Reset() { - if (!pointer) { - return; +void DuckCatalog::DropSchema(ClientContext &context, DropInfo *info) { + D_ASSERT(!info->name.empty()); + ModifyCatalog(); + if (!schemas->DropEntry(GetCatalogTransaction(context), info->name, info->cascade)) { + if (!info->if_exists) { + throw CatalogException("Schema with name \"%s\" does not exist!", info->name); + } } - D_ASSERT(allocator); - allocator->FreeData(pointer, allocated_size); - allocated_size = 0; - pointer = nullptr; } -//===--------------------------------------------------------------------===// -// Debug Info -//===--------------------------------------------------------------------===// +void DuckCatalog::ScanSchemas(ClientContext &context, std::function callback) { + schemas->Scan(GetCatalogTransaction(context), [&](CatalogEntry *entry) { callback(entry); }); +} + +void DuckCatalog::ScanSchemas(std::function callback) { + schemas->Scan([&](CatalogEntry *entry) { callback(entry); }); +} + +SchemaCatalogEntry *DuckCatalog::GetSchema(CatalogTransaction transaction, const string &schema_name, bool if_exists, + QueryErrorContext error_context) { + D_ASSERT(!schema_name.empty()); + auto entry = schemas->GetEntry(transaction, schema_name); + if (!entry && !if_exists) { + throw CatalogException(error_context.FormatError("Schema with name %s does not exist!", schema_name)); + } + return (SchemaCatalogEntry *)entry; +} + +DatabaseSize DuckCatalog::GetDatabaseSize(ClientContext &context) { + return db.GetStorageManager().GetDatabaseSize(); +} + +bool DuckCatalog::InMemory() { + return db.GetStorageManager().InMemory(); +} + +string DuckCatalog::GetDBPath() { + return db.GetStorageManager().GetDBPath(); +} + +void DuckCatalog::Verify() { +#ifdef DEBUG + schemas->Verify(*this); +#endif +} + +} // namespace duckdb + + + + +namespace duckdb { + +string SimilarCatalogEntry::GetQualifiedName(bool qualify_catalog, bool qualify_schema) const { + D_ASSERT(Found()); + string result; + if (qualify_catalog) { + result += schema->catalog->GetName(); + } + if (qualify_schema) { + if (!result.empty()) { + result += "."; + } + result += schema->name; + } + if (!result.empty()) { + result += "."; + } + result += name; + return result; +} + +} // namespace duckdb + + + + + + +#include + +#ifdef DUCKDB_DEBUG_ALLOCATION + + + + +#include +#endif + +#if defined(BUILD_JEMALLOC_EXTENSION) && !defined(WIN32) +#include "jemalloc-extension.hpp" +#endif + +namespace duckdb { + +AllocatedData::AllocatedData() : allocator(nullptr), pointer(nullptr), allocated_size(0) { +} + +AllocatedData::AllocatedData(Allocator &allocator, data_ptr_t pointer, idx_t allocated_size) + : allocator(&allocator), pointer(pointer), allocated_size(allocated_size) { + if (!pointer) { + throw InternalException("AllocatedData object constructed with nullptr"); + } +} +AllocatedData::~AllocatedData() { + Reset(); +} + +AllocatedData::AllocatedData(AllocatedData &&other) noexcept + : allocator(other.allocator), pointer(nullptr), allocated_size(0) { + std::swap(pointer, other.pointer); + std::swap(allocated_size, other.allocated_size); +} + +AllocatedData &AllocatedData::operator=(AllocatedData &&other) noexcept { + std::swap(allocator, other.allocator); + std::swap(pointer, other.pointer); + std::swap(allocated_size, other.allocated_size); + return *this; +} + +void AllocatedData::Reset() { + if (!pointer) { + return; + } + D_ASSERT(allocator); + allocator->FreeData(pointer, allocated_size); + allocated_size = 0; + pointer = nullptr; +} + +//===--------------------------------------------------------------------===// +// Debug Info +//===--------------------------------------------------------------------===// struct AllocatorDebugInfo { #ifdef DEBUG AllocatorDebugInfo(); @@ -13175,7 +15228,7 @@ Allocator::Allocator() Allocator::Allocator(allocate_function_ptr_t allocate_function_p, free_function_ptr_t free_function_p, reallocate_function_ptr_t reallocate_function_p, unique_ptr private_data_p) : allocate_function(allocate_function_p), free_function(free_function_p), - reallocate_function(reallocate_function_p), private_data(move(private_data_p)) { + reallocate_function(reallocate_function_p), private_data(std::move(private_data_p)) { D_ASSERT(allocate_function); D_ASSERT(free_function); D_ASSERT(reallocate_function); @@ -13203,7 +15256,7 @@ data_ptr_t Allocator::AllocateData(idx_t size) { private_data->debug_info->AllocateData(result, size); #endif if (!result) { - throw std::bad_alloc(); + throw OutOfMemoryException("Failed to allocate block of %llu bytes", size); } return result; } @@ -13236,7 +15289,7 @@ data_ptr_t Allocator::ReallocateData(data_ptr_t pointer, idx_t old_size, idx_t s private_data->debug_info->ReallocateData(pointer, new_pointer, old_size, size); #endif if (!new_pointer) { - throw std::bad_alloc(); + throw OutOfMemoryException("Failed to re-allocate block of %llu bytes", size); } return new_pointer; } @@ -13495,10 +15548,10 @@ struct ArrowAppendData { static unique_ptr InitializeArrowChild(const LogicalType &type, idx_t capacity); static ArrowArray *FinalizeArrowChild(const LogicalType &type, ArrowAppendData &append_data); -ArrowAppender::ArrowAppender(vector types_p, idx_t initial_capacity) : types(move(types_p)) { +ArrowAppender::ArrowAppender(vector types_p, idx_t initial_capacity) : types(std::move(types_p)) { for (auto &type : types) { auto entry = InitializeArrowChild(type, initial_capacity); - root_data.push_back(move(entry)); + root_data.push_back(std::move(entry)); } } @@ -13642,7 +15695,7 @@ struct ArrowEnumData : public ArrowScalarBaseData { // construct the enum child data auto enum_data = InitializeArrowChild(LogicalType::VARCHAR, EnumType::GetSize(type)); enum_data->append_vector(*enum_data, EnumType::GetValuesInsertOrder(type), EnumType::GetSize(type)); - result.child_data.push_back(move(enum_data)); + result.child_data.push_back(std::move(enum_data)); } static void Finalize(ArrowAppendData &append_data, const LogicalType &type, ArrowArray *result) { @@ -13791,7 +15844,7 @@ struct ArrowStructData { auto &children = StructType::GetChildTypes(type); for (auto &child : children) { auto child_buffer = InitializeArrowChild(child.second, capacity); - result.child_data.push_back(move(child_buffer)); + result.child_data.push_back(std::move(child_buffer)); } } @@ -13864,7 +15917,7 @@ struct ArrowListData { auto &child_type = ListType::GetChildType(type); result.main_buffer.reserve((capacity + 1) * sizeof(uint32_t)); auto child_buffer = InitializeArrowChild(child_type, capacity); - result.child_data.push_back(move(child_buffer)); + result.child_data.push_back(std::move(child_buffer)); } static void Append(ArrowAppendData &append_data, Vector &input, idx_t size) { @@ -13913,7 +15966,7 @@ struct ArrowMapData { internal_struct->child_data.push_back(InitializeArrowChild(key_type, capacity)); internal_struct->child_data.push_back(InitializeArrowChild(value_type, capacity)); - result.child_data.push_back(move(internal_struct)); + result.child_data.push_back(std::move(internal_struct)); } static void Append(ArrowAppendData &append_data, Vector &input, idx_t size) { @@ -13921,33 +15974,21 @@ struct ArrowMapData { input.ToUnifiedFormat(size, format); AppendValidity(append_data, format, size); - // maps exist as a struct of two lists, e.g. STRUCT(key VARCHAR[], value VARCHAR[]) - // since both lists are the same, arrow tries to be smart by storing the offsets only once - // we can append the offsets from any of the two children - auto &children = StructVector::GetEntries(input); - - UnifiedVectorFormat child_format; - children[0]->ToUnifiedFormat(size, child_format); vector child_indices; - AppendListOffsets(append_data, child_format, size, child_indices); + AppendListOffsets(append_data, format, size, child_indices); - // now we can append the children to the lists - auto &struct_entries = StructVector::GetEntries(input); - D_ASSERT(struct_entries.size() == 2); SelectionVector child_sel(child_indices.data()); - auto &key_vector = ListVector::GetEntry(*struct_entries[0]); - auto &value_vector = ListVector::GetEntry(*struct_entries[1]); + auto &key_vector = MapVector::GetKeys(input); + auto &value_vector = MapVector::GetValues(input); auto list_size = child_indices.size(); key_vector.Slice(child_sel, list_size); value_vector.Slice(child_sel, list_size); - // perform the append auto &struct_data = *append_data.child_data[0]; auto &key_data = *struct_data.child_data[0]; auto &value_data = *struct_data.child_data[1]; key_data.append_vector(key_data, key_vector, list_size); value_data.append_vector(value_data, value_vector, list_size); - append_data.row_count += size; struct_data.row_count += size; } @@ -14071,7 +16112,7 @@ static void InitializeFunctionPointers(ArrowAppendData &append_data, const Logic break; case LogicalTypeId::VARCHAR: case LogicalTypeId::BLOB: - case LogicalTypeId::JSON: + case LogicalTypeId::BIT: InitializeFunctionPointers>(append_data); break; case LogicalTypeId::UUID: @@ -14149,7 +16190,7 @@ ArrowArray *FinalizeArrowChild(const LogicalType &type, ArrowAppendData &append_ append_data.finalize(append_data, type, result.get()); } - append_data.array = move(result); + append_data.array = std::move(result); return append_data.array.get(); } @@ -14171,7 +16212,7 @@ ArrowArray ArrowAppender::Finalize() { result.offset = 0; result.null_count = 0; // needs to be 0 result.dictionary = nullptr; - root_holder->child_data = move(root_data); + root_holder->child_data = std::move(root_data); for (idx_t i = 0; i < root_holder->child_data.size(); i++) { root_holder->child_pointers[i] = FinalizeArrowChild(types[i], *root_holder->child_data[i]); @@ -14185,6 +16226,63 @@ ArrowArray ArrowAppender::Finalize() { } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/types/bit.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +//! The Bit class is a static class that holds helper functions for the BIT type. +class Bit { +public: + //! Returns the number of bits in the bit string + DUCKDB_API static idx_t BitLength(string_t bits); + //! Returns the number of set bits in the bit string + DUCKDB_API static idx_t BitCount(string_t bits); + //! Returns the number of bytes in the bit string + DUCKDB_API static idx_t OctetLength(string_t bits); + //! Extracts the nth bit from bit string; the first (leftmost) bit is indexed 0 + DUCKDB_API static idx_t GetBit(string_t bit_string, idx_t n); + //! Sets the nth bit in bit string to newvalue; the first (leftmost) bit is indexed 0 + DUCKDB_API static void SetBit(const string_t &bit_string, idx_t n, idx_t new_value, string_t &result); + //! Returns first starting index of the specified substring within bits, or zero if it's not present. + DUCKDB_API static idx_t BitPosition(string_t substring, string_t bits); + //! Converts bits to a string, writing the output to the designated output string. + //! The string needs to have space for at least GetStringSize(bits) bytes. + DUCKDB_API static void ToString(string_t bits, char *output); + DUCKDB_API static string ToString(string_t str); + //! Returns the bit size of a string -> bit conversion + DUCKDB_API static bool TryGetBitStringSize(string_t str, idx_t &result_size, string *error_message); + //! Convert a string to a bit. This function should ONLY be called after calling GetBitSize, since it does NOT + //! perform data validation. + DUCKDB_API static void ToBit(string_t str, data_ptr_t output); + DUCKDB_API static string ToBit(string_t str); + DUCKDB_API static void SetEmptyBitString(string_t &target, string_t &input); + + DUCKDB_API static void RightShift(const string_t &bit_string, const idx_t &shif, string_t &result); + DUCKDB_API static void LeftShift(const string_t &bit_string, const idx_t &shift, string_t &result); + DUCKDB_API static void BitwiseAnd(const string_t &rhs, const string_t &lhs, string_t &result); + DUCKDB_API static void BitwiseOr(const string_t &rhs, const string_t &lhs, string_t &result); + DUCKDB_API static void BitwiseXor(const string_t &rhs, const string_t &lhs, string_t &result); + DUCKDB_API static void BitwiseNot(const string_t &rhs, string_t &result); + +private: + //! Returns the amount of padded zeroes to fill up to a full byte. This information is stored in the first byte of + //! the bitstring. + DUCKDB_API static idx_t GetPadding(const string_t &bit_string); + DUCKDB_API static idx_t GetBitSize(string_t str); + DUCKDB_API static void SetBit(string_t &bit_string, idx_t n, idx_t new_value); +}; +} // namespace duckdb @@ -14314,11 +16412,7 @@ void SetArrowMapFormat(DuckDBArrowSchemaHolder &root_holder, ArrowSchema &child, InitializeChild(root_holder.nested_children.back()[0]); child.children = &root_holder.nested_children_ptr.back()[0]; child.children[0]->name = "entries"; - child_list_t struct_child_types; - struct_child_types.push_back(std::make_pair("key", ListType::GetChildType(StructType::GetChildType(type, 0)))); - struct_child_types.push_back(std::make_pair("value", ListType::GetChildType(StructType::GetChildType(type, 1)))); - auto struct_type = LogicalType::STRUCT(move(struct_child_types)); - SetArrowFormat(root_holder, *child.children[0], struct_type, config_timezone); + SetArrowFormat(root_holder, **child.children, ListType::GetChildType(type), config_timezone); } void SetArrowFormat(DuckDBArrowSchemaHolder &root_holder, ArrowSchema &child, const LogicalType &type, @@ -14361,7 +16455,6 @@ void SetArrowFormat(DuckDBArrowSchemaHolder &root_holder, ArrowSchema &child, co child.format = "g"; break; case LogicalTypeId::UUID: - case LogicalTypeId::JSON: case LogicalTypeId::VARCHAR: child.format = "u"; break; @@ -14382,7 +16475,7 @@ void SetArrowFormat(DuckDBArrowSchemaHolder &root_holder, ArrowSchema &child, co format_ptr[i] = format[i]; } format_ptr[format.size()] = '\0'; - root_holder.owned_type_names.push_back(move(format_ptr)); + root_holder.owned_type_names.push_back(std::move(format_ptr)); child.format = root_holder.owned_type_names.back().get(); break; } @@ -14407,7 +16500,7 @@ void SetArrowFormat(DuckDBArrowSchemaHolder &root_holder, ArrowSchema &child, co format_ptr[i] = format[i]; } format_ptr[format.size()] = '\0'; - root_holder.owned_type_names.push_back(move(format_ptr)); + root_holder.owned_type_names.push_back(std::move(format_ptr)); child.format = root_holder.owned_type_names.back().get(); break; } @@ -14415,7 +16508,8 @@ void SetArrowFormat(DuckDBArrowSchemaHolder &root_holder, ArrowSchema &child, co child.format = "n"; break; } - case LogicalTypeId::BLOB: { + case LogicalTypeId::BLOB: + case LogicalTypeId::BIT: { child.format = "z"; break; } @@ -14454,7 +16548,7 @@ void SetArrowFormat(DuckDBArrowSchemaHolder &root_holder, ArrowSchema &child, co name_ptr[i] = struct_col_name[i]; } name_ptr[struct_col_name.size()] = '\0'; - root_holder.owned_type_names.push_back(move(name_ptr)); + root_holder.owned_type_names.push_back(std::move(name_ptr)); child.children[type_idx]->name = root_holder.owned_type_names.back().get(); SetArrowFormat(root_holder, *child.children[type_idx], child_types[type_idx].second, config_timezone); @@ -14724,7 +16818,7 @@ const char *ResultArrowArrayStreamWrapper::MyStreamGetLastError(struct ArrowArra } ResultArrowArrayStreamWrapper::ResultArrowArrayStreamWrapper(unique_ptr result_p, idx_t batch_size_p) - : result(move(result_p)) { + : result(std::move(result_p)) { //! We first initialize the private data of the stream stream.private_data = this; //! Ceil Approx_Batch_Size/STANDARD_VECTOR_SIZE @@ -14800,7 +16894,7 @@ void DuckDBAssertInternal(bool condition, const char *condition_name, const char //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/box_renderer.hpp +// duckdb/common/bind_helpers.hpp // // //===----------------------------------------------------------------------===// @@ -14809,10 +16903,86 @@ void DuckDBAssertInternal(bool condition, const char *condition_name, const char +namespace duckdb { + +class Value; + +Value ConvertVectorToValue(vector set); +vector ParseColumnList(const vector &set, vector &names, const string &option_name); +vector ParseColumnList(const Value &value, vector &names, const string &option_name); + +} // namespace duckdb + + + + + + + +namespace duckdb { + +Value ConvertVectorToValue(vector set) { + if (set.empty()) { + return Value::EMPTYLIST(LogicalType::BOOLEAN); + } + return Value::LIST(std::move(set)); +} + +vector ParseColumnList(const vector &set, vector &names, const string &loption) { + vector result; + + if (set.empty()) { + throw BinderException("\"%s\" expects a column list or * as parameter", loption); + } + // list of options: parse the list + case_insensitive_map_t option_map; + for (idx_t i = 0; i < set.size(); i++) { + option_map[set[i].ToString()] = false; + } + result.resize(names.size(), false); + for (idx_t i = 0; i < names.size(); i++) { + auto entry = option_map.find(names[i]); + if (entry != option_map.end()) { + result[i] = true; + entry->second = true; + } + } + for (auto &entry : option_map) { + if (!entry.second) { + throw BinderException("\"%s\" expected to find %s, but it was not found in the table", loption, + entry.first.c_str()); + } + } + return result; +} + +vector ParseColumnList(const Value &value, vector &names, const string &loption) { + vector result; + + // Only accept a list of arguments + if (value.type().id() != LogicalTypeId::LIST) { + // Support a single argument if it's '*' + if (value.type().id() == LogicalTypeId::VARCHAR && value.GetValue() == "*") { + result.resize(names.size(), true); + return result; + } + throw BinderException("\"%s\" expects a column list or * as parameter", loption); + } + auto &children = ListValue::GetChildren(value); + // accept '*' as single argument + if (children.size() == 1 && children[0].type().id() == LogicalTypeId::VARCHAR && + children[0].GetValue() == "*") { + result.resize(names.size(), true); + return result; + } + return ParseColumnList(children, names, loption); +} + +} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/query_profiler.hpp +// duckdb/common/box_renderer.hpp // // //===----------------------------------------------------------------------===// @@ -14824,7 +16994,7 @@ void DuckDBAssertInternal(bool condition, const char *condition_name, const char //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/profiler.hpp +// duckdb/main/query_profiler.hpp // // //===----------------------------------------------------------------------===// @@ -14834,44 +17004,6 @@ void DuckDBAssertInternal(bool condition, const char *condition_name, const char -namespace duckdb { - -//! The profiler can be used to measure elapsed time -template -class BaseProfiler { -public: - //! Starts the timer - void Start() { - finished = false; - start = Tick(); - } - //! Finishes timing - void End() { - end = Tick(); - finished = true; - } - - //! Returns the elapsed time in seconds. If End() has been called, returns - //! the total elapsed time. Otherwise returns how far along the timer is - //! right now. - double Elapsed() const { - auto _end = finished ? end : Tick(); - return std::chrono::duration_cast>(_end - start).count(); - } - -private: - time_point Tick() const { - return T::now(); - } - time_point start; - time_point end; - bool finished = false; -}; - -using Profiler = BaseProfiler; - -} // namespace duckdb - @@ -15093,10 +17225,12 @@ class QueryProfiler { //! The QueryProfilerHistory can be used to access the profiler of previous queries class QueryProfilerHistory { private: + static constexpr uint64_t DEFAULT_SIZE = 20; + //! Previous Query profilers deque>> prev_profilers; //! Previous Query profilers size - uint64_t prev_profilers_size = 20; + uint64_t prev_profilers_size = DEFAULT_SIZE; public: deque>> &GetPrevProfilers() { @@ -15116,6 +17250,9 @@ class QueryProfilerHistory { void SetProfilerHistorySize(uint64_t size) { this->prev_profilers_size = size; } + void ResetProfilerHistorySize() { + this->prev_profilers_size = DEFAULT_SIZE; + } }; } // namespace duckdb @@ -15145,7 +17282,11 @@ enum class ValueRenderAlignment { LEFT, MIDDLE, RIGHT }; struct BoxRendererConfig { // a max_width of 0 means we default to the terminal width idx_t max_width = 0; + // the maximum amount of rows to render idx_t max_rows = 20; + // the limit that is applied prior to rendering + // if we are rendering exactly "limit" rows then a question mark is rendered instead + idx_t limit = 0; // the max col width determines the maximum size of a single column // note that the max col width is only used if the result does not fit on the screen idx_t max_col_width = 20; @@ -15288,7 +17429,7 @@ namespace duckdb { const idx_t BoxRenderer::SPLIT_COLUMN = idx_t(-1); -BoxRenderer::BoxRenderer(BoxRendererConfig config_p) : config(move(config_p)) { +BoxRenderer::BoxRenderer(BoxRendererConfig config_p) : config(std::move(config_p)) { } string BoxRenderer::ToString(ClientContext &context, const vector &names, const ColumnDataCollection &result) { @@ -15869,10 +18010,18 @@ void BoxRenderer::Render(ClientContext &context, const vector &names, co bottom_rows = rows_to_render - top_rows; } auto row_count_str = to_string(row_count) + " rows"; + bool has_limited_rows = config.limit > 0 && row_count == config.limit; + if (has_limited_rows) { + row_count_str = "? rows"; + } string shown_str; bool has_hidden_rows = top_rows < row_count; if (has_hidden_rows) { - shown_str = "(" + to_string(top_rows + bottom_rows) + " shown)"; + shown_str = "("; + if (has_limited_rows) { + shown_str += ">" + to_string(config.limit - 1) + " rows, "; + } + shown_str += to_string(top_rows + bottom_rows) + " shown)"; } auto minimum_row_length = MaxValue(row_count_str.size(), shown_str.size()) + 4; @@ -15924,7 +18073,7 @@ void BoxRenderer::Render(ClientContext &context, const vector &names, co column_count--; column_count_str += " (" + to_string(column_count) + " shown)"; } - RenderRowCount(move(row_count_str), move(shown_str), column_count_str, boundaries, has_hidden_rows, + RenderRowCount(std::move(row_count_str), std::move(shown_str), column_count_str, boundaries, has_hidden_rows, has_hidden_columns, total_length, row_count, column_count, minimum_row_length, ss); } @@ -16059,11 +18208,11 @@ StreamWrapper::~StreamWrapper() { } CompressedFile::CompressedFile(CompressedFileSystem &fs, unique_ptr child_handle_p, const string &path) - : FileHandle(fs, path), compressed_fs(fs), child_handle(move(child_handle_p)) { + : FileHandle(fs, path), compressed_fs(fs), child_handle(std::move(child_handle_p)) { } CompressedFile::~CompressedFile() { - Close(); + CompressedFile::Close(); } void CompressedFile::Initialize(bool write) { @@ -16212,6 +18361,14 @@ uint64_t NextPowerOfTwo(uint64_t v) { return v; } +bool IsInvalidSchema(const string &str) { + return str.empty(); +} + +bool IsInvalidCatalog(const string &str) { + return str.empty(); +} + bool IsRowIdColumnId(column_t column_id) { return column_id == COLUMN_IDENTIFIER_ROW_ID; } @@ -16627,6 +18784,8 @@ string CatalogTypeToString(CatalogType type) { return "Table"; case CatalogType::SCHEMA_ENTRY: return "Schema"; + case CatalogType::DATABASE_ENTRY: + return "Database"; case CatalogType::TABLE_FUNCTION_ENTRY: return "Table Function"; case CatalogType::SCALAR_FUNCTION_ENTRY: @@ -16666,6 +18825,17 @@ string CatalogTypeToString(CatalogType type) { namespace duckdb { // LCOV_EXCL_START + +vector ListCompressionTypes(void) { + vector compression_types; + uint8_t amount_of_compression_options = (uint8_t)CompressionType::COMPRESSION_COUNT; + compression_types.reserve(amount_of_compression_options); + for (uint8_t i = 0; i < amount_of_compression_options; i++) { + compression_types.push_back(CompressionTypeToString((CompressionType)i)); + } + return compression_types; +} + CompressionType CompressionTypeFromString(const string &str) { auto compression = StringUtil::Lower(str); if (compression == "uncompressed") { @@ -16691,6 +18861,8 @@ CompressionType CompressionTypeFromString(const string &str) { string CompressionTypeToString(CompressionType type) { switch (type) { + case CompressionType::COMPRESSION_AUTO: + return "Auto"; case CompressionType::COMPRESSION_UNCOMPRESSED: return "Uncompressed"; case CompressionType::COMPRESSION_CONSTANT: @@ -16851,6 +19023,8 @@ string ExpressionTypeToString(ExpressionType type) { return "COLLATE"; case ExpressionType::POSITIONAL_REFERENCE: return "POSITIONAL_REFERENCE"; + case ExpressionType::BOUND_LAMBDA_REF: + return "BOUND_LAMBDA_REF"; case ExpressionType::LAMBDA: return "LAMBDA"; case ExpressionType::ARROW: @@ -17152,6 +19326,8 @@ string LogicalOperatorToString(LogicalOperatorType type) { return "JOIN"; case LogicalOperatorType::LOGICAL_CROSS_PRODUCT: return "CROSS_PRODUCT"; + case LogicalOperatorType::LOGICAL_POSITIONAL_JOIN: + return "POSITIONAL_JOIN"; case LogicalOperatorType::LOGICAL_UNION: return "UNION"; case LogicalOperatorType::LOGICAL_EXCEPT: @@ -17198,6 +19374,8 @@ string LogicalOperatorToString(LogicalOperatorType type) { return "CREATE_VIEW"; case LogicalOperatorType::LOGICAL_CREATE_SCHEMA: return "CREATE_SCHEMA"; + case LogicalOperatorType::LOGICAL_ATTACH: + return "ATTACH"; case LogicalOperatorType::LOGICAL_DROP: return "DROP"; case LogicalOperatorType::LOGICAL_PRAGMA: @@ -17208,6 +19386,8 @@ string LogicalOperatorToString(LogicalOperatorType type) { return "EXPORT"; case LogicalOperatorType::LOGICAL_SET: return "SET"; + case LogicalOperatorType::LOGICAL_RESET: + return "RESET"; case LogicalOperatorType::LOGICAL_LOAD: return "LOAD"; case LogicalOperatorType::LOGICAL_INVALID: @@ -17240,6 +19420,7 @@ static DefaultOptimizerType internal_optimizer_types[] = { {"in_clause", OptimizerType::IN_CLAUSE}, {"join_order", OptimizerType::JOIN_ORDER}, {"deliminator", OptimizerType::DELIMINATOR}, + {"unnest_rewriter", OptimizerType::UNNEST_REWRITER}, {"unused_columns", OptimizerType::UNUSED_COLUMNS}, {"statistics_propagation", OptimizerType::STATISTICS_PROPAGATION}, {"common_subexpressions", OptimizerType::COMMON_SUBEXPRESSIONS}, @@ -17340,6 +19521,10 @@ string PhysicalOperatorToString(PhysicalOperatorType type) { return "IE_JOIN"; case PhysicalOperatorType::CROSS_PRODUCT: return "CROSS_PRODUCT"; + case PhysicalOperatorType::POSITIONAL_JOIN: + return "POSITIONAL_JOIN"; + case PhysicalOperatorType::POSITIONAL_SCAN: + return "POSITIONAL_SCAN"; case PhysicalOperatorType::UNION: return "UNION"; case PhysicalOperatorType::INSERT: @@ -17396,14 +19581,20 @@ string PhysicalOperatorToString(PhysicalOperatorType type) { return "EXPORT"; case PhysicalOperatorType::SET: return "SET"; + case PhysicalOperatorType::RESET: + return "RESET"; case PhysicalOperatorType::LOAD: return "LOAD"; case PhysicalOperatorType::INOUT_FUNCTION: return "INOUT_FUNCTION"; case PhysicalOperatorType::CREATE_TYPE: return "CREATE_TYPE"; + case PhysicalOperatorType::ATTACH: + return "ATTACH"; case PhysicalOperatorType::RESULT_COLLECTOR: return "RESULT_COLLECTOR"; + case PhysicalOperatorType::EXTENSION: + return "EXTENSION"; case PhysicalOperatorType::INVALID: break; } @@ -17457,6 +19648,8 @@ string RelationTypeToString(RelationType type) { return "UPDATE_RELATION"; case RelationType::WRITE_CSV_RELATION: return "WRITE_CSV_RELATION"; + case RelationType::WRITE_PARQUET_RELATION: + return "WRITE_PARQUET_RELATION"; case RelationType::READ_CSV_RELATION: return "READ_CSV_RELATION"; case RelationType::SUBQUERY_RELATION: @@ -17532,6 +19725,8 @@ string StatementTypeToString(StatementType type) { return "EXTENSION"; case StatementType::LOGICAL_PLAN_STATEMENT: return "LOGICAL_PLAN"; + case StatementType::ATTACH_STATEMENT: + return "ATTACH"; case StatementType::INVALID_STATEMENT: break; } @@ -18304,16 +20499,18 @@ template class basic_string_view { using string_view = basic_string_view; using wstring_view = basic_string_view; -#ifndef __cpp_char8_t // A UTF-8 code unit type. -enum char8_t : unsigned char {}; +#if FMT_HAS_FEATURE(__cpp_char8_t) +typedef char8_t fmt_char8_t; +#else +typedef unsigned char fmt_char8_t; #endif /** Specifies if ``T`` is a character type. Can be specialized by users. */ template struct is_char : std::false_type {}; template <> struct is_char : std::true_type {}; template <> struct is_char : std::true_type {}; -template <> struct is_char : std::true_type {}; +template <> struct is_char : std::true_type {}; template <> struct is_char : std::true_type {}; template <> struct is_char : std::true_type {}; @@ -19847,8 +22044,8 @@ inline size_t count_code_points(basic_string_view s) { } // Counts the number of code points in a UTF-8 string. -inline size_t count_code_points(basic_string_view s) { - const char8_t* data = s.data(); +inline size_t count_code_points(basic_string_view s) { + const fmt_char8_t* data = s.data(); size_t num_code_points = 0; for (size_t i = 0, size = s.size(); i != size; ++i) { if ((data[i] & 0xc0) != 0x80) ++num_code_points; @@ -19863,8 +22060,8 @@ inline size_t code_point_index(basic_string_view s, size_t n) { } // Calculates the index of the nth code point in a UTF-8 string. -inline size_t code_point_index(basic_string_view s, size_t n) { - const char8_t* data = s.data(); +inline size_t code_point_index(basic_string_view s, size_t n) { + const fmt_char8_t* data = s.data(); size_t num_code_points = 0; for (size_t i = 0, size = s.size(); i != size; ++i) { if ((data[i] & 0xc0) != 0x80 && ++num_code_points > n) { @@ -19874,13 +22071,13 @@ inline size_t code_point_index(basic_string_view s, size_t n) { return s.size(); } -inline char8_t to_char8_t(char c) { return static_cast(c); } +inline fmt_char8_t to_fmt_char8_t(char c) { return static_cast(c); } template using needs_conversion = bool_constant< std::is_same::value_type, char>::value && - std::is_same::value>; + std::is_same::value>; template ::value)> @@ -19891,7 +22088,7 @@ OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) { template ::value)> OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) { - return std::transform(begin, end, it, to_char8_t); + return std::transform(begin, end, it, to_fmt_char8_t); } #ifndef FMT_USE_GRISU @@ -19925,12 +22122,12 @@ class buffer_range : public internal::output_range< }; // A UTF-8 string view. -class u8string_view : public basic_string_view { +class u8string_view : public basic_string_view { public: u8string_view(const char* s) - : basic_string_view(reinterpret_cast(s)) {} + : basic_string_view(reinterpret_cast(s)) {} u8string_view(const char* s, size_t count) FMT_NOEXCEPT - : basic_string_view(reinterpret_cast(s), count) { + : basic_string_view(reinterpret_cast(s), count) { } }; @@ -23614,7 +25811,7 @@ ExceptionFormatValue::ExceptionFormatValue(hugeint_t huge_val) : type(ExceptionFormatValueType::FORMAT_VALUE_TYPE_STRING), str_val(Hugeint::ToString(huge_val)) { } ExceptionFormatValue::ExceptionFormatValue(string str_val) - : type(ExceptionFormatValueType::FORMAT_VALUE_TYPE_STRING), str_val(move(str_val)) { + : type(ExceptionFormatValueType::FORMAT_VALUE_TYPE_STRING), str_val(std::move(str_val)) { } template <> @@ -23636,7 +25833,7 @@ ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(double value) { } template <> ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(string value) { - return ExceptionFormatValue(move(value)); + return ExceptionFormatValue(std::move(value)); } template <> ExceptionFormatValue ExceptionFormatValue::CreateFormatValue(const char *value) { @@ -23792,8 +25989,6 @@ void FileBuffer::Init() { size = 0; internal_buffer = nullptr; internal_size = 0; - malloced_buffer = nullptr; - malloced_size = 0; } FileBuffer::FileBuffer(FileBuffer &source, FileBufferType type_p) : allocator(source.allocator), type(type_p) { @@ -23802,31 +25997,29 @@ FileBuffer::FileBuffer(FileBuffer &source, FileBufferType type_p) : allocator(so size = source.size; internal_buffer = source.internal_buffer; internal_size = source.internal_size; - malloced_buffer = source.malloced_buffer; - malloced_size = source.malloced_size; source.Init(); } FileBuffer::~FileBuffer() { - if (!malloced_buffer) { + if (!internal_buffer) { return; } - allocator.FreeData(malloced_buffer, malloced_size); + allocator.FreeData(internal_buffer, internal_size); } void FileBuffer::ReallocBuffer(size_t new_size) { - if (malloced_buffer) { - malloced_buffer = allocator.ReallocateData(malloced_buffer, malloced_size, new_size); + data_ptr_t new_buffer; + if (internal_buffer) { + new_buffer = allocator.ReallocateData(internal_buffer, internal_size, new_size); } else { - malloced_buffer = allocator.AllocateData(new_size); + new_buffer = allocator.AllocateData(new_size); } - if (!malloced_buffer) { + if (!new_buffer) { throw std::bad_alloc(); } - malloced_size = new_size; - internal_buffer = malloced_buffer; - internal_size = malloced_size; + internal_buffer = new_buffer; + internal_size = new_size; // Caller must update these. buffer = nullptr; size = 0; @@ -23861,32 +26054,11 @@ void FileBuffer::Read(FileHandle &handle, uint64_t location) { handle.Read(internal_buffer, internal_size, location); } -void FileBuffer::ReadAndChecksum(FileHandle &handle, uint64_t location) { - // read the buffer from disk - Read(handle, location); - // compute the checksum - auto stored_checksum = Load(internal_buffer); - uint64_t computed_checksum = Checksum(buffer, size); - // verify the checksum - if (stored_checksum != computed_checksum) { - throw IOException("Corrupt database file: computed checksum %llu does not match stored checksum %llu in block", - computed_checksum, stored_checksum); - } -} - void FileBuffer::Write(FileHandle &handle, uint64_t location) { D_ASSERT(type != FileBufferType::TINY_BUFFER); handle.Write(internal_buffer, internal_size, location); } -void FileBuffer::ChecksumAndWrite(FileHandle &handle, uint64_t location) { - // compute the checksum and write it to the start of the buffer (if not temp buffer) - uint64_t checksum = Checksum(buffer, size); - Store(checksum, internal_buffer); - // now write the buffer - Write(handle, location); -} - void FileBuffer::Clear() { memset(internal_buffer, 0, internal_size); } @@ -23908,6 +26080,7 @@ void FileBuffer::Clear() { + namespace duckdb { class ClientContext; @@ -23919,8 +26092,11 @@ class FileOpener { virtual ~FileOpener() {}; virtual bool TryGetCurrentSetting(const string &key, Value &result) = 0; + virtual ClientContext *TryGetClientContext() = 0; - static FileOpener *Get(ClientContext &context); + DUCKDB_API static FileOpener *Get(ClientContext &context); + DUCKDB_API static ClientContext *TryGetClientContext(FileOpener *opener); + DUCKDB_API static bool TryGetCurrentSetting(FileOpener *opener, const string &key, Value &result); }; } // namespace duckdb @@ -23929,7 +26105,7 @@ class FileOpener { -#ifdef _WIN32 +#if defined(_WIN32) #ifndef NOMINMAX #define NOMINMAX @@ -24728,6 +26904,7 @@ UTF8PROC_DLLEXPORT utf8proc_uint8_t *utf8proc_NFKC_Casefold(const utf8proc_uint8 // LICENSE_CHANGE_END + namespace re2 { class RE2; } @@ -24863,6 +27040,10 @@ struct ReplaceFun { static void RegisterFunction(BuiltinFunctions &set); }; +struct TranslateFun { + static void RegisterFunction(BuiltinFunctions &set); +}; + struct RpadFun { static void RegisterFunction(BuiltinFunctions &set); }; @@ -24884,6 +27065,10 @@ struct ContainsFun { idx_t needle_size); }; +struct StartsWithFun { + static void RegisterFunction(BuiltinFunctions &set); +}; + struct UnicodeFun { static void RegisterFunction(BuiltinFunctions &set); }; @@ -24892,6 +27077,10 @@ struct StringSplitFun { static void RegisterFunction(BuiltinFunctions &set); }; +struct BarFun { + static void RegisterFunction(BuiltinFunctions &set); +}; + struct ASCII { static void RegisterFunction(BuiltinFunctions &set); }; @@ -24950,7 +27139,7 @@ FileSystem::~FileSystem() { } FileSystem &FileSystem::GetFileSystem(ClientContext &context) { - return *context.db->config.file_system; + return FileSystem::GetFileSystem(*context.db); } FileOpener *FileSystem::GetFileOpener(ClientContext &context) { @@ -25083,7 +27272,7 @@ string FileSystem::ConvertSeparators(const string &path) { return result; } -string FileSystem::ExtractBaseName(const string &path) { +string FileSystem::ExtractName(const string &path) { if (path.empty()) { return string(); } @@ -25091,7 +27280,14 @@ string FileSystem::ExtractBaseName(const string &path) { auto sep = PathSeparator(); auto splits = StringUtil::Split(normalized_path, sep); D_ASSERT(!splits.empty()); - auto vec = StringUtil::Split(splits.back(), "."); + return splits.back(); +} + +string FileSystem::ExtractBaseName(const string &path) { + if (path.empty()) { + return string(); + } + auto vec = StringUtil::Split(ExtractName(path), "."); D_ASSERT(!vec.empty()); return vec[0]; } @@ -25150,6 +27346,14 @@ int64_t FileSystem::Write(FileHandle &handle, void *buffer, int64_t nr_bytes) { throw NotImplementedException("%s: Write is not implemented!", GetName()); } +string FileSystem::GetFileExtension(FileHandle &handle) { + auto dot_location = handle.path.rfind('.'); + if (dot_location != std::string::npos) { + return handle.path.substr(dot_location + 1, std::string::npos); + } + return string(); +} + int64_t FileSystem::GetFileSize(FileHandle &handle) { throw NotImplementedException("%s: GetFileSize is not implemented!", GetName()); } @@ -25178,7 +27382,8 @@ void FileSystem::RemoveDirectory(const string &directory) { throw NotImplementedException("%s: RemoveDirectory is not implemented!", GetName()); } -bool FileSystem::ListFiles(const string &directory, const std::function &callback) { +bool FileSystem::ListFiles(const string &directory, const std::function &callback, + FileOpener *opener) { throw NotImplementedException("%s: ListFiles is not implemented!", GetName()); } @@ -25218,6 +27423,14 @@ void FileSystem::RegisterSubSystem(FileCompressionType compression_type, unique_ throw NotImplementedException("%s: Can't register a sub system on a non-virtual file system", GetName()); } +void FileSystem::UnregisterSubSystem(const string &name) { + throw NotImplementedException("%s: Can't unregister a sub system on a non-virtual file system", GetName()); +} + +vector FileSystem::ListSubSystems() { + throw NotImplementedException("%s: Can't list sub systems on a non-virtual file system", GetName()); +} + bool FileSystem::CanHandleFile(const string &fpath) { throw NotImplementedException("%s: CanHandleFile is not implemented!", GetName()); } @@ -25247,7 +27460,7 @@ bool FileSystem::OnDiskFile(FileHandle &handle) { } // LCOV_EXCL_STOP -FileHandle::FileHandle(FileSystem &file_system, string path_p) : file_system(file_system), path(move(path_p)) { +FileHandle::FileHandle(FileSystem &file_system, string path_p) : file_system(file_system), path(std::move(path_p)) { } FileHandle::~FileHandle() { @@ -25721,7 +27934,7 @@ struct UncompressedStringStorage { static unique_ptr StringInitAppend(ColumnSegment &segment) { auto &buffer_manager = BufferManager::GetBufferManager(segment.db); auto handle = buffer_manager.Pin(segment.block); - return make_unique(move(handle)); + return make_unique(std::move(handle)); } static idx_t StringAppend(CompressionAppendState &append_state, ColumnSegment &segment, SegmentStatistics &stats, @@ -26178,7 +28391,7 @@ namespace duckdb { class GZipFileSystem : public CompressedFileSystem { // 32 KB - static constexpr const idx_t BUFFER_SIZE = 1 << 15; + static constexpr const idx_t BUFFER_SIZE = 1u << 15; public: unique_ptr OpenCompressedFile(unique_ptr handle, bool write) override; @@ -27749,7 +29962,7 @@ MiniZStreamWrapper::~MiniZStreamWrapper() { return; } try { - Close(); + MiniZStreamWrapper::Close(); } catch (...) { } } @@ -27898,7 +30111,7 @@ void MiniZStreamWrapper::Close() { class GZipFile : public CompressedFile { public: GZipFile(unique_ptr child_handle_p, const string &path, bool write) - : CompressedFile(gzip_fs, move(child_handle_p), path) { + : CompressedFile(gzip_fs, std::move(child_handle_p), path) { Initialize(write); } @@ -27979,7 +30192,7 @@ string GZipFileSystem::UncompressGZIPString(const string &in) { unique_ptr GZipFileSystem::OpenCompressedFile(unique_ptr handle, bool write) { auto path = handle->path; - return make_unique(move(handle), path, write); + return make_unique(std::move(handle), path, write); } unique_ptr GZipFileSystem::CreateStream() { @@ -28008,21 +30221,17 @@ idx_t GZipFileSystem::OutBufferSize() { //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/statistics_propagator.hpp +// duckdb/common/types/partitioned_column_data.hpp // // //===----------------------------------------------------------------------===// - - - - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/planner/column_binding_map.hpp +// duckdb/common/types/column_data_allocator.hpp // // //===----------------------------------------------------------------------===// @@ -28031,125 +30240,185 @@ idx_t GZipFileSystem::OutBufferSize() { +namespace duckdb { +struct ChunkMetaData; +struct VectorMetaData; +struct BlockMetaData { + //! The underlying block handle + shared_ptr handle; + //! How much space is currently used within the block + uint32_t size; + //! How much space is available in the block + uint32_t capacity; -namespace duckdb { - -struct ColumnBindingHashFunction { - uint64_t operator()(const ColumnBinding &a) const { - return CombineHash(Hash(a.table_index), Hash(a.column_index)); - } + uint32_t Capacity(); }; -struct ColumnBindingEquality { - bool operator()(const ColumnBinding &a, const ColumnBinding &b) const { - return a == b; - } -}; +class ColumnDataAllocator { +public: + ColumnDataAllocator(Allocator &allocator); + ColumnDataAllocator(BufferManager &buffer_manager); + ColumnDataAllocator(ClientContext &context, ColumnDataAllocatorType allocator_type); + ColumnDataAllocator(ColumnDataAllocator &allocator); -template -using column_binding_map_t = unordered_map; + //! Returns an allocator object to allocate with. This returns the allocator in IN_MEMORY_ALLOCATOR, and a buffer + //! allocator in case of BUFFER_MANAGER_ALLOCATOR. + Allocator &GetAllocator(); + //! Returns the allocator type + ColumnDataAllocatorType GetType() { + return type; + } + void MakeShared() { + shared = true; + } + idx_t BlockCount() const { + return blocks.size(); + } -using column_binding_set_t = unordered_set; +public: + void AllocateData(idx_t size, uint32_t &block_id, uint32_t &offset, ChunkManagementState *chunk_state); -} // namespace duckdb + void Initialize(ColumnDataAllocator &other); + void InitializeChunkState(ChunkManagementState &state, ChunkMetaData &meta_data); + data_ptr_t GetDataPointer(ChunkManagementState &state, uint32_t block_id, uint32_t offset); + void UnswizzlePointers(ChunkManagementState &state, Vector &result, uint16_t v_offset, uint16_t count, + uint32_t block_id, uint32_t offset); + //! Deletes the block with the given id + void DeleteBlock(uint32_t block_id); +private: + void AllocateEmptyBlock(idx_t size); + BufferHandle AllocateBlock(idx_t size); + BufferHandle Pin(uint32_t block_id); + bool HasBlocks() const { + return !blocks.empty(); + } +private: + void AllocateBuffer(idx_t size, uint32_t &block_id, uint32_t &offset, ChunkManagementState *chunk_state); + void AllocateMemory(idx_t size, uint32_t &block_id, uint32_t &offset, ChunkManagementState *chunk_state); + void AssignPointer(uint32_t &block_id, uint32_t &offset, data_ptr_t pointer); -namespace duckdb { -class ClientContext; -class LogicalOperator; -class TableFilter; -struct BoundOrderByNode; +private: + ColumnDataAllocatorType type; + union { + //! The allocator object (if this is a IN_MEMORY_ALLOCATOR) + Allocator *allocator; + //! The buffer manager (if this is a BUFFER_MANAGER_ALLOCATOR) + BufferManager *buffer_manager; + } alloc; + //! The set of blocks used by the column data collection + vector blocks; + //! The set of allocated data + vector allocated_data; + //! Whether this ColumnDataAllocator is shared across ColumnDataCollections that allocate in parallel + bool shared = false; + //! Lock used in case this ColumnDataAllocator is shared across threads + mutex lock; +}; -class StatisticsPropagator { -public: - explicit StatisticsPropagator(ClientContext &context); +} // namespace duckdb - unique_ptr PropagateStatistics(unique_ptr &node_ptr); -private: - //! Propagate statistics through an operator - unique_ptr PropagateStatistics(LogicalOperator &node, unique_ptr *node_ptr); - unique_ptr PropagateStatistics(LogicalFilter &op, unique_ptr *node_ptr); - unique_ptr PropagateStatistics(LogicalGet &op, unique_ptr *node_ptr); - unique_ptr PropagateStatistics(LogicalJoin &op, unique_ptr *node_ptr); - unique_ptr PropagateStatistics(LogicalProjection &op, unique_ptr *node_ptr); - void PropagateStatistics(LogicalComparisonJoin &op, unique_ptr *node_ptr); - void PropagateStatistics(LogicalAnyJoin &op, unique_ptr *node_ptr); - unique_ptr PropagateStatistics(LogicalSetOperation &op, unique_ptr *node_ptr); - unique_ptr PropagateStatistics(LogicalAggregate &op, unique_ptr *node_ptr); - unique_ptr PropagateStatistics(LogicalCrossProduct &op, unique_ptr *node_ptr); - unique_ptr PropagateStatistics(LogicalLimit &op, unique_ptr *node_ptr); - unique_ptr PropagateStatistics(LogicalOrder &op, unique_ptr *node_ptr); - unique_ptr PropagateStatistics(LogicalWindow &op, unique_ptr *node_ptr); +namespace duckdb { - unique_ptr PropagateChildren(LogicalOperator &node, unique_ptr *node_ptr); +//! Local state for parallel partitioning +struct PartitionedColumnDataAppendState { +public: + PartitionedColumnDataAppendState() : partition_indices(LogicalType::UBIGINT) { + } - //! Return statistics from a constant value - unique_ptr StatisticsFromValue(const Value &input); - //! Run a comparison with two sets of statistics, returns if the comparison will always returns true/false or not - FilterPropagateResult PropagateComparison(BaseStatistics &left, BaseStatistics &right, ExpressionType comparison); +public: + Vector partition_indices; + SelectionVector partition_sel; + DataChunk slice_chunk; - //! Update filter statistics from a filter with a constant - void UpdateFilterStatistics(BaseStatistics &input, ExpressionType comparison_type, const Value &constant); - //! Update statistics from a filter between two stats - void UpdateFilterStatistics(BaseStatistics &lstats, BaseStatistics &rstats, ExpressionType comparison_type); - //! Update filter statistics from a generic comparison - void UpdateFilterStatistics(Expression &left, Expression &right, ExpressionType comparison_type); - //! Update filter statistics from an expression - void UpdateFilterStatistics(Expression &condition); - //! Set the statistics of a specific column binding to not contain null values - void SetStatisticsNotNull(ColumnBinding binding); + vector> partition_buffers; + vector> partition_append_states; +}; - //! Run a comparison between the statistics and the table filter; returns the prune result - FilterPropagateResult PropagateTableFilter(BaseStatistics &stats, TableFilter &filter); - //! Update filter statistics from a TableFilter - void UpdateFilterStatistics(BaseStatistics &input, TableFilter &filter); +enum class PartitionedColumnDataType : uint8_t { RADIX, HIVE, INVALID }; - //! Add cardinalities together (i.e. new max is stats.max + new_stats.max): used for union - void AddCardinalities(unique_ptr &stats, NodeStatistics &new_stats); - //! Multiply the cardinalities together (i.e. new max cardinality is stats.max * new_stats.max): used for - //! joins/cross products - void MultiplyCardinalities(unique_ptr &stats, NodeStatistics &new_stats); +//! Shared allocators for parallel partitioning +struct PartitionAllocators { + mutex lock; + vector> allocators; +}; - unique_ptr PropagateExpression(unique_ptr &expr); - unique_ptr PropagateExpression(Expression &expr, unique_ptr *expr_ptr); +//! PartitionedColumnData represents partitioned columnar data, which serves as an interface for different types of +//! partitioning, e.g., radix, hive +class PartitionedColumnData { +public: + unique_ptr CreateShared(); + virtual ~PartitionedColumnData(); - unique_ptr PropagateExpression(BoundAggregateExpression &expr, unique_ptr *expr_ptr); - unique_ptr PropagateExpression(BoundBetweenExpression &expr, unique_ptr *expr_ptr); - unique_ptr PropagateExpression(BoundCaseExpression &expr, unique_ptr *expr_ptr); - unique_ptr PropagateExpression(BoundCastExpression &expr, unique_ptr *expr_ptr); - unique_ptr PropagateExpression(BoundConjunctionExpression &expr, unique_ptr *expr_ptr); - unique_ptr PropagateExpression(BoundFunctionExpression &expr, unique_ptr *expr_ptr); - unique_ptr PropagateExpression(BoundComparisonExpression &expr, unique_ptr *expr_ptr); - unique_ptr PropagateExpression(BoundConstantExpression &expr, unique_ptr *expr_ptr); - unique_ptr PropagateExpression(BoundColumnRefExpression &expr, unique_ptr *expr_ptr); - unique_ptr PropagateExpression(BoundOperatorExpression &expr, unique_ptr *expr_ptr); +public: + //! Initializes a local state for parallel partitioning that can be merged into this PartitionedColumnData + void InitializeAppendState(PartitionedColumnDataAppendState &state) const; + //! Appends a DataChunk to this PartitionedColumnData + void Append(PartitionedColumnDataAppendState &state, DataChunk &input); + //! Flushes any remaining data in the append state into this PartitionedColumnData + void FlushAppendState(PartitionedColumnDataAppendState &state); + //! Combine another PartitionedColumnData into this PartitionedColumnData + void Combine(PartitionedColumnData &other); + //! Get the partitions in this PartitionedColumnData + vector> &GetPartitions(); - void PropagateAndCompress(unique_ptr &expr, unique_ptr &stats); +protected: + //===--------------------------------------------------------------------===// + // Partitioning type implementation interface + //===--------------------------------------------------------------------===// + //! Size of the buffers in the append states for this type of partitioning (default 128) + virtual idx_t BufferSize() const { + return MinValue(128, STANDARD_VECTOR_SIZE); + } + //! Initialize a PartitionedColumnDataAppendState for this type of partitioning (optional) + virtual void InitializeAppendStateInternal(PartitionedColumnDataAppendState &state) const { + } + //! Compute the partition indices for this type of partitioning for the input DataChunk and store them in the + //! `partition_data` of the local state. If this type creates partitions on the fly (for, e.g., hive), this + //! function is also in charge of creating new partitions and mapping the input data to a partition index + virtual void ComputePartitionIndices(PartitionedColumnDataAppendState &state, DataChunk &input) { + throw NotImplementedException("ComputePartitionIndices for this type of PartitionedColumnData"); + } - void ReplaceWithEmptyResult(unique_ptr &node); +protected: + //! PartitionedColumnData can only be instantiated by derived classes + PartitionedColumnData(PartitionedColumnDataType type, ClientContext &context, vector types); + PartitionedColumnData(const PartitionedColumnData &other); - bool ExpressionIsConstant(Expression &expr, const Value &val); - bool ExpressionIsConstantOrNull(Expression &expr, const Value &val); + //! If the buffer is half full, we append to the partition + inline idx_t HalfBufferSize() const { + D_ASSERT((BufferSize() & (BufferSize() - 1)) == 0); // BufferSize should be a power of two + return BufferSize() / 2; + } + //! Create a new shared allocator + void CreateAllocator(); + //! Create a collection for a specific a partition + unique_ptr CreatePartitionCollection(idx_t partition_index) const { + return make_unique(allocators->allocators[partition_index], types); + } + //! Create a DataChunk used for buffering appends to the partition + unique_ptr CreatePartitionBuffer() const; -private: +protected: + PartitionedColumnDataType type; ClientContext &context; - //! The map of ColumnBinding -> statistics for the various nodes - column_binding_map_t> statistics_map; - //! Node stats for the current node - unique_ptr node_stats; + vector types; + + mutex lock; + shared_ptr allocators; + vector> partitions; }; } // namespace duckdb - //===----------------------------------------------------------------------===// // DuckDB // @@ -28320,7 +30589,7 @@ class FilterCombiner { // void GenerateConjunctionFilter(BoundConjunctionExpression *conjunction, ConjunctionFilter *last_conj_filter) { // auto new_filter = NextConjunctionFilter(conjunction); // auto conj_filter_ptr = (ConjunctionFilter *)new_filter.get(); - // last_conj_filter->child_filters.push_back(move(new_filter)); + // last_conj_filter->child_filters.push_back(std::move(new_filter)); // last_conj_filter = conj_filter_ptr; // } // @@ -28333,9 +30602,9 @@ class FilterCombiner { // (comp_expr->left->type == ExpressionType::VALUE_CONSTANT) ? *comp_expr->left : *comp_expr->right; // auto const_value = ExpressionExecutor::EvaluateScalar(const_expr); // auto const_filter = make_unique(comp_expr->type, const_value); - // conj_filter->child_filters.push_back(move(const_filter)); + // conj_filter->child_filters.push_back(std::move(const_filter)); // } - // return move(conj_filter); + // return std::move(conj_filter); // } private: @@ -28370,6 +30639,150 @@ class FilterCombiner { } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/statistics_propagator.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/column_binding_map.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + + +namespace duckdb { + +struct ColumnBindingHashFunction { + uint64_t operator()(const ColumnBinding &a) const { + return CombineHash(Hash(a.table_index), Hash(a.column_index)); + } +}; + +struct ColumnBindingEquality { + bool operator()(const ColumnBinding &a, const ColumnBinding &b) const { + return a == b; + } +}; + +template +using column_binding_map_t = unordered_map; + +using column_binding_set_t = unordered_set; + +} // namespace duckdb + + + + + +namespace duckdb { +class ClientContext; +class LogicalOperator; +class TableFilter; +struct BoundOrderByNode; + +class StatisticsPropagator { +public: + explicit StatisticsPropagator(ClientContext &context); + + unique_ptr PropagateStatistics(unique_ptr &node_ptr); + +private: + //! Propagate statistics through an operator + unique_ptr PropagateStatistics(LogicalOperator &node, unique_ptr *node_ptr); + + unique_ptr PropagateStatistics(LogicalFilter &op, unique_ptr *node_ptr); + unique_ptr PropagateStatistics(LogicalGet &op, unique_ptr *node_ptr); + unique_ptr PropagateStatistics(LogicalJoin &op, unique_ptr *node_ptr); + unique_ptr PropagateStatistics(LogicalPositionalJoin &op, unique_ptr *node_ptr); + unique_ptr PropagateStatistics(LogicalProjection &op, unique_ptr *node_ptr); + void PropagateStatistics(LogicalComparisonJoin &op, unique_ptr *node_ptr); + void PropagateStatistics(LogicalAnyJoin &op, unique_ptr *node_ptr); + unique_ptr PropagateStatistics(LogicalSetOperation &op, unique_ptr *node_ptr); + unique_ptr PropagateStatistics(LogicalAggregate &op, unique_ptr *node_ptr); + unique_ptr PropagateStatistics(LogicalCrossProduct &op, unique_ptr *node_ptr); + unique_ptr PropagateStatistics(LogicalLimit &op, unique_ptr *node_ptr); + unique_ptr PropagateStatistics(LogicalOrder &op, unique_ptr *node_ptr); + unique_ptr PropagateStatistics(LogicalWindow &op, unique_ptr *node_ptr); + + unique_ptr PropagateChildren(LogicalOperator &node, unique_ptr *node_ptr); + + //! Return statistics from a constant value + unique_ptr StatisticsFromValue(const Value &input); + //! Run a comparison with two sets of statistics, returns if the comparison will always returns true/false or not + FilterPropagateResult PropagateComparison(BaseStatistics &left, BaseStatistics &right, ExpressionType comparison); + + //! Update filter statistics from a filter with a constant + void UpdateFilterStatistics(BaseStatistics &input, ExpressionType comparison_type, const Value &constant); + //! Update statistics from a filter between two stats + void UpdateFilterStatistics(BaseStatistics &lstats, BaseStatistics &rstats, ExpressionType comparison_type); + //! Update filter statistics from a generic comparison + void UpdateFilterStatistics(Expression &left, Expression &right, ExpressionType comparison_type); + //! Update filter statistics from an expression + void UpdateFilterStatistics(Expression &condition); + //! Set the statistics of a specific column binding to not contain null values + void SetStatisticsNotNull(ColumnBinding binding); + + //! Run a comparison between the statistics and the table filter; returns the prune result + FilterPropagateResult PropagateTableFilter(BaseStatistics &stats, TableFilter &filter); + //! Update filter statistics from a TableFilter + void UpdateFilterStatistics(BaseStatistics &input, TableFilter &filter); + + //! Add cardinalities together (i.e. new max is stats.max + new_stats.max): used for union + void AddCardinalities(unique_ptr &stats, NodeStatistics &new_stats); + //! Multiply the cardinalities together (i.e. new max cardinality is stats.max * new_stats.max): used for + //! joins/cross products + void MultiplyCardinalities(unique_ptr &stats, NodeStatistics &new_stats); + + unique_ptr PropagateExpression(unique_ptr &expr); + unique_ptr PropagateExpression(Expression &expr, unique_ptr *expr_ptr); + + unique_ptr PropagateExpression(BoundAggregateExpression &expr, unique_ptr *expr_ptr); + unique_ptr PropagateExpression(BoundBetweenExpression &expr, unique_ptr *expr_ptr); + unique_ptr PropagateExpression(BoundCaseExpression &expr, unique_ptr *expr_ptr); + unique_ptr PropagateExpression(BoundCastExpression &expr, unique_ptr *expr_ptr); + unique_ptr PropagateExpression(BoundConjunctionExpression &expr, unique_ptr *expr_ptr); + unique_ptr PropagateExpression(BoundFunctionExpression &expr, unique_ptr *expr_ptr); + unique_ptr PropagateExpression(BoundComparisonExpression &expr, unique_ptr *expr_ptr); + unique_ptr PropagateExpression(BoundConstantExpression &expr, unique_ptr *expr_ptr); + unique_ptr PropagateExpression(BoundColumnRefExpression &expr, unique_ptr *expr_ptr); + unique_ptr PropagateExpression(BoundOperatorExpression &expr, unique_ptr *expr_ptr); + + void PropagateAndCompress(unique_ptr &expr, unique_ptr &stats); + + void ReplaceWithEmptyResult(unique_ptr &node); + + bool ExpressionIsConstant(Expression &expr, const Value &val); + bool ExpressionIsConstantOrNull(Expression &expr, const Value &val); + +private: + ClientContext &context; + //! The map of ColumnBinding -> statistics for the various nodes + column_binding_map_t> statistics_map; + //! Node stats for the current node + unique_ptr node_stats; +}; + +} // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // @@ -28409,6 +30822,7 @@ class ExpressionIterator { + // LICENSE_CHANGE_BEGIN // The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #6 // See the end of this file for a list @@ -29594,6 +32008,9 @@ using duckdb_re2::LazyRE2; // LICENSE_CHANGE_END +#include +#include + namespace duckdb { class HivePartitioning { @@ -29613,8 +32030,72 @@ class HivePartitioning { DUCKDB_API static const string REGEX_STRING; }; -} // namespace duckdb +struct HivePartitionKey { + //! Columns by which we want to partition + vector values; + //! Precomputed hash of values + hash_t hash; + struct Hash { + std::size_t operator()(const HivePartitionKey &k) const { + return k.hash; + } + }; + + struct Equality { + bool operator()(const HivePartitionKey &a, const HivePartitionKey &b) const { + return a.values == b.values; + } + }; +}; + +//! Maps hive partitions to partition_ids +typedef unordered_map hive_partition_map_t; + +//! class shared between HivePartitionColumnData classes that synchronizes partition discovery between threads. +//! each HivePartitionedColumnData will hold a local copy of the key->partition map +class GlobalHivePartitionState { +public: + mutex lock; + hive_partition_map_t partition_map; + //! Used for incremental updating local copies of the partition map; + std::vector partitions; +}; + +class HivePartitionedColumnData : public PartitionedColumnData { +public: + HivePartitionedColumnData(ClientContext &context, vector types, vector partition_by_cols, + shared_ptr global_state = nullptr) + : PartitionedColumnData(PartitionedColumnDataType::HIVE, context, std::move(types)), + global_state(std::move(global_state)), group_by_columns(partition_by_cols) { + } + HivePartitionedColumnData(const HivePartitionedColumnData &other); + void ComputePartitionIndices(PartitionedColumnDataAppendState &state, DataChunk &input) override; + + //! Reverse lookup map to reconstruct keys from a partition id + std::map GetReverseMap(); + +protected: + //! Create allocators for all currently registered partitions + void GrowAllocators(); + //! Create append states for all currently registered partitions + void GrowAppendState(PartitionedColumnDataAppendState &state); + //! Create and initialize partitions for all currently registered partitions + void GrowPartitions(PartitionedColumnDataAppendState &state); + //! Register a newly discovered partition + idx_t RegisterNewPartition(HivePartitionKey key, PartitionedColumnDataAppendState &state); + //! Copy the newly added entries in the global_state.map to the local_partition_map (requires lock!) + void SynchronizeLocalMap(); + + //! Shared HivePartitionedColumnData should always have a global state to allow parallel key discovery + shared_ptr global_state; + //! Thread-local copy of the partition map + hive_partition_map_t local_partition_map; + //! The columns that make up the key + vector group_by_columns; +}; + +} // namespace duckdb @@ -29622,7 +32103,6 @@ class HivePartitioning { -#include namespace duckdb { @@ -29704,6 +32184,7 @@ void HivePartitioning::ApplyFiltersToFileList(ClientContext &context, vector &column_map, idx_t table_index, bool hive_enabled, bool filename_enabled) { vector pruned_files; + vector have_preserved_filter(filters.size(), false); vector> pruned_filters; duckdb_re2::RE2 regex(REGEX_STRING); @@ -29717,15 +32198,21 @@ void HivePartitioning::ApplyFiltersToFileList(ClientContext &context, vector filter_copy = filter->Copy(); ConvertKnownColRefToConstants(filter_copy, known_values, table_index); // Evaluate the filter, if it can be evaluated here, we can not prune this filter Value result_value; + if (!filter_copy->IsScalar() || !filter_copy->IsFoldable() || !ExpressionExecutor::TryEvaluateScalar(context, *filter_copy, result_value)) { // can not be evaluated only with the filename/hive columns added, we can not prune this filter - pruned_filters.emplace_back(filter->Copy()); + if (!have_preserved_filter[j]) { + pruned_filters.emplace_back(filter->Copy()); + have_preserved_filter[j] = true; + } } else if (!result_value.GetValue()) { // filter evaluates to false should_prune_file = true; @@ -29742,113 +32229,128 @@ void HivePartitioning::ApplyFiltersToFileList(ClientContext &context, vector= pruned_filters.size()); + filters = std::move(pruned_filters); files = std::move(pruned_files); } -} // namespace duckdb - - - - -#include - -namespace duckdb { - -using std::numeric_limits; - -int8_t NumericLimits::Minimum() { - return numeric_limits::lowest(); +HivePartitionedColumnData::HivePartitionedColumnData(const HivePartitionedColumnData &other) + : PartitionedColumnData(other) { + // Synchronize to ensure consistency of shared partition map + if (other.global_state) { + global_state = other.global_state; + unique_lock lck(global_state->lock); + SynchronizeLocalMap(); + } } -int8_t NumericLimits::Maximum() { - return numeric_limits::max(); -} +void HivePartitionedColumnData::ComputePartitionIndices(PartitionedColumnDataAppendState &state, DataChunk &input) { + Vector hashes(LogicalType::HASH, input.size()); + input.Hash(group_by_columns, hashes); -int16_t NumericLimits::Minimum() { - return numeric_limits::lowest(); -} + for (idx_t i = 0; i < input.size(); i++) { + HivePartitionKey key; + key.hash = FlatVector::GetData(hashes)[i]; + for (auto &col : group_by_columns) { + key.values.emplace_back(input.GetValue(col, i)); + } -int16_t NumericLimits::Maximum() { - return numeric_limits::max(); + auto lookup = local_partition_map.find(key); + const auto partition_indices = FlatVector::GetData(state.partition_indices); + if (lookup == local_partition_map.end()) { + idx_t new_partition_id = RegisterNewPartition(key, state); + partition_indices[i] = new_partition_id; + } else { + partition_indices[i] = lookup->second; + } + } } -int32_t NumericLimits::Minimum() { - return numeric_limits::lowest(); +std::map HivePartitionedColumnData::GetReverseMap() { + std::map ret; + for (const auto &pair : local_partition_map) { + ret[pair.second] = &(pair.first); + } + return ret; } -int32_t NumericLimits::Maximum() { - return numeric_limits::max(); -} +void HivePartitionedColumnData::GrowAllocators() { + unique_lock lck_gstate(allocators->lock); -int64_t NumericLimits::Minimum() { - return numeric_limits::lowest(); -} + idx_t current_allocator_size = allocators->allocators.size(); + idx_t required_allocators = local_partition_map.size(); -int64_t NumericLimits::Maximum() { - return numeric_limits::max(); -} + allocators->allocators.reserve(current_allocator_size); + for (idx_t i = current_allocator_size; i < required_allocators; i++) { + CreateAllocator(); + } -float NumericLimits::Minimum() { - return numeric_limits::lowest(); + D_ASSERT(allocators->allocators.size() == local_partition_map.size()); } -float NumericLimits::Maximum() { - return numeric_limits::max(); -} +void HivePartitionedColumnData::GrowAppendState(PartitionedColumnDataAppendState &state) { + idx_t current_append_state_size = state.partition_append_states.size(); + idx_t required_append_state_size = local_partition_map.size(); -double NumericLimits::Minimum() { - return numeric_limits::lowest(); + for (idx_t i = current_append_state_size; i < required_append_state_size; i++) { + state.partition_append_states.emplace_back(make_unique()); + state.partition_buffers.emplace_back(CreatePartitionBuffer()); + } } -double NumericLimits::Maximum() { - return numeric_limits::max(); -} +void HivePartitionedColumnData::GrowPartitions(PartitionedColumnDataAppendState &state) { + idx_t current_partitions = partitions.size(); + idx_t required_partitions = local_partition_map.size(); -uint8_t NumericLimits::Minimum() { - return numeric_limits::lowest(); -} + D_ASSERT(allocators->allocators.size() == required_partitions); -uint8_t NumericLimits::Maximum() { - return numeric_limits::max(); + for (idx_t i = current_partitions; i < required_partitions; i++) { + partitions.emplace_back(CreatePartitionCollection(i)); + partitions[i]->InitializeAppend(*state.partition_append_states[i]); + } + D_ASSERT(partitions.size() == local_partition_map.size()); } -uint16_t NumericLimits::Minimum() { - return numeric_limits::lowest(); +void HivePartitionedColumnData::SynchronizeLocalMap() { + // Synchronise global map into local, may contain changes from other threads too + for (auto it = global_state->partitions.begin() + local_partition_map.size(); it < global_state->partitions.end(); + it++) { + local_partition_map[(*it)->first] = (*it)->second; + } } -uint16_t NumericLimits::Maximum() { - return numeric_limits::max(); -} +idx_t HivePartitionedColumnData::RegisterNewPartition(HivePartitionKey key, PartitionedColumnDataAppendState &state) { + if (global_state) { + idx_t partition_id; -uint32_t NumericLimits::Minimum() { - return numeric_limits::lowest(); -} + // Synchronize Global state with our local state with the newly discoveren partition + { + unique_lock lck_gstate(global_state->lock); -uint32_t NumericLimits::Maximum() { - return numeric_limits::max(); -} + // Insert into global map, or return partition if already present + auto res = + global_state->partition_map.emplace(std::make_pair(std::move(key), global_state->partition_map.size())); + auto it = res.first; + partition_id = it->second; -uint64_t NumericLimits::Minimum() { - return numeric_limits::lowest(); -} + // Add iterator to vector to allow incrementally updating local states from global state + global_state->partitions.emplace_back(it); + SynchronizeLocalMap(); + } -uint64_t NumericLimits::Maximum() { - return numeric_limits::max(); -} + // After synchronizing with the global state, we need to grow the shared allocators to support + // the number of partitions, which guarantees that there's always enough allocators available to each thread + GrowAllocators(); -hugeint_t NumericLimits::Minimum() { - hugeint_t result; - result.lower = 1; - result.upper = numeric_limits::lowest(); - return result; -} + // Grow local partition data + GrowAppendState(state); + GrowPartitions(state); -hugeint_t NumericLimits::Maximum() { - hugeint_t result; - result.lower = numeric_limits::max(); - result.upper = numeric_limits::max(); - return result; + return partition_id; + } else { + return local_partition_map.emplace(std::make_pair(std::move(key), local_partition_map.size())).first->second; + } } } // namespace duckdb @@ -29901,7 +32403,8 @@ class LocalFileSystem : public FileSystem { //! Recursively remove a directory and all files in it void RemoveDirectory(const string &directory) override; //! List files in a directory, invoking the callback method for each one with (filename, is_dir) - bool ListFiles(const string &directory, const std::function &callback) override; + bool ListFiles(const string &directory, const std::function &callback, + FileOpener *opener = nullptr) override; //! Move a file from source path to the target, StorageManager relies on this being an atomic action for ACID //! properties void MoveFile(const string &source, const string &target) override; @@ -30102,10 +32605,10 @@ bool LocalFileSystem::IsPipe(const string &filename) { struct UnixFileHandle : public FileHandle { public: - UnixFileHandle(FileSystem &file_system, string path, int fd) : FileHandle(file_system, move(path)), fd(fd) { + UnixFileHandle(FileSystem &file_system, string path, int fd) : FileHandle(file_system, std::move(path)), fd(fd) { } ~UnixFileHandle() override { - Close(); + UnixFileHandle::Close(); } int fd; @@ -30389,7 +32892,8 @@ void LocalFileSystem::RemoveFile(const string &filename) { } } -bool LocalFileSystem::ListFiles(const string &directory, const std::function &callback) { +bool LocalFileSystem::ListFiles(const string &directory, const std::function &callback, + FileOpener *opener) { if (!DirectoryExists(directory)) { return false; } @@ -30470,7 +32974,7 @@ struct WindowsFileHandle : public FileHandle { WindowsFileHandle(FileSystem &file_system, string path, HANDLE fd) : FileHandle(file_system, path), position(0), fd(fd) { } - virtual ~WindowsFileHandle() { + ~WindowsFileHandle() override { Close(); } @@ -30534,7 +33038,7 @@ unique_ptr LocalFileSystem::OpenFile(const string &path, uint8_t fla auto file_size = GetFileSize(*handle); SetFilePointer(*handle, file_size); } - return move(handle); + return std::move(handle); } void LocalFileSystem::SetFilePointer(FileHandle &handle, idx_t location) { @@ -30716,7 +33220,8 @@ void LocalFileSystem::RemoveFile(const string &filename) { } } -bool LocalFileSystem::ListFiles(const string &directory, const std::function &callback) { +bool LocalFileSystem::ListFiles(const string &directory, const std::function &callback, + FileOpener *opener) { string search_dir = JoinPath(directory, "*"); auto unicode_path = WindowsUtil::UTF8ToUnicode(search_dir.c_str()); @@ -30948,7 +33453,7 @@ vector LocalFileSystem::Glob(const string &path, FileOpener *opener) { if (is_last_chunk) { return result; } - previous_directories = move(result); + previous_directories = std::move(result); } return vector(); } @@ -30992,45 +33497,45 @@ namespace duckdb { struct ConvertToString { template - static inline string Operation(SRC input) { + DUCKDB_API static inline string Operation(SRC input) { throw InternalException("Unrecognized type for ConvertToString %s", GetTypeId()); } }; template <> -string ConvertToString::Operation(bool input); +DUCKDB_API string ConvertToString::Operation(bool input); template <> -string ConvertToString::Operation(int8_t input); +DUCKDB_API string ConvertToString::Operation(int8_t input); template <> -string ConvertToString::Operation(int16_t input); +DUCKDB_API string ConvertToString::Operation(int16_t input); template <> -string ConvertToString::Operation(int32_t input); +DUCKDB_API string ConvertToString::Operation(int32_t input); template <> -string ConvertToString::Operation(int64_t input); +DUCKDB_API string ConvertToString::Operation(int64_t input); template <> -string ConvertToString::Operation(uint8_t input); +DUCKDB_API string ConvertToString::Operation(uint8_t input); template <> -string ConvertToString::Operation(uint16_t input); +DUCKDB_API string ConvertToString::Operation(uint16_t input); template <> -string ConvertToString::Operation(uint32_t input); +DUCKDB_API string ConvertToString::Operation(uint32_t input); template <> -string ConvertToString::Operation(uint64_t input); +DUCKDB_API string ConvertToString::Operation(uint64_t input); template <> -string ConvertToString::Operation(hugeint_t input); +DUCKDB_API string ConvertToString::Operation(hugeint_t input); template <> -string ConvertToString::Operation(float input); +DUCKDB_API string ConvertToString::Operation(float input); template <> -string ConvertToString::Operation(double input); +DUCKDB_API string ConvertToString::Operation(double input); template <> -string ConvertToString::Operation(interval_t input); +DUCKDB_API string ConvertToString::Operation(interval_t input); template <> -string ConvertToString::Operation(date_t input); +DUCKDB_API string ConvertToString::Operation(date_t input); template <> -string ConvertToString::Operation(dtime_t input); +DUCKDB_API string ConvertToString::Operation(dtime_t input); template <> -string ConvertToString::Operation(timestamp_t input); +DUCKDB_API string ConvertToString::Operation(timestamp_t input); template <> -string ConvertToString::Operation(string_t input); +DUCKDB_API string ConvertToString::Operation(string_t input); } // namespace duckdb @@ -31054,6 +33559,13 @@ struct TryCastErrorMessage { } }; +struct TryCastErrorMessageCommaSeparated { + template + DUCKDB_API static inline bool Operation(SRC input, DST &result, string *error_message, bool strict = false) { + throw NotImplementedException("Unimplemented type for cast (%s -> %s)", GetTypeId(), GetTypeId()); + } +}; + template static string CastExceptionText(SRC input) { if (std::is_same()) { @@ -31454,6 +33966,16 @@ template <> DUCKDB_API bool TryCast::Operation(string_t input, float &result, bool strict); template <> DUCKDB_API bool TryCast::Operation(string_t input, double &result, bool strict); +template <> +DUCKDB_API bool TryCastErrorMessage::Operation(string_t input, float &result, string *error_message, bool strict); +template <> +DUCKDB_API bool TryCastErrorMessage::Operation(string_t input, double &result, string *error_message, bool strict); +template <> +DUCKDB_API bool TryCastErrorMessageCommaSeparated::Operation(string_t input, float &result, string *error_message, + bool strict); +template <> +DUCKDB_API bool TryCastErrorMessageCommaSeparated::Operation(string_t input, double &result, string *error_message, + bool strict); //===--------------------------------------------------------------------===// // Date Casts @@ -31667,6 +34189,30 @@ template <> bool TryCastToBlob::Operation(string_t input, string_t &result, Vector &result_vector, string *error_message, bool strict); +//===--------------------------------------------------------------------===// +// Bits +//===--------------------------------------------------------------------===// +struct CastFromBit { + template + static inline string_t Operation(SRC input, Vector &result) { + throw duckdb::NotImplementedException("Cast from bit could not be performed!"); + } +}; +template <> +duckdb::string_t CastFromBit::Operation(duckdb::string_t input, Vector &vector); + +struct TryCastToBit { + template + static inline bool Operation(SRC input, DST &result, Vector &result_vector, string *error_message, + bool strict = false) { + throw InternalException("Unsupported type for try cast to bit"); + } +}; + +template <> +bool TryCastToBit::Operation(string_t input, string_t &result, Vector &result_vector, string *error_message, + bool strict); + //===--------------------------------------------------------------------===// // UUID //===--------------------------------------------------------------------===// @@ -31882,6 +34428,26 @@ bool TryCastWithOverflowCheck(float value, int64_t &result) { 9223372036854775808.0f); } +template <> +bool TryCastWithOverflowCheck(float value, uint8_t &result) { + return TryCastWithOverflowCheckFloat(value, result, 0.0f, 256.0f); +} + +template <> +bool TryCastWithOverflowCheck(float value, uint16_t &result) { + return TryCastWithOverflowCheckFloat(value, result, 0.0f, 65536.0f); +} + +template <> +bool TryCastWithOverflowCheck(float value, uint32_t &result) { + return TryCastWithOverflowCheckFloat(value, result, 0.0f, 4294967296.0f); +} + +template <> +bool TryCastWithOverflowCheck(float value, uint64_t &result) { + return TryCastWithOverflowCheckFloat(value, result, 0.0f, 18446744073709551616.0f); +} + template <> bool TryCastWithOverflowCheck(double value, int8_t &result) { return TryCastWithOverflowCheckFloat(value, result, -128.0, 128.0); @@ -31902,6 +34468,25 @@ bool TryCastWithOverflowCheck(double value, int64_t &result) { return TryCastWithOverflowCheckFloat(value, result, -9223372036854775808.0, 9223372036854775808.0); } +template <> +bool TryCastWithOverflowCheck(double value, uint8_t &result) { + return TryCastWithOverflowCheckFloat(value, result, 0.0, 256.0); +} + +template <> +bool TryCastWithOverflowCheck(double value, uint16_t &result) { + return TryCastWithOverflowCheckFloat(value, result, 0.0, 65536.0); +} + +template <> +bool TryCastWithOverflowCheck(double value, uint32_t &result) { + return TryCastWithOverflowCheckFloat(value, result, 0.0, 4294967296.0); +} + +template <> +bool TryCastWithOverflowCheck(double value, uint64_t &result) { + return TryCastWithOverflowCheckFloat(value, result, 0.0, 18446744073709551615.0); +} template <> bool TryCastWithOverflowCheck(float input, float &result) { result = input; @@ -32234,6 +34819,14 @@ struct TryCastToDecimal { } }; +struct TryCastToDecimalCommaSeparated { + template + DUCKDB_API static inline bool Operation(SRC input, DST &result, string *error_message, uint8_t width, + uint8_t scale) { + throw NotImplementedException("Unimplemented type for TryCastToDecimal!"); + } +}; + struct TryCastFromDecimal { template static inline bool Operation(SRC input, DST &result, string *error_message, uint8_t width, uint8_t scale) { @@ -32578,6 +35171,18 @@ DUCKDB_API bool TryCastToDecimal::Operation(string_t input, int64_t &result, str template <> DUCKDB_API bool TryCastToDecimal::Operation(string_t input, hugeint_t &result, string *error_message, uint8_t width, uint8_t scale); +template <> +DUCKDB_API bool TryCastToDecimalCommaSeparated::Operation(string_t input, int16_t &result, string *error_message, + uint8_t width, uint8_t scale); +template <> +DUCKDB_API bool TryCastToDecimalCommaSeparated::Operation(string_t input, int32_t &result, string *error_message, + uint8_t width, uint8_t scale); +template <> +DUCKDB_API bool TryCastToDecimalCommaSeparated::Operation(string_t input, int64_t &result, string *error_message, + uint8_t width, uint8_t scale); +template <> +DUCKDB_API bool TryCastToDecimalCommaSeparated::Operation(string_t input, hugeint_t &result, string *error_message, + uint8_t width, uint8_t scale); struct StringCastFromDecimal { template @@ -33358,7 +35963,9 @@ struct from_chars_result { */ template from_chars_result from_chars(const char *first, const char *last, - T &value, chars_format fmt = chars_format::general) noexcept; + T &value, + const char decimal_separator = '.', + chars_format fmt = chars_format::general) noexcept; } #endif // FASTFLOAT_FAST_FLOAT_H @@ -33783,7 +36390,7 @@ struct parsed_number_string { // Assuming that you use no more than 19 digits, this will // parse an ASCII string. fastfloat_really_inline -parsed_number_string parse_number_string(const char *p, const char *pend, chars_format fmt) noexcept { +parsed_number_string parse_number_string(const char *p, const char *pend, const char decimal_separator, chars_format fmt) noexcept { parsed_number_string answer; answer.valid = false; answer.too_many_digits = false; @@ -33793,7 +36400,7 @@ parsed_number_string parse_number_string(const char *p, const char *pend, chars_ if (p == pend) { return answer; } - if (!is_integer(*p) && (*p != '.')) { // a sign must be followed by an integer or the dot + if (!is_integer(*p) && (*p != decimal_separator)) { // a sign must be followed by an integer or the dot return answer; } } @@ -33811,7 +36418,7 @@ parsed_number_string parse_number_string(const char *p, const char *pend, chars_ const char *const end_of_integer_part = p; int64_t digit_count = int64_t(end_of_integer_part - start_digits); int64_t exponent = 0; - if ((p != pend) && (*p == '.')) { + if ((p != pend) && (*p == decimal_separator)) { ++p; // Fast approach only tested under little endian systems if ((p + 8 <= pend) && is_made_of_eight_digits_fast(p)) { @@ -33881,7 +36488,7 @@ parsed_number_string parse_number_string(const char *p, const char *pend, chars_ // We need to be mindful of the case where we only have zeroes... // E.g., 0.000000000...000. const char *start = start_digits; - while ((start != pend) && (*start == '0' || *start == '.')) { + while ((start != pend) && (*start == '0' || *start == decimal_separator)) { if(*start == '0') { digit_count --; } start++; } @@ -33898,7 +36505,7 @@ parsed_number_string parse_number_string(const char *p, const char *pend, chars_ if (i >= minimal_nineteen_digit_integer) { // We have a big integers exponent = end_of_integer_part - p + exp_number; } else { // We have a value with a fractional component. - p++; // skip the '.' + p++; // skip the decimal_separator const char *first_after_period = p; while((i < minimal_nineteen_digit_integer) && (p != pend) && is_integer(*p)) { i = i * 10 + uint64_t(*p - '0'); @@ -33919,7 +36526,7 @@ parsed_number_string parse_number_string(const char *p, const char *pend, chars_ // This function could be optimized. In particular, we could stop after 19 digits // and try to bail out. Furthermore, we should be able to recover the computed // exponent from the pass in parse_number_string. -fastfloat_really_inline decimal parse_decimal(const char *p, const char *pend) noexcept { +fastfloat_really_inline decimal parse_decimal(const char *p, const char *pend, const char decimal_separator = '.') noexcept { decimal answer; answer.num_digits = 0; answer.decimal_point = 0; @@ -33939,7 +36546,7 @@ fastfloat_really_inline decimal parse_decimal(const char *p, const char *pend) n answer.num_digits++; ++p; } - if ((p != pend) && (*p == '.')) { + if ((p != pend) && (*p == decimal_separator)) { ++p; const char *first_after_period = p; // if we have not yet encountered a zero, we have to skip it as well @@ -33978,7 +36585,7 @@ fastfloat_really_inline decimal parse_decimal(const char *p, const char *pend) n // we have at least one non-zero digit. const char *preverse = p - 1; int32_t trailing_zeros = 0; - while ((*preverse == '0') || (*preverse == '.')) { + while ((*preverse == '0') || (*preverse == decimal_separator)) { if(*preverse == '0') { trailing_zeros++; }; --preverse; } @@ -34974,7 +37581,7 @@ struct parsed_number_string { // Assuming that you use no more than 19 digits, this will // parse an ASCII string. fastfloat_really_inline -parsed_number_string parse_number_string(const char *p, const char *pend, chars_format fmt) noexcept { +parsed_number_string parse_number_string(const char *p, const char *pend, const char decimal_separator, chars_format fmt) noexcept { parsed_number_string answer; answer.valid = false; answer.too_many_digits = false; @@ -34984,7 +37591,7 @@ parsed_number_string parse_number_string(const char *p, const char *pend, chars_ if (p == pend) { return answer; } - if (!is_integer(*p) && (*p != '.')) { // a sign must be followed by an integer or the dot + if (!is_integer(*p) && (*p != decimal_separator)) { // a sign must be followed by an integer or the dot return answer; } } @@ -35002,7 +37609,7 @@ parsed_number_string parse_number_string(const char *p, const char *pend, chars_ const char *const end_of_integer_part = p; int64_t digit_count = int64_t(end_of_integer_part - start_digits); int64_t exponent = 0; - if ((p != pend) && (*p == '.')) { + if ((p != pend) && (*p == decimal_separator)) { ++p; // Fast approach only tested under little endian systems if ((p + 8 <= pend) && is_made_of_eight_digits_fast(p)) { @@ -35072,7 +37679,7 @@ parsed_number_string parse_number_string(const char *p, const char *pend, chars_ // We need to be mindful of the case where we only have zeroes... // E.g., 0.000000000...000. const char *start = start_digits; - while ((start != pend) && (*start == '0' || *start == '.')) { + while ((start != pend) && (*start == '0' || *start == decimal_separator)) { if(*start == '0') { digit_count --; } start++; } @@ -35089,7 +37696,7 @@ parsed_number_string parse_number_string(const char *p, const char *pend, chars_ if (i >= minimal_nineteen_digit_integer) { // We have a big integers exponent = end_of_integer_part - p + exp_number; } else { // We have a value with a fractional component. - p++; // skip the '.' + p++; // skip the decimal_separator const char *first_after_period = p; while((i < minimal_nineteen_digit_integer) && (p != pend) && is_integer(*p)) { i = i * 10 + uint64_t(*p - '0'); @@ -35110,7 +37717,7 @@ parsed_number_string parse_number_string(const char *p, const char *pend, chars_ // This function could be optimized. In particular, we could stop after 19 digits // and try to bail out. Furthermore, we should be able to recover the computed // exponent from the pass in parse_number_string. -fastfloat_really_inline decimal parse_decimal(const char *p, const char *pend) noexcept { +fastfloat_really_inline decimal parse_decimal(const char *p, const char *pend, const char decimal_separator) noexcept { decimal answer; answer.num_digits = 0; answer.decimal_point = 0; @@ -35130,7 +37737,7 @@ fastfloat_really_inline decimal parse_decimal(const char *p, const char *pend) n answer.num_digits++; ++p; } - if ((p != pend) && (*p == '.')) { + if ((p != pend) && (*p == decimal_separator)) { ++p; const char *first_after_period = p; // if we have not yet encountered a zero, we have to skip it as well @@ -35169,7 +37776,7 @@ fastfloat_really_inline decimal parse_decimal(const char *p, const char *pend) n // we have at least one non-zero digit. const char *preverse = p - 1; int32_t trailing_zeros = 0; - while ((*preverse == '0') || (*preverse == '.')) { + while ((*preverse == '0') || (*preverse == decimal_separator)) { if(*preverse == '0') { trailing_zeros++; }; --preverse; } @@ -35653,7 +38260,8 @@ fastfloat_really_inline void to_float(bool negative, adjusted_mantissa am, T &va template from_chars_result from_chars(const char *first, const char *last, - T &value, chars_format fmt /*= chars_format::general*/) noexcept { + T &value, const char decimal_separator, chars_format fmt + /*= chars_format::general*/) noexcept { static_assert (std::is_same::value || std::is_same::value, "only float and double are supported"); @@ -35663,7 +38271,7 @@ from_chars_result from_chars(const char *first, const char *last, answer.ptr = first; return answer; } - parsed_number_string pns = parse_number_string(first, last, fmt); + parsed_number_string pns = parse_number_string(first, last, decimal_separator, fmt); if (!pns.valid) { return detail::parse_infnan(first, last, value); } @@ -35700,6 +38308,7 @@ from_chars_result from_chars(const char *first, const char *last, + #include #include #include @@ -36500,11 +39109,22 @@ struct IntegerCastOperation { return true; } + template + static bool HandleBinaryDigit(T &state, uint8_t digit) { + using result_t = typename T::Result; + if (state.result > (NumericLimits::Maximum() - digit) / 2) { + return false; + } + state.result = state.result * 2 + digit; + return true; + } + template static bool HandleExponent(T &state, int32_t exponent) { using result_t = typename T::Result; double dbl_res = state.result * std::pow(10.0L, exponent); - if (dbl_res < NumericLimits::Minimum() || dbl_res > NumericLimits::Maximum()) { + if (dbl_res < (double)NumericLimits::Minimum() || + dbl_res > (double)NumericLimits::Maximum()) { return false; } state.result = (result_t)std::nearbyint(dbl_res); @@ -36543,14 +39163,27 @@ struct IntegerCastOperation { } }; -template +template static bool IntegerCastLoop(const char *buf, idx_t len, T &result, bool strict) { - idx_t start_pos = NEGATIVE || *buf == '+' ? 1 : 0; + idx_t start_pos; + if (NEGATIVE) { + start_pos = 1; + } else { + if (*buf == '+') { + if (strict) { + // leading plus is not allowed in strict mode + return false; + } + start_pos = 1; + } else { + start_pos = 0; + } + } idx_t pos = start_pos; while (pos < len) { if (!StringUtil::CharacterIsDigit(buf[pos])) { // not a digit! - if (buf[pos] == '.') { + if (buf[pos] == decimal_separator) { if (strict) { return false; } @@ -36600,11 +39233,13 @@ static bool IntegerCastLoop(const char *buf, idx_t len, T &result, bool strict) ExponentData exponent {0, false}; int negative = buf[pos] == '-'; if (negative) { - if (!IntegerCastLoop(buf + pos, len - pos, exponent, strict)) { + if (!IntegerCastLoop(buf + pos, len - pos, + exponent, strict)) { return false; } } else { - if (!IntegerCastLoop(buf + pos, len - pos, exponent, strict)) { + if (!IntegerCastLoop(buf + pos, len - pos, + exponent, strict)) { return false; } } @@ -36654,8 +39289,45 @@ static bool IntegerHexCastLoop(const char *buf, idx_t len, T &result, bool stric return pos > start_pos; } +template +static bool IntegerBinaryCastLoop(const char *buf, idx_t len, T &result, bool strict) { + if (ALLOW_EXPONENT || NEGATIVE) { + return false; + } + idx_t start_pos = 1; + idx_t pos = start_pos; + uint8_t digit; + char current_char; + while (pos < len) { + current_char = buf[pos]; + if (current_char == '_' && pos > start_pos) { + // skip underscore, if it is not the first character + pos++; + if (pos == len) { + // we cant end on an underscore either + return false; + } + continue; + } else if (current_char == '0') { + digit = 0; + } else if (current_char == '1') { + digit = 1; + } else { + return false; + } + pos++; + if (!OP::template HandleBinaryDigit(result, digit)) { + return false; + } + } + if (!OP::template Finalize(result)) { + return false; + } + return pos > start_pos; +} + template + bool ZERO_INITIALIZE = true, char decimal_separator = '.'> static bool TryIntegerCast(const char *buf, idx_t len, T &result, bool strict) { // skip any spaces at the start while (len > 0 && StringUtil::CharacterIsSpace(*buf)) { @@ -36665,24 +39337,11 @@ static bool TryIntegerCast(const char *buf, idx_t len, T &result, bool strict) { if (len == 0) { return false; } - int negative = *buf == '-'; - - // If it starts with 0x or 0X, we parse it as a hex value - int hex = len > 1 && *buf == '0' && (buf[1] == 'x' || buf[1] == 'X'); - if (ZERO_INITIALIZE) { memset(&result, 0, sizeof(T)); } - if (!negative) { - if (hex) { - // Skip the 0x - buf++; - len--; - return IntegerHexCastLoop(buf, len, result, strict); - } else { - return IntegerCastLoop(buf, len, result, strict); - } - } else { + // if the number is negative, we set the negative flag and skip the negative sign + if (*buf == '-') { if (!IS_SIGNED) { // Need to check if its not -0 idx_t pos = 1; @@ -36692,8 +39351,25 @@ static bool TryIntegerCast(const char *buf, idx_t len, T &result, bool strict) { } } } - return IntegerCastLoop(buf, len, result, strict); + return IntegerCastLoop(buf, len, result, strict); } + if (len > 1 && *buf == '0') { + if (buf[1] == 'x' || buf[1] == 'X') { + // If it starts with 0x or 0X, we parse it as a hex value + buf++; + len--; + return IntegerHexCastLoop(buf, len, result, strict); + } else if (buf[1] == 'b' || buf[1] == 'B') { + // If it starts with 0b or 0B, we parse it as a binary value + buf++; + len--; + return IntegerBinaryCastLoop(buf, len, result, strict); + } else if (strict && StringUtil::CharacterIsDigit(buf[1])) { + // leading zeros are not allowed in strict mode + return false; + } + } + return IntegerCastLoop(buf, len, result, strict); } template @@ -36784,7 +39460,7 @@ bool TryCast::Operation(string_t input, uint64_t &result, bool strict) { return TrySimpleIntegerCast(input.GetDataUnsafe(), input.GetSize(), result, strict); } -template +template static bool TryDoubleCast(const char *buf, idx_t len, T &result, bool strict) { // skip any spaces at the start while (len > 0 && StringUtil::CharacterIsSpace(*buf)) { @@ -36795,11 +39471,21 @@ static bool TryDoubleCast(const char *buf, idx_t len, T &result, bool strict) { return false; } if (*buf == '+') { + if (strict) { + // plus is not allowed in strict mode + return false; + } buf++; len--; } + if (strict && len >= 2) { + if (buf[0] == '0' && StringUtil::CharacterIsDigit(buf[1])) { + // leading zeros are not allowed in strict mode + return false; + } + } auto endptr = buf + len; - auto parse_result = duckdb_fast_float::from_chars(buf, buf + len, result); + auto parse_result = duckdb_fast_float::from_chars(buf, buf + len, result, decimal_separator); if (parse_result.ec != std::errc()) { return false; } @@ -36822,6 +39508,26 @@ bool TryCast::Operation(string_t input, double &result, bool strict) { return TryDoubleCast(input.GetDataUnsafe(), input.GetSize(), result, strict); } +template <> +bool TryCastErrorMessageCommaSeparated::Operation(string_t input, float &result, string *error_message, bool strict) { + if (!TryDoubleCast(input.GetDataUnsafe(), input.GetSize(), result, strict)) { + HandleCastError::AssignError(StringUtil::Format("Could not cast string to float: \"%s\"", input.GetString()), + error_message); + return false; + } + return true; +} + +template <> +bool TryCastErrorMessageCommaSeparated::Operation(string_t input, double &result, string *error_message, bool strict) { + if (!TryDoubleCast(input.GetDataUnsafe(), input.GetSize(), result, strict)) { + HandleCastError::AssignError(StringUtil::Format("Could not cast string to double: \"%s\"", input.GetString()), + error_message); + return false; + } + return true; +} + //===--------------------------------------------------------------------===// // Cast From Date //===--------------------------------------------------------------------===// @@ -37002,6 +39708,21 @@ string_t CastFromBlob::Operation(string_t input, Vector &vector) { string_t result = StringVector::EmptyString(vector, result_size); Blob::ToString(input, result.GetDataWriteable()); result.Finalize(); + + return result; +} + +//===--------------------------------------------------------------------===// +// Cast From Bit +//===--------------------------------------------------------------------===// +template <> +string_t CastFromBit::Operation(string_t input, Vector &vector) { + + idx_t result_size = Bit::BitLength(input); + string_t result = StringVector::EmptyString(vector, result_size); + Bit::ToString(input, result.GetDataWriteable()); + result.Finalize(); + return result; } @@ -37031,6 +39752,23 @@ bool TryCastToBlob::Operation(string_t input, string_t &result, Vector &result_v return true; } +//===--------------------------------------------------------------------===// +// Cast To Bit +//===--------------------------------------------------------------------===// +template <> +bool TryCastToBit::Operation(string_t input, string_t &result, Vector &result_vector, string *error_message, + bool strict) { + idx_t result_size; + if (!Bit::TryGetBitStringSize(input, result_size, error_message)) { + return false; + } + + result = StringVector::EmptyString(result_vector, result_size); + Bit::ToBit(input, (data_ptr_t)result.GetDataWriteable()); + result.Finalize(); + return true; +} + //===--------------------------------------------------------------------===// // Cast From UUID //===--------------------------------------------------------------------===// @@ -37193,6 +39931,19 @@ struct HugeIntegerCastOperation { return false; } + template + static bool HandleBinaryDigit(T &result, uint8_t digit) { + if (result.intermediate > (NumericLimits::Maximum() - digit) / 2) { + // intermediate is full: need to flush it + if (!result.Flush()) { + return false; + } + } + result.intermediate = result.intermediate * 2 + digit; + result.digits++; + return true; + } + template static bool HandleExponent(T &result, int32_t exponent) { if (!result.Flush()) { @@ -37256,6 +40007,7 @@ bool TryCast::Operation(string_t input, hugeint_t &result, bool strict) { //===--------------------------------------------------------------------===// // Decimal String Cast //===--------------------------------------------------------------------===// + template struct DecimalCastData { typedef TYPE type_t; @@ -37264,9 +40016,14 @@ struct DecimalCastData { uint8_t scale; uint8_t digit_count; uint8_t decimal_count; + //! Whether we have determined if the result should be rounded + bool round_set; + //! If the result should be rounded + bool should_round; //! Only set when ALLOW_EXPONENT is enabled + enum class ExponentType : uint8_t { NONE, POSITIVE, NEGATIVE }; uint8_t excessive_decimals; - bool positive_exponent; + ExponentType exponent_type; }; struct DecimalCastOperation { @@ -37300,6 +40057,11 @@ struct DecimalCastOperation { return false; } + template + static bool HandleBinaryDigit(T &state, uint8_t digit) { + return false; + } + template static void RoundUpResult(T &state) { if (NEGATIVE) { @@ -37313,17 +40075,19 @@ struct DecimalCastOperation { static bool HandleExponent(T &state, int32_t exponent) { auto decimal_excess = (state.decimal_count > state.scale) ? state.decimal_count - state.scale : 0; if (exponent > 0) { - state.positive_exponent = true; - //! Positive exponents need up to 'exponent' amount of digits - //! Everything beyond that amount needs to be truncated + state.exponent_type = T::ExponentType::POSITIVE; + // Positive exponents need up to 'exponent' amount of digits + // Everything beyond that amount needs to be truncated if (decimal_excess > exponent) { - //! We've allowed too many decimals + // We've allowed too many decimals state.excessive_decimals = decimal_excess - exponent; exponent = 0; } else { exponent -= decimal_excess; } D_ASSERT(exponent >= 0); + } else if (exponent < 0) { + state.exponent_type = T::ExponentType::NEGATIVE; } if (!Finalize(state)) { return false; @@ -37355,6 +40119,11 @@ struct DecimalCastOperation { template static bool HandleDecimal(T &state, uint8_t digit) { + if (state.decimal_count == state.scale && !state.round_set) { + // Determine whether the last registered decimal should be rounded or not + state.round_set = true; + state.should_round = digit >= 5; + } if (!ALLOW_EXPONENT && state.decimal_count == state.scale) { // we exceeded the amount of supported decimals // however, we don't throw an error here @@ -37385,7 +40154,7 @@ struct DecimalCastOperation { state.result /= 10.0; } //! Only round up when exponents are involved - if (state.positive_exponent && round_up) { + if (state.exponent_type == T::ExponentType::POSITIVE && round_up) { RoundUpResult(state); } D_ASSERT(state.decimal_count > state.scale); @@ -37395,13 +40164,16 @@ struct DecimalCastOperation { template static bool Finalize(T &state) { - if (!state.positive_exponent && state.decimal_count > state.scale) { + if (state.exponent_type != T::ExponentType::POSITIVE && state.decimal_count > state.scale) { //! Did not encounter an exponent, but ALLOW_EXPONENT was on state.excessive_decimals = state.decimal_count - state.scale; } if (state.excessive_decimals && !TruncateExcessiveDecimals(state)) { return false; } + if (state.exponent_type == T::ExponentType::NONE && state.round_set && state.should_round) { + RoundUpResult(state); + } // if we have not gotten exactly "scale" decimals, we need to multiply the result // e.g. if we have a string "1.0" that is cast to a DECIMAL(9,3), the value needs to be 1000 // but we have only gotten the value "10" so far, so we multiply by 1000 @@ -37412,7 +40184,7 @@ struct DecimalCastOperation { } }; -template +template bool TryDecimalStringCast(string_t input, T &result, string *error_message, uint8_t width, uint8_t scale) { DecimalCastData state; state.result = 0; @@ -37421,9 +40193,11 @@ bool TryDecimalStringCast(string_t input, T &result, string *error_message, uint state.digit_count = 0; state.decimal_count = 0; state.excessive_decimals = 0; - state.positive_exponent = false; - if (!TryIntegerCast, true, true, DecimalCastOperation, false>(input.GetDataUnsafe(), - input.GetSize(), state, false)) { + state.exponent_type = DecimalCastData::ExponentType::NONE; + state.round_set = false; + state.should_round = false; + if (!TryIntegerCast, true, true, DecimalCastOperation, false, decimal_separator>( + input.GetDataUnsafe(), input.GetSize(), state, false)) { string error = StringUtil::Format("Could not convert string \"%s\" to DECIMAL(%d,%d)", input.GetString(), (int)width, (int)scale); HandleCastError::AssignError(error, error_message); @@ -37454,6 +40228,30 @@ bool TryCastToDecimal::Operation(string_t input, hugeint_t &result, string *erro return TryDecimalStringCast(input, result, error_message, width, scale); } +template <> +bool TryCastToDecimalCommaSeparated::Operation(string_t input, int16_t &result, string *error_message, uint8_t width, + uint8_t scale) { + return TryDecimalStringCast(input, result, error_message, width, scale); +} + +template <> +bool TryCastToDecimalCommaSeparated::Operation(string_t input, int32_t &result, string *error_message, uint8_t width, + uint8_t scale) { + return TryDecimalStringCast(input, result, error_message, width, scale); +} + +template <> +bool TryCastToDecimalCommaSeparated::Operation(string_t input, int64_t &result, string *error_message, uint8_t width, + uint8_t scale) { + return TryDecimalStringCast(input, result, error_message, width, scale); +} + +template <> +bool TryCastToDecimalCommaSeparated::Operation(string_t input, hugeint_t &result, string *error_message, uint8_t width, + uint8_t scale) { + return TryDecimalStringCast(input, result, error_message, width, scale); +} + template <> string_t StringCastFromDecimal::Operation(int16_t input, uint8_t width, uint8_t scale, Vector &result) { return DecimalToString::Format(input, width, scale, result); @@ -38505,7 +41303,7 @@ namespace duckdb { class PipeFile : public FileHandle { public: PipeFile(unique_ptr child_handle_p, const string &path) - : FileHandle(pipe_fs, path), child_handle(move(child_handle_p)) { + : FileHandle(pipe_fs, path), child_handle(std::move(child_handle_p)) { } PipeFileSystem pipe_fs; @@ -38549,7 +41347,7 @@ void PipeFileSystem::FileSync(FileHandle &handle) { unique_ptr PipeFileSystem::OpenPipe(unique_ptr handle) { auto path = handle->path; - return make_unique(move(handle), path); + return make_unique(std::move(handle), path); } } // namespace duckdb @@ -38569,10 +41367,6 @@ PreservedError::PreservedError(const Exception &exception) : initialized(true), type(exception.type), raw_message(SanitizeErrorMessage(exception.RawMessage())) { } -PreservedError::PreservedError(const std::exception &exception) - : initialized(true), type(ExceptionType::INVALID), raw_message(SanitizeErrorMessage(exception.what())) { -} - PreservedError::PreservedError(const string &message) : initialized(true), type(ExceptionType::INVALID), raw_message(SanitizeErrorMessage(message)) { } @@ -38585,7 +41379,7 @@ const string &PreservedError::Message() { } string PreservedError::SanitizeErrorMessage(string error) { - return StringUtil::Replace(move(error), string("\0", 1), "\\0"); + return StringUtil::Replace(std::move(error), string("\0", 1), "\\0"); } void PreservedError::Throw(const string &prepended_message) const { @@ -38623,72 +41417,6 @@ bool PreservedError::operator==(const PreservedError &other) const { } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/progress_bar.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - - -namespace duckdb { - -class ProgressBar { -public: - explicit ProgressBar(Executor &executor, idx_t show_progress_after, bool print_progress); - - //! Starts the thread - void Start(); - //! Updates the progress bar and prints it to the screen - void Update(bool final); - //! Gets current percentage - double GetCurrentPercentage(); - -private: - static constexpr const idx_t PARTIAL_BLOCK_COUNT = 8; -#ifndef DUCKDB_ASCII_TREE_RENDERER - const char *PROGRESS_EMPTY = " "; - const char *PROGRESS_PARTIAL[PARTIAL_BLOCK_COUNT] { - " ", "\xE2\x96\x8F", "\xE2\x96\x8E", "\xE2\x96\x8D", "\xE2\x96\x8C", "\xE2\x96\x8B", "\xE2\x96\x8A", - "\xE2\x96\x89"}; - const char *PROGRESS_BLOCK = "\xE2\x96\x88"; - const char *PROGRESS_START = "\xE2\x96\x95"; - const char *PROGRESS_END = "\xE2\x96\x8F"; -#else - const char *PROGRESS_EMPTY = " "; - const char *PROGRESS_PARTIAL[PARTIAL_BLOCK_COUNT] {" ", " ", " ", " ", " ", " ", " ", " "}; - const char *PROGRESS_BLOCK = "="; - const char *PROGRESS_START = "["; - const char *PROGRESS_END = "]"; -#endif - static constexpr const idx_t PROGRESS_BAR_WIDTH = 60; - - void PrintProgressInternal(int percentage); - void PrintProgress(int percentage); - void FinishProgressBarPrint(); - -private: - //! The executor - Executor &executor; - //! The profiler used to measure the time since the progress bar was started - Profiler profiler; - //! The time in ms after which to start displaying the progress bar - idx_t show_progress_after; - //! The current progress percentage - double current_percentage; - //! Whether or not we print the progress bar - bool print_progress; - //! Whether or not profiling is supported for the current query - bool supported = true; -}; -} // namespace duckdb @@ -38771,13 +41499,104 @@ idx_t Printer::TerminalWidth() { } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/progress_bar/display/terminal_progress_bar_display.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/unicode_bar.hpp +// +// +//===----------------------------------------------------------------------===// + +namespace duckdb { +struct UnicodeBar { +private: + static constexpr idx_t PARTIAL_BLOCKS_COUNT = 8; + +public: + static constexpr idx_t PartialBlocksCount() { + return PARTIAL_BLOCKS_COUNT; + } + + static const char *const *PartialBlocks() { + static const char *PARTIAL_BLOCKS[PARTIAL_BLOCKS_COUNT] = {" ", + "\xE2\x96\x8F", + "\xE2\x96\x8E", + "\xE2\x96\x8D", + "\xE2\x96\x8C", + "\xE2\x96\x8B", + "\xE2\x96\x8A", + "\xE2\x96\x89"}; + return PARTIAL_BLOCKS; + } + + static const char *FullBlock() { + return "\xE2\x96\x88"; + } +}; +} // namespace duckdb + + +namespace duckdb { + +class TerminalProgressBarDisplay : public ProgressBarDisplay { +public: + TerminalProgressBarDisplay() { + } + ~TerminalProgressBarDisplay() override { + } + +public: + void Update(double percentage) override; + void Finish() override; + +private: + static constexpr const idx_t PARTIAL_BLOCK_COUNT = UnicodeBar::PartialBlocksCount(); +#ifndef DUCKDB_ASCII_TREE_RENDERER + const char *PROGRESS_EMPTY = " "; + const char *const *PROGRESS_PARTIAL = UnicodeBar::PartialBlocks(); + const char *PROGRESS_BLOCK = UnicodeBar::FullBlock(); + const char *PROGRESS_START = "\xE2\x96\x95"; + const char *PROGRESS_END = "\xE2\x96\x8F"; +#else + const char *PROGRESS_EMPTY = " "; + const char *const PROGRESS_PARTIAL[PARTIAL_BLOCK_COUNT] = {" ", " ", " ", " ", " ", " ", " ", " "}; + const char *PROGRESS_BLOCK = "="; + const char *PROGRESS_START = "["; + const char *PROGRESS_END = "]"; +#endif + static constexpr const idx_t PROGRESS_BAR_WIDTH = 60; + +private: + void PrintProgressInternal(int percentage); +}; + +} // namespace duckdb namespace duckdb { -ProgressBar::ProgressBar(Executor &executor, idx_t show_progress_after, bool print_progress) - : executor(executor), show_progress_after(show_progress_after), current_percentage(-1), - print_progress(print_progress) { +unique_ptr ProgressBar::DefaultProgressBarDisplay() { + return make_unique(); +} + +ProgressBar::ProgressBar(Executor &executor, idx_t show_progress_after, + progress_bar_display_create_func_t create_display_func) + : executor(executor), show_progress_after(show_progress_after), current_percentage(-1) { + if (create_display_func) { + display = create_display_func(); + } } double ProgressBar::GetCurrentPercentage() { @@ -38790,20 +41609,44 @@ void ProgressBar::Start() { supported = true; } -void ProgressBar::Update(bool final) { +bool ProgressBar::PrintEnabled() const { + return display != nullptr; +} + +bool ProgressBar::ShouldPrint(bool final) const { + if (!PrintEnabled()) { + // Don't print progress at all + return false; + } + // FIXME - do we need to check supported before running `profiler.Elapsed()` ? + auto sufficient_time_elapsed = profiler.Elapsed() > show_progress_after / 1000.0; + if (!sufficient_time_elapsed) { + // Don't print yet + return false; + } + if (final) { + // Print the last completed bar + return true; + } if (!supported) { + return false; + } + return current_percentage > -1; +} + +void ProgressBar::Update(bool final) { + if (!final && !supported) { return; } double new_percentage; supported = executor.GetPipelinesProgress(new_percentage); - if (!supported) { + if (!final && !supported) { return; } - auto sufficient_time_elapsed = profiler.Elapsed() > show_progress_after / 1000.0; if (new_percentage > current_percentage) { current_percentage = new_percentage; } - if (supported && print_progress && sufficient_time_elapsed && current_percentage > -1 && print_progress) { + if (ShouldPrint(final)) { #ifndef DUCKDB_DISABLE_PRINT if (final) { FinishProgressBarPrint(); @@ -38814,7 +41657,28 @@ void ProgressBar::Update(bool final) { } } -void ProgressBar::PrintProgressInternal(int percentage) { +void ProgressBar::PrintProgress(int current_percentage) { + D_ASSERT(display); + display->Update(current_percentage); +} + +void ProgressBar::FinishProgressBarPrint() { + if (finished) { + return; + } + D_ASSERT(display); + display->Finish(); + finished = true; +} + +} // namespace duckdb + + + + +namespace duckdb { + +void TerminalProgressBarDisplay::PrintProgressInternal(int percentage) { if (percentage > 100) { percentage = 100; } @@ -38861,12 +41725,13 @@ void ProgressBar::PrintProgressInternal(int percentage) { Printer::RawPrint(OutputStream::STREAM_STDOUT, result); } -void ProgressBar::PrintProgress(int percentage) { + +void TerminalProgressBarDisplay::Update(double percentage) { PrintProgressInternal(percentage); Printer::Flush(OutputStream::STREAM_STDOUT); } -void ProgressBar::FinishProgressBarPrint() { +void TerminalProgressBarDisplay::Finish() { PrintProgressInternal(100); Printer::RawPrint(OutputStream::STREAM_STDOUT, "\n"); Printer::Flush(OutputStream::STREAM_STDOUT); @@ -38884,201 +41749,6 @@ void ProgressBar::FinishProgressBarPrint() { -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/types/partitioned_column_data.hpp -// -// -//===----------------------------------------------------------------------===// - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/types/column_data_allocator.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { -struct ChunkMetaData; - -struct BlockMetaData { - //! The underlying block handle - shared_ptr handle; - //! How much space is currently used within the block - uint32_t size; - //! How much space is available in the block - uint32_t capacity; - - uint32_t Capacity(); -}; - -class ColumnDataAllocator { -public: - ColumnDataAllocator(Allocator &allocator); - ColumnDataAllocator(BufferManager &buffer_manager); - ColumnDataAllocator(ClientContext &context, ColumnDataAllocatorType allocator_type); - - //! Returns an allocator object to allocate with. This returns the allocator in IN_MEMORY_ALLOCATOR, and a buffer - //! allocator in case of BUFFER_MANAGER_ALLOCATOR. - Allocator &GetAllocator(); - //! Returns the allocator type - ColumnDataAllocatorType GetType() { - return type; - } - void MakeShared() { - shared = true; - } - idx_t BlockCount() const { - return blocks.size(); - } - -public: - void AllocateData(idx_t size, uint32_t &block_id, uint32_t &offset, ChunkManagementState *chunk_state); - - void Initialize(ColumnDataAllocator &other); - void InitializeChunkState(ChunkManagementState &state, ChunkMetaData &meta_data); - data_ptr_t GetDataPointer(ChunkManagementState &state, uint32_t block_id, uint32_t offset); - - //! Deletes the block with the given id - void DeleteBlock(uint32_t block_id); - -private: - void AllocateEmptyBlock(idx_t size); - BufferHandle AllocateBlock(); - BufferHandle Pin(uint32_t block_id); - BufferHandle PinInternal(uint32_t block_id); - - bool HasBlocks() const { - return !blocks.empty(); - } - -private: - void AllocateBuffer(idx_t size, uint32_t &block_id, uint32_t &offset, ChunkManagementState *chunk_state); - void AllocateMemory(idx_t size, uint32_t &block_id, uint32_t &offset, ChunkManagementState *chunk_state); - void AssignPointer(uint32_t &block_id, uint32_t &offset, data_ptr_t pointer); - -private: - ColumnDataAllocatorType type; - union { - //! The allocator object (if this is a IN_MEMORY_ALLOCATOR) - Allocator *allocator; - //! The buffer manager (if this is a BUFFER_MANAGER_ALLOCATOR) - BufferManager *buffer_manager; - } alloc; - //! The set of blocks used by the column data collection - vector blocks; - //! The set of allocated data - vector allocated_data; - //! Whether this ColumnDataAllocator is shared across ColumnDataCollections that allocate in parallel - bool shared = false; - //! Lock used in case this ColumnDataAllocator is shared across threads - mutex lock; -}; - -} // namespace duckdb - - - -namespace duckdb { - -//! Local state for parallel partitioning -struct PartitionedColumnDataAppendState { -public: - PartitionedColumnDataAppendState() : partition_indices(LogicalType::UBIGINT) { - } - -public: - Vector partition_indices; - SelectionVector partition_sel; - DataChunk slice_chunk; - - vector> partition_buffers; - vector> partition_append_states; -}; - -enum class PartitionedColumnDataType : uint8_t { RADIX, INVALID }; - -//! Shared allocators for parallel partitioning -struct PartitionAllocators { - mutex lock; - vector> allocators; -}; - -//! PartitionedColumnData represents partitioned columnar data, which serves as an interface for different types of -//! partitioning, e.g., radix, hive -class PartitionedColumnData { -public: - unique_ptr CreateShared(); - virtual ~PartitionedColumnData(); - -public: - //! Initializes a local state for parallel partitioning that can be merged into this PartitionedColumnData - void InitializeAppendState(PartitionedColumnDataAppendState &state) const; - //! Appends a DataChunk to this PartitionedColumnData - void Append(PartitionedColumnDataAppendState &state, DataChunk &input); - //! Flushes any remaining data in the append state into this PartitionedColumnData - void FlushAppendState(PartitionedColumnDataAppendState &state); - //! Combine another PartitionedColumnData into this PartitionedColumnData - void Combine(PartitionedColumnData &other); - //! Get the partitions in this PartitionedColumnData - vector> &GetPartitions(); - -protected: - //===--------------------------------------------------------------------===// - // Partitioning type implementation interface - //===--------------------------------------------------------------------===// - //! Size of the buffers in the append states for this type of partitioning (default 128) - virtual idx_t BufferSize() const { - return MinValue(128, STANDARD_VECTOR_SIZE); - } - //! Initialize a PartitionedColumnDataAppendState for this type of partitioning (optional) - virtual void InitializeAppendStateInternal(PartitionedColumnDataAppendState &state) const { - } - //! Compute the partition indices for this type of partitioning for the input DataChunk and store them in the - //! `partition_data` of the local state. If this type creates partitions on the fly (for, e.g., hive), this - //! function is also in charge of creating new partitions and mapping the input data to a partition index - virtual void ComputePartitionIndices(PartitionedColumnDataAppendState &state, DataChunk &input) { - throw NotImplementedException("ComputePartitionIndices for this type of PartitionedColumnData"); - } - -protected: - //! PartitionedColumnData can only be instantiated by derived classes - PartitionedColumnData(PartitionedColumnDataType type, ClientContext &context, vector types); - PartitionedColumnData(const PartitionedColumnData &other); - - //! If the buffer is half full, we append to the partition - inline idx_t HalfBufferSize() const { - D_ASSERT((BufferSize() & (BufferSize() - 1)) == 0); // BufferSize should be a power of two - return BufferSize() / 2; - } - //! Create a new shared allocator - void CreateAllocator(); - //! Create a collection for a specific a partition - unique_ptr CreatePartitionCollection(idx_t partition_index) const { - return make_unique(allocators->allocators[partition_index], types); - } - //! Create a DataChunk used for buffering appends to the partition - unique_ptr CreatePartitionBuffer() const; - -protected: - PartitionedColumnDataType type; - ClientContext &context; - vector types; - - mutex lock; - shared_ptr allocators; - vector> partitions; -}; - -} // namespace duckdb namespace duckdb { @@ -39134,6 +41804,10 @@ class RadixPartitionedColumnData : public PartitionedColumnData { RadixPartitionedColumnData(const RadixPartitionedColumnData &other); ~RadixPartitionedColumnData() override; + idx_t GetRadixBits() const { + return radix_bits; + } + protected: //===--------------------------------------------------------------------===// // Radix Partitioning interface implementation @@ -39301,7 +41975,7 @@ struct RowOperations { namespace duckdb { template -RETURN_TYPE RadixBitsSwitch(idx_t radix_bits, ARGS &&...args) { +RETURN_TYPE RadixBitsSwitch(idx_t radix_bits, ARGS &&... args) { D_ASSERT(radix_bits <= sizeof(hash_t) * 8); switch (radix_bits) { case 1: @@ -39330,7 +42004,7 @@ RETURN_TYPE RadixBitsSwitch(idx_t radix_bits, ARGS &&...args) { } template -RETURN_TYPE DoubleRadixBitsSwitch2(idx_t radix_bits_2, ARGS &&...args) { +RETURN_TYPE DoubleRadixBitsSwitch2(idx_t radix_bits_2, ARGS &&... args) { D_ASSERT(radix_bits_2 <= sizeof(hash_t) * 8); switch (radix_bits_2) { case 1: @@ -39359,7 +42033,7 @@ RETURN_TYPE DoubleRadixBitsSwitch2(idx_t radix_bits_2, ARGS &&...args) { } template -RETURN_TYPE DoubleRadixBitsSwitch1(idx_t radix_bits_1, idx_t radix_bits_2, ARGS &&...args) { +RETURN_TYPE DoubleRadixBitsSwitch1(idx_t radix_bits_1, idx_t radix_bits_2, ARGS &&... args) { D_ASSERT(radix_bits_1 <= sizeof(hash_t) * 8); switch (radix_bits_1) { case 1: @@ -39712,7 +42386,7 @@ void RadixPartitioning::PartitionRowData(BufferManager &buffer_manager, const Ro //===--------------------------------------------------------------------===// RadixPartitionedColumnData::RadixPartitionedColumnData(ClientContext &context_p, vector types_p, idx_t radix_bits_p, idx_t hash_col_idx_p) - : PartitionedColumnData(PartitionedColumnDataType::RADIX, context_p, move(types_p)), radix_bits(radix_bits_p), + : PartitionedColumnData(PartitionedColumnDataType::RADIX, context_p, std::move(types_p)), radix_bits(radix_bits_p), hash_col_idx(hash_col_idx_p) { D_ASSERT(hash_col_idx < types.size()); const auto num_partitions = RadixPartitioning::NumberOfPartitions(radix_bits); @@ -39725,6 +42399,7 @@ RadixPartitionedColumnData::RadixPartitionedColumnData(ClientContext &context_p, RadixPartitionedColumnData::RadixPartitionedColumnData(const RadixPartitionedColumnData &other) : PartitionedColumnData(other), radix_bits(other.radix_bits), hash_col_idx(other.hash_col_idx) { + for (idx_t i = 0; i < RadixPartitioning::NumberOfPartitions(radix_bits); i++) { partitions.emplace_back(CreatePartitionCollection(i)); } @@ -43534,7 +46209,7 @@ void RowOperations::InitializeStates(RowLayout &layout, Vector &addresses, const auto &offsets = layout.GetOffsets(); auto aggr_idx = layout.ColumnCount(); - for (auto &aggr : layout.GetAggregates()) { + for (const auto &aggr : layout.GetAggregates()) { for (idx_t i = 0; i < count; ++i) { auto row_idx = sel.get_index(i); auto row = pointers[row_idx]; @@ -43550,7 +46225,7 @@ void RowOperations::DestroyStates(RowLayout &layout, Vector &addresses, idx_t co } // Move to the first aggregate state VectorOperations::AddInPlace(addresses, layout.GetAggrOffset(), count); - for (auto &aggr : layout.GetAggregates()) { + for (const auto &aggr : layout.GetAggregates()) { if (aggr.function.destructor) { aggr.function.destructor(addresses, count); } @@ -43995,7 +46670,6 @@ void RowOperations::Gather(Vector &rows, const SelectionVector &row_sel, Vector GatherVarchar(rows, row_sel, col, col_sel, count, layout, col_no, build_size, heap_ptr); break; case PhysicalType::LIST: - case PhysicalType::MAP: case PhysicalType::STRUCT: GatherNestedVector(rows, row_sel, col, col_sel, count, layout, col_no, heap_ptr); break; @@ -44878,7 +47552,6 @@ static void TemplatedMatchOp(Vector &vec, UnifiedVectorFormat &col, const RowLay no_match_count); break; case PhysicalType::LIST: - case PhysicalType::MAP: case PhysicalType::STRUCT: TemplatedMatchNested(vec, rows, sel, count, layout, col_no, no_match, no_match_count); break; @@ -45356,7 +48029,6 @@ void RowOperations::Scatter(DataChunk &columns, UnifiedVectorFormat col_data[], ComputeStringEntrySizes(col, entry_sizes, sel, count); break; case PhysicalType::LIST: - case PhysicalType::MAP: case PhysicalType::STRUCT: RowOperations::ComputeEntrySizes(vec, col, entry_sizes, vcount, count, sel); break; @@ -45428,7 +48100,6 @@ void RowOperations::Scatter(DataChunk &columns, UnifiedVectorFormat col_data[], ScatterStringVector(col, rows, data_locations, sel, count, col_offset, col_no); break; case PhysicalType::LIST: - case PhysicalType::MAP: case PhysicalType::STRUCT: ScatterNestedVector(vec, col, rows, data_locations, sel, count, col_offset, col_no, vcount); break; @@ -45680,7 +48351,7 @@ BufferedSerializer::BufferedSerializer(idx_t maximum_size) BufferedSerializer::BufferedSerializer(unique_ptr data, idx_t size) : maximum_size(size), data(data.get()) { blob.size = 0; - blob.data = move(data); + blob.data = std::move(data); } BufferedSerializer::BufferedSerializer(data_ptr_t data, idx_t size) : maximum_size(size), data(data) { @@ -45787,7 +48458,7 @@ int Comparators::CompareVal(const data_ptr_t l_ptr, const data_ptr_t r_ptr, cons case PhysicalType::STRUCT: { auto l_nested_ptr = Load(l_ptr); auto r_nested_ptr = Load(r_ptr); - return CompareValAndAdvance(l_nested_ptr, r_nested_ptr, type); + return CompareValAndAdvance(l_nested_ptr, r_nested_ptr, type, true); } default: throw NotImplementedException("Unimplemented CompareVal for type %s", type.ToString()); @@ -45842,7 +48513,7 @@ int Comparators::TemplatedCompareVal(const data_ptr_t &left_ptr, const data_ptr_ } } -int Comparators::CompareValAndAdvance(data_ptr_t &l_ptr, data_ptr_t &r_ptr, const LogicalType &type) { +int Comparators::CompareValAndAdvance(data_ptr_t &l_ptr, data_ptr_t &r_ptr, const LogicalType &type, bool valid) { switch (type.InternalType()) { case PhysicalType::BOOL: case PhysicalType::INT8: @@ -45870,11 +48541,11 @@ int Comparators::CompareValAndAdvance(data_ptr_t &l_ptr, data_ptr_t &r_ptr, cons case PhysicalType::INTERVAL: return TemplatedCompareAndAdvance(l_ptr, r_ptr); case PhysicalType::VARCHAR: - return CompareStringAndAdvance(l_ptr, r_ptr); + return CompareStringAndAdvance(l_ptr, r_ptr, valid); case PhysicalType::LIST: - return CompareListAndAdvance(l_ptr, r_ptr, ListType::GetChildType(type)); + return CompareListAndAdvance(l_ptr, r_ptr, ListType::GetChildType(type), valid); case PhysicalType::STRUCT: - return CompareStructAndAdvance(l_ptr, r_ptr, StructType::GetChildTypes(type)); + return CompareStructAndAdvance(l_ptr, r_ptr, StructType::GetChildTypes(type), valid); default: throw NotImplementedException("Unimplemented CompareValAndAdvance for type %s", type.ToString()); } @@ -45888,7 +48559,10 @@ int Comparators::TemplatedCompareAndAdvance(data_ptr_t &left_ptr, data_ptr_t &ri return result; } -int Comparators::CompareStringAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr) { +int Comparators::CompareStringAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr, bool valid) { + if (!valid) { + return 0; + } // Construct the string_t uint32_t left_string_size = Load(left_ptr); uint32_t right_string_size = Load(right_ptr); @@ -45903,7 +48577,7 @@ int Comparators::CompareStringAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right } int Comparators::CompareStructAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr, - const child_list_t &types) { + const child_list_t &types, bool valid) { idx_t count = types.size(); // Load validity masks ValidityBytes left_validity(left_ptr); @@ -45922,8 +48596,8 @@ int Comparators::CompareStructAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right left_valid = left_validity.RowIsValid(left_validity.GetValidityEntry(entry_idx), idx_in_entry); right_valid = right_validity.RowIsValid(right_validity.GetValidityEntry(entry_idx), idx_in_entry); auto &type = types[i].second; - if ((left_valid && right_valid) || TypeIsConstantSize(type.InternalType())) { - comp_res = CompareValAndAdvance(left_ptr, right_ptr, types[i].second); + if ((left_valid == right_valid) || TypeIsConstantSize(type.InternalType())) { + comp_res = CompareValAndAdvance(left_ptr, right_ptr, types[i].second, left_valid && valid); } if (!left_valid && !right_valid) { comp_res = 0; @@ -45939,7 +48613,11 @@ int Comparators::CompareStructAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right return comp_res; } -int Comparators::CompareListAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr, const LogicalType &type) { +int Comparators::CompareListAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_ptr, const LogicalType &type, + bool valid) { + if (!valid) { + return 0; + } // Load list lengths auto left_len = Load(left_ptr); auto right_len = Load(right_ptr); @@ -46013,13 +48691,14 @@ int Comparators::CompareListAndAdvance(data_ptr_t &left_ptr, data_ptr_t &right_p if (left_valid && right_valid) { switch (type.InternalType()) { case PhysicalType::LIST: - comp_res = CompareListAndAdvance(left_ptr, right_ptr, ListType::GetChildType(type)); + comp_res = CompareListAndAdvance(left_ptr, right_ptr, ListType::GetChildType(type), left_valid); break; case PhysicalType::VARCHAR: - comp_res = CompareStringAndAdvance(left_ptr, right_ptr); + comp_res = CompareStringAndAdvance(left_ptr, right_ptr, left_valid); break; case PhysicalType::STRUCT: - comp_res = CompareStructAndAdvance(left_ptr, right_ptr, StructType::GetChildTypes(type)); + comp_res = + CompareStructAndAdvance(left_ptr, right_ptr, StructType::GetChildTypes(type), left_valid); break; default: throw NotImplementedException("CompareListAndAdvance for variable-size type %s", type.ToString()); @@ -46427,8 +49106,8 @@ void MergeSorter::MergeRadix(const idx_t &count, const bool left_smaller[]) { auto &l_blocks = l.sb->radix_sorting_data; auto &r_blocks = r.sb->radix_sorting_data; - RowDataBlock *l_block; - RowDataBlock *r_block; + RowDataBlock *l_block = nullptr; + RowDataBlock *r_block = nullptr; data_ptr_t l_ptr; data_ptr_t r_ptr; @@ -46457,18 +49136,24 @@ void MergeSorter::MergeRadix(const idx_t &count, const bool left_smaller[]) { const bool l_done = l.block_idx == l_blocks.size(); const bool r_done = r.block_idx == r_blocks.size(); // Pin the radix sortable blocks + idx_t l_count; if (!l_done) { l_block = l_blocks[l.block_idx].get(); left->PinRadix(l.block_idx); l_ptr = l.RadixPtr(); + l_count = l_block->count; + } else { + l_count = 0; } + idx_t r_count; if (!r_done) { r_block = r_blocks[r.block_idx].get(); r.PinRadix(r.block_idx); r_ptr = r.RadixPtr(); + r_count = r_block->count; + } else { + r_count = 0; } - const idx_t &l_count = !l_done ? l_block->count : 0; - const idx_t &r_count = !r_done ? r_block->count : 0; // Copy using computed merge if (!l_done && !r_done) { // Both sides have data - merge @@ -46513,7 +49198,7 @@ void MergeSorter::MergeData(SortedData &result_data, SortedData &l_data, SortedD auto result_data_handle = buffer_manager.Pin(result_data_block->block); data_ptr_t result_data_ptr = result_data_handle.Ptr() + result_data_block->count * row_width; // Result heap to write to (if needed) - RowDataBlock *result_heap_block; + RowDataBlock *result_heap_block = nullptr; BufferHandle result_heap_handle; data_ptr_t result_heap_ptr; if (!layout.AllConstant() && state.external) { @@ -47803,6 +50488,8 @@ void LocalSortState::SortInMemory() { + +#include #include namespace duckdb { @@ -47825,7 +50512,6 @@ idx_t GetNestedSortingColSize(idx_t &col_size, const LogicalType &type) { // Lists get 2 bytes (null and empty list) col_size += 2; return GetNestedSortingColSize(col_size, ListType::GetChildType(type)); - case PhysicalType::MAP: case PhysicalType::STRUCT: // Structs get 1 bytes (null) col_size++; @@ -48036,16 +50722,16 @@ void LocalSortState::Sort(GlobalSortState &global_sort_state, bool reorder_heap) auto &sb = *sorted_blocks.back(); // Fixed-size sorting data auto sorting_block = ConcatenateBlocks(*radix_sorting_data); - sb.radix_sorting_data.push_back(move(sorting_block)); + sb.radix_sorting_data.push_back(std::move(sorting_block)); // Variable-size sorting data if (!sort_layout->all_constant) { auto &blob_data = *blob_sorting_data; auto new_block = ConcatenateBlocks(blob_data); - sb.blob_sorting_data->data_blocks.push_back(move(new_block)); + sb.blob_sorting_data->data_blocks.push_back(std::move(new_block)); } // Payload data auto payload_block = ConcatenateBlocks(*payload_data); - sb.payload_data->data_blocks.push_back(move(payload_block)); + sb.payload_data->data_blocks.push_back(std::move(payload_block)); // Now perform the actual sort SortInMemory(); // Re-order before the merge sort @@ -48055,7 +50741,7 @@ void LocalSortState::Sort(GlobalSortState &global_sort_state, bool reorder_heap) unique_ptr LocalSortState::ConcatenateBlocks(RowDataCollection &row_data) { // Don't copy and delete if there is only one block. if (row_data.blocks.size() == 1) { - auto new_block = move(row_data.blocks[0]); + auto new_block = std::move(row_data.blocks[0]); row_data.blocks.clear(); row_data.count = 0; return new_block; @@ -48069,10 +50755,12 @@ unique_ptr LocalSortState::ConcatenateBlocks(RowDataCollection &ro auto new_block_handle = buffer_manager->Pin(new_block->block); data_ptr_t new_block_ptr = new_block_handle.Ptr(); // Copy the data of the blocks into a single block - for (auto &block : row_data.blocks) { + for (idx_t i = 0; i < row_data.blocks.size(); i++) { + auto &block = row_data.blocks[i]; auto block_handle = buffer_manager->Pin(block->block); memcpy(new_block_ptr, block_handle.Ptr(), block->count * entry_size); new_block_ptr += block->count * entry_size; + block.reset(); } row_data.blocks.clear(); row_data.count = 0; @@ -48101,10 +50789,10 @@ void LocalSortState::ReOrder(SortedData &sd, data_ptr_t sorting_ptr, RowDataColl ordered_data_ptr += row_width; sorting_ptr += sorting_entry_size; } - ordered_data_block->block->SetSwizzling(sd.layout.AllConstant() ? nullptr : "LocalSortState::ReOrder.ordered_data"); + ordered_data_block->block->SetSwizzling(sd.swizzled ? "LocalSortState::ReOrder.ordered_data" : nullptr); // Replace the unordered data block with the re-ordered data block sd.data_blocks.clear(); - sd.data_blocks.push_back(move(ordered_data_block)); + sd.data_blocks.push_back(std::move(ordered_data_block)); // Deal with the heap (if necessary) if (!sd.layout.AllConstant() && reorder_heap) { // Swizzle the column pointers to offsets @@ -48133,7 +50821,7 @@ void LocalSortState::ReOrder(SortedData &sd, data_ptr_t sorting_ptr, RowDataColl // Swizzle the base pointer to the offset of each row in the heap RowOperations::SwizzleHeapPointer(sd.layout, ordered_data_handle.Ptr(), ordered_heap_handle.Ptr(), count); // Move the re-ordered heap to the SortedData, and clear the local heap - sd.heap_blocks.push_back(move(ordered_heap_block)); + sd.heap_blocks.push_back(std::move(ordered_heap_block)); heap.pinned_blocks.clear(); heap.blocks.clear(); heap.count = 0; @@ -48172,18 +50860,18 @@ void GlobalSortState::AddLocalState(LocalSortState &local_sort_state) { // Append local state sorted data to this global state lock_guard append_guard(lock); for (auto &sb : local_sort_state.sorted_blocks) { - sorted_blocks.push_back(move(sb)); + sorted_blocks.push_back(std::move(sb)); } auto &payload_heap = local_sort_state.payload_heap; for (idx_t i = 0; i < payload_heap->blocks.size(); i++) { - heap_blocks.push_back(move(payload_heap->blocks[i])); - pinned_blocks.push_back(move(payload_heap->pinned_blocks[i])); + heap_blocks.push_back(std::move(payload_heap->blocks[i])); + pinned_blocks.push_back(std::move(payload_heap->pinned_blocks[i])); } if (!sort_layout.all_constant) { auto &blob_heap = local_sort_state.blob_sorting_heap; for (idx_t i = 0; i < blob_heap->blocks.size(); i++) { - heap_blocks.push_back(move(blob_heap->blocks[i])); - pinned_blocks.push_back(move(blob_heap->pinned_blocks[i])); + heap_blocks.push_back(std::move(blob_heap->blocks[i])); + pinned_blocks.push_back(std::move(blob_heap->pinned_blocks[i])); } } } @@ -48228,7 +50916,7 @@ void GlobalSortState::InitializeMergeRound() { std::reverse(sorted_blocks.begin(), sorted_blocks.end()); // Uneven number of blocks - keep one on the side if (sorted_blocks.size() % 2 == 1) { - odd_one_out = move(sorted_blocks.back()); + odd_one_out = std::move(sorted_blocks.back()); sorted_blocks.pop_back(); } // Init merge path path indices @@ -48250,7 +50938,7 @@ void GlobalSortState::CompleteMergeRound(bool keep_radix_data) { } sorted_blocks_temp.clear(); if (odd_one_out) { - sorted_blocks.push_back(move(odd_one_out)); + sorted_blocks.push_back(std::move(odd_one_out)); odd_one_out = nullptr; } // Only one block left: Done! @@ -48287,7 +50975,7 @@ namespace duckdb { SortedData::SortedData(SortedDataType type, const RowLayout &layout, BufferManager &buffer_manager, GlobalSortState &state) - : type(type), layout(layout), swizzled(false), buffer_manager(buffer_manager), state(state) { + : type(type), layout(layout), swizzled(state.external), buffer_manager(buffer_manager), state(state) { } idx_t SortedData::Count() { @@ -48347,9 +51035,10 @@ void SortedData::Unswizzle() { auto heap_handle_p = buffer_manager.Pin(heap_block->block); RowOperations::UnswizzlePointers(layout, data_handle_p.Ptr(), heap_handle_p.Ptr(), data_block->count); data_block->block->SetSwizzling("SortedData::Unswizzle"); - state.heap_blocks.push_back(move(heap_block)); - state.pinned_blocks.push_back(move(heap_handle_p)); + state.heap_blocks.push_back(std::move(heap_block)); + state.pinned_blocks.push_back(std::move(heap_handle_p)); } + swizzled = false; heap_blocks.clear(); } @@ -48388,22 +51077,22 @@ void SortedBlock::AppendSortedBlocks(vector> &sorted_blo D_ASSERT(Count() == 0); for (auto &sb : sorted_blocks) { for (auto &radix_block : sb->radix_sorting_data) { - radix_sorting_data.push_back(move(radix_block)); + radix_sorting_data.push_back(std::move(radix_block)); } if (!sort_layout.all_constant) { for (auto &blob_block : sb->blob_sorting_data->data_blocks) { - blob_sorting_data->data_blocks.push_back(move(blob_block)); + blob_sorting_data->data_blocks.push_back(std::move(blob_block)); } for (auto &heap_block : sb->blob_sorting_data->heap_blocks) { - blob_sorting_data->heap_blocks.push_back(move(heap_block)); + blob_sorting_data->heap_blocks.push_back(std::move(heap_block)); } } for (auto &payload_data_block : sb->payload_data->data_blocks) { - payload_data->data_blocks.push_back(move(payload_data_block)); + payload_data->data_blocks.push_back(std::move(payload_data_block)); } if (!payload_data->layout.AllConstant()) { for (auto &payload_heap_block : sb->payload_data->heap_blocks) { - payload_data->heap_blocks.push_back(move(payload_heap_block)); + payload_data->heap_blocks.push_back(std::move(payload_heap_block)); } } } @@ -48575,9 +51264,9 @@ PayloadScanner::PayloadScanner(SortedData &sorted_data, GlobalSortState &global_ if (flush_p) { // If we are flushing, we can just move the data - rows->blocks = move(sorted_data.data_blocks); + rows->blocks = std::move(sorted_data.data_blocks); if (!layout.AllConstant()) { - heap->blocks = move(sorted_data.heap_blocks); + heap->blocks = std::move(sorted_data.heap_blocks); } } else { // Not flushing, create references to the blocks @@ -48598,23 +51287,31 @@ PayloadScanner::PayloadScanner(GlobalSortState &global_sort_state, bool flush_p) : PayloadScanner(*global_sort_state.sorted_blocks[0]->payload_data, global_sort_state, flush_p) { } -PayloadScanner::PayloadScanner(GlobalSortState &global_sort_state, idx_t block_idx) { +PayloadScanner::PayloadScanner(GlobalSortState &global_sort_state, idx_t block_idx, bool flush_p) { auto &sorted_data = *global_sort_state.sorted_blocks[0]->payload_data; auto count = sorted_data.data_blocks[block_idx]->count; auto &layout = sorted_data.layout; // Create collections to put the data into so we can use RowDataCollectionScanner rows = make_unique(global_sort_state.buffer_manager, (idx_t)Storage::BLOCK_SIZE, 1); - rows->blocks.emplace_back(sorted_data.data_blocks[block_idx]->Copy()); + if (flush_p) { + rows->blocks.emplace_back(std::move(sorted_data.data_blocks[block_idx])); + } else { + rows->blocks.emplace_back(sorted_data.data_blocks[block_idx]->Copy()); + } rows->count = count; heap = make_unique(global_sort_state.buffer_manager, (idx_t)Storage::BLOCK_SIZE, 1); if (!sorted_data.layout.AllConstant() && sorted_data.swizzled) { - heap->blocks.emplace_back(sorted_data.heap_blocks[block_idx]->Copy()); + if (flush_p) { + heap->blocks.emplace_back(std::move(sorted_data.heap_blocks[block_idx])); + } else { + heap->blocks.emplace_back(sorted_data.heap_blocks[block_idx]->Copy()); + } heap->count = count; } - scanner = make_unique(*rows, *heap, layout, global_sort_state.external, false); + scanner = make_unique(*rows, *heap, layout, global_sort_state.external, flush_p); } void PayloadScanner::Scan(DataChunk &chunk) { @@ -48651,6 +51348,7 @@ SBIterator::SBIterator(GlobalSortState &gss, ExpressionType comparison, idx_t en + #include #include #include @@ -48667,7 +51365,7 @@ bool StringUtil::Contains(const string &haystack, const string &needle) { void StringUtil::LTrim(string &str) { auto it = str.begin(); - while (CharacterIsSpace(*it)) { + while (it != str.end() && CharacterIsSpace(*it)) { it++; } str.erase(str.begin(), it); @@ -48679,6 +51377,13 @@ void StringUtil::RTrim(string &str) { str.end()); } +void StringUtil::RTrim(string &str, const string &chars_to_trim) { + str.erase(find_if(str.rbegin(), str.rend(), + [&chars_to_trim](int ch) { return ch > 0 && chars_to_trim.find(ch) == string::npos; }) + .base(), + str.end()); +} + void StringUtil::Trim(string &str) { StringUtil::LTrim(str); StringUtil::RTrim(str); @@ -48813,6 +51518,10 @@ string StringUtil::Lower(const string &str) { return (copy); } +bool StringUtil::CIEquals(const string &l1, const string &l2) { + return StringUtil::Lower(l1) == StringUtil::Lower(l2); +} + vector StringUtil::Split(const string &input, const string &split) { vector splits; @@ -49047,7 +51756,7 @@ struct TreeRendererConfig { class TreeRenderer { public: - explicit TreeRenderer(TreeRendererConfig config_p = TreeRendererConfig()) : config(move(config_p)) { + explicit TreeRenderer(TreeRendererConfig config_p = TreeRendererConfig()) : config(std::move(config_p)) { } string ToString(const LogicalOperator &op); @@ -49150,8 +51859,8 @@ class ClientContext; */ class ChunkCollection { public: - ChunkCollection(Allocator &allocator); - ChunkCollection(ClientContext &context); + explicit ChunkCollection(Allocator &allocator); + explicit ChunkCollection(ClientContext &context); //! The types of columns in the ChunkCollection DUCKDB_API vector &Types() { @@ -49233,18 +51942,11 @@ class ChunkCollection { return nullptr; } - auto res = move(chunks[0]); + auto res = std::move(chunks[0]); chunks.erase(chunks.begin() + 0); return res; } - DUCKDB_API void Sort(vector &desc, vector &null_order, idx_t result[]); - //! Reorders the rows in the collection according to the given indices. - DUCKDB_API void Reorder(idx_t order[]); - - //! Returns true if the ChunkCollections are equivalent - DUCKDB_API bool Equals(ChunkCollection &other); - //! Locates the chunk that belongs to the specific index DUCKDB_API idx_t LocateChunk(idx_t index) { idx_t result = index / STANDARD_VECTOR_SIZE; @@ -49972,6 +52674,48 @@ class PhysicalHashAggregate : public PhysicalOperator { } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/execution/operator/scan/physical_positional_scan.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + + +namespace duckdb { + +//! Represents a scan of a base table +class PhysicalPositionalScan : public PhysicalOperator { +public: + //! Regular Table Scan + PhysicalPositionalScan(vector types, unique_ptr left, + unique_ptr right); + + //! The child table functions + vector> child_tables; + +public: + bool Equals(const PhysicalOperator &other) const override; + +public: + unique_ptr GetLocalSourceState(ExecutionContext &context, + GlobalSourceState &gstate) const override; + unique_ptr GetGlobalSourceState(ClientContext &context) const override; + void GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, + LocalSourceState &lstate) const override; + + double GetProgress(ClientContext &context, GlobalSourceState &gstate) const override; +}; + +} // namespace duckdb + @@ -50003,7 +52747,7 @@ idx_t RenderTree::GetPosition(idx_t x, idx_t y) { } void RenderTree::SetNode(idx_t x, idx_t y, unique_ptr node) { - nodes[GetPosition(x, y)] = move(node); + nodes[GetPosition(x, y)] = std::move(node); } void TreeRenderer::RenderTopLayer(RenderTree &root, std::ostream &ss, idx_t y) { @@ -50323,8 +53067,8 @@ string TreeRenderer::ExtraInfoSeparator() { unique_ptr TreeRenderer::CreateRenderNode(string name, string extra_info) { auto result = make_unique(); - result->name = move(name); - result->extra_text = move(extra_info); + result->name = std::move(name); + result->extra_text = std::move(extra_info); return result; } @@ -50344,10 +53088,13 @@ class TreeChildrenIterator { template <> bool TreeChildrenIterator::HasChildren(const PhysicalOperator &op) { - if (op.type == PhysicalOperatorType::DELIM_JOIN) { + switch (op.type) { + case PhysicalOperatorType::DELIM_JOIN: + case PhysicalOperatorType::POSITIONAL_SCAN: return true; + default: + return !op.children.empty(); } - return !op.children.empty(); } template <> void TreeChildrenIterator::Iterate(const PhysicalOperator &op, @@ -50358,6 +53105,11 @@ void TreeChildrenIterator::Iterate(const PhysicalOperator &op, if (op.type == PhysicalOperatorType::DELIM_JOIN) { auto &delim = (PhysicalDelimJoin &)op; callback(*delim.join); + } else if ((op.type == PhysicalOperatorType::POSITIONAL_SCAN)) { + auto &pscan = (PhysicalPositionalScan &)op; + for (auto &table : pscan.child_tables) { + callback(*table); + } } } @@ -50404,7 +53156,7 @@ static void GetTreeWidthHeight(const T &op, idx_t &width, idx_t &height) { template idx_t TreeRenderer::CreateRenderTreeRecursive(RenderTree &result, const T &op, idx_t x, idx_t y) { auto node = TreeRenderer::CreateNode(op); - result.SetNode(x, y, move(node)); + result.SetNode(x, y, std::move(node)); if (!TreeChildrenIterator::HasChildren(op)) { return 1; @@ -50502,8 +53254,8 @@ unique_ptr TreeRenderer::CreateTree(const Pipeline &op) { unique_ptr node; for (auto &op : operators) { auto new_node = make_unique(*op); - new_node->child = move(node); - node = move(new_node); + new_node->child = std::move(node); + node = std::move(new_node); } return CreateRenderTree(*node); } @@ -50575,7 +53327,7 @@ class BatchedDataCollection { namespace duckdb { -BatchedDataCollection::BatchedDataCollection(vector types_p) : types(move(types_p)) { +BatchedDataCollection::BatchedDataCollection(vector types_p) : types(std::move(types_p)) { } void BatchedDataCollection::Append(DataChunk &input, idx_t batch_index) { @@ -50597,7 +53349,7 @@ void BatchedDataCollection::Append(DataChunk &input, idx_t batch_index) { last_collection.batch_index = batch_index; new_collection->InitializeAppend(last_collection.append_state); collection = new_collection.get(); - data.insert(make_pair(batch_index, move(new_collection))); + data.insert(make_pair(batch_index, std::move(new_collection))); } collection->Append(last_collection.append_state, input); } @@ -50610,7 +53362,7 @@ void BatchedDataCollection::Merge(BatchedDataCollection &other) { "batch indexes are not uniquely distributed over threads", entry.first); } - data[entry.first] = move(entry.second); + data[entry.first] = std::move(entry.second); } other.data.clear(); } @@ -50644,7 +53396,7 @@ unique_ptr BatchedDataCollection::FetchCollection() { unique_ptr result; for (auto &entry : data) { if (!result) { - result = move(entry.second); + result = std::move(entry.second); } else { result->Combine(*entry.second); } @@ -50676,6 +53428,284 @@ void BatchedDataCollection::Print() const { +namespace duckdb { + +void Bit::SetEmptyBitString(string_t &target, string_t &input) { + char *res_buf = target.GetDataWriteable(); + const char *buf = input.GetDataUnsafe(); + memset(res_buf, 0, input.GetSize()); + res_buf[0] = buf[0]; +} + +idx_t Bit::BitLength(string_t bits) { + return ((bits.GetSize() - 1) * 8) - GetPadding(bits); +} + +idx_t Bit::OctetLength(string_t bits) { + return bits.GetSize() - 1; +} + +idx_t Bit::BitCount(string_t bits) { + idx_t count = 0; + const char *buf = bits.GetDataUnsafe(); + for (idx_t byte_idx = 1; byte_idx < OctetLength(bits) + 1; byte_idx++) { + for (idx_t bit_idx = 0; bit_idx < 8; bit_idx++) { + count += (buf[byte_idx] & (1 << bit_idx)) ? 1 : 0; + } + } + return count; +} + +idx_t Bit::BitPosition(string_t substring, string_t bits) { + const char *buf = bits.GetDataUnsafe(); + auto len = bits.GetSize(); + auto substr_len = BitLength(substring); + idx_t substr_idx = 0; + + for (idx_t bit_idx = GetPadding(bits); bit_idx < 8; bit_idx++) { + idx_t bit = buf[1] & (1 << (7 - bit_idx)) ? 1 : 0; + if (bit == GetBit(substring, substr_idx)) { + substr_idx++; + if (substr_idx == substr_len) { + return (bit_idx - GetPadding(bits)) - substr_len + 2; + } + } else { + substr_idx = 0; + } + } + + for (idx_t byte_idx = 2; byte_idx < len; byte_idx++) { + for (idx_t bit_idx = 0; bit_idx < 8; bit_idx++) { + idx_t bit = buf[byte_idx] & (1 << (7 - bit_idx)) ? 1 : 0; + if (bit == GetBit(substring, substr_idx)) { + substr_idx++; + if (substr_idx == substr_len) { + return (((byte_idx - 1) * 8) + bit_idx - GetPadding(bits)) - substr_len + 2; + } + } else { + substr_idx = 0; + } + } + } + return 0; +} + +void Bit::ToString(string_t bits, char *output) { + auto data = (const_data_ptr_t)bits.GetDataUnsafe(); + auto len = bits.GetSize(); + + idx_t padding = GetPadding(bits); + idx_t output_idx = 0; + for (idx_t bit_idx = padding; bit_idx < 8; bit_idx++) { + output[output_idx++] = data[1] & (1 << (7 - bit_idx)) ? '1' : '0'; + } + for (idx_t byte_idx = 2; byte_idx < len; byte_idx++) { + for (idx_t bit_idx = 0; bit_idx < 8; bit_idx++) { + output[output_idx++] = data[byte_idx] & (1 << (7 - bit_idx)) ? '1' : '0'; + } + } +} + +string Bit::ToString(string_t str) { + auto len = BitLength(str); + auto buffer = std::unique_ptr(new char[len]); + ToString(str, buffer.get()); + return string(buffer.get(), len); +} + +bool Bit::TryGetBitStringSize(string_t str, idx_t &str_len, string *error_message) { + auto data = (const_data_ptr_t)str.GetDataUnsafe(); + auto len = str.GetSize(); + str_len = 0; + for (idx_t i = 0; i < len; i++) { + if (data[i] == '0' || data[i] == '1') { + str_len++; + } else { + string error = StringUtil::Format("Invalid character encountered in string -> bit conversion: '%s'", + string((char *)data + i, 1)); + HandleCastError::AssignError(error, error_message); + return false; + } + } + str_len = str_len % 8 ? (str_len / 8) + 1 : str_len / 8; + str_len++; // additional first byte to store info on zero padding + return true; +} + +idx_t Bit::GetBitSize(string_t str) { + string error_message; + idx_t str_len; + if (!Bit::TryGetBitStringSize(str, str_len, &error_message)) { + throw ConversionException(error_message); + } + return str_len; +} + +void Bit::ToBit(string_t str, data_ptr_t output) { + auto data = (const_data_ptr_t)str.GetDataUnsafe(); + auto len = str.GetSize(); + + char byte = 0; + idx_t padded_byte = len % 8; + for (idx_t i = 0; i < padded_byte; i++) { + byte <<= 1; + if (data[i] == '1') { + byte |= 1; + } + } + if (padded_byte != 0) { + *(output++) = (8 - padded_byte); // the first byte contains the number of padded zeroes + } + *(output++) = byte; + + for (idx_t byte_idx = padded_byte; byte_idx < len; byte_idx += 8) { + byte = 0; + for (idx_t bit_idx = 0; bit_idx < 8; bit_idx++) { + byte <<= 1; + if (data[byte_idx + bit_idx] == '1') { + byte |= 1; + } + } + *(output++) = byte; + } +} + +string Bit::ToBit(string_t str) { + auto bit_len = GetBitSize(str); + auto buffer = std::unique_ptr(new char[bit_len]); + Bit::ToBit(str, (data_ptr_t)buffer.get()); + return string(buffer.get(), bit_len); +} + +idx_t Bit::GetBit(string_t bit_string, idx_t n) { + const char *buf = bit_string.GetDataUnsafe(); + n += GetPadding(bit_string); + + char byte = buf[(n / 8) + 1] >> (7 - (n % 8)); + return (byte & 1 ? 1 : 0); +} + +void Bit::SetBit(const string_t &bit_string, idx_t n, idx_t new_value, string_t &result) { + char *result_buf = result.GetDataWriteable(); + const char *buf = bit_string.GetDataUnsafe(); + n += GetPadding(bit_string); + + memcpy(result_buf, buf, bit_string.GetSize()); + char shift_byte = 1 << (7 - (n % 8)); + if (new_value == 0) { + shift_byte = ~shift_byte; + result_buf[(n / 8) + 1] = buf[(n / 8) + 1] & shift_byte; + } else { + result_buf[(n / 8) + 1] = buf[(n / 8) + 1] | shift_byte; + } +} + +void Bit::SetBit(string_t &bit_string, idx_t n, idx_t new_value) { + char *buf = bit_string.GetDataWriteable(); + n += GetPadding(bit_string); + + char shift_byte = 1 << (7 - (n % 8)); + if (new_value == 0) { + shift_byte = ~shift_byte; + buf[(n / 8) + 1] &= shift_byte; + } else { + buf[(n / 8) + 1] |= shift_byte; + } +} + +inline idx_t Bit::GetPadding(const string_t &bit_string) { + auto data = (const_data_ptr_t)bit_string.GetDataUnsafe(); + return data[0]; +} + +// **** BITWISE OPERATORS **** +void Bit::RightShift(const string_t &bit_string, const idx_t &shift, string_t &result) { + char *res_buf = result.GetDataWriteable(); + const char *buf = bit_string.GetDataUnsafe(); + res_buf[0] = buf[0]; + for (idx_t i = 0; i < Bit::BitLength(result); i++) { + if (i < shift) { + Bit::SetBit(result, i, 0); + } else { + idx_t bit = Bit::GetBit(bit_string, i - shift); + Bit::SetBit(result, i, bit); + } + } +} + +void Bit::LeftShift(const string_t &bit_string, const idx_t &shift, string_t &result) { + char *res_buf = result.GetDataWriteable(); + const char *buf = bit_string.GetDataUnsafe(); + res_buf[0] = buf[0]; + for (idx_t i = 0; i < Bit::BitLength(bit_string); i++) { + if (i < (Bit::BitLength(bit_string) - shift)) { + idx_t bit = Bit::GetBit(bit_string, shift + i); + Bit::SetBit(result, i, bit); + } else { + Bit::SetBit(result, i, 0); + } + } +} + +void Bit::BitwiseAnd(const string_t &rhs, const string_t &lhs, string_t &result) { + if (Bit::BitLength(lhs) != Bit::BitLength(rhs)) { + throw InvalidInputException("Cannot AND bit strings of different sizes"); + } + + char *buf = result.GetDataWriteable(); + const char *r_buf = rhs.GetDataUnsafe(); + const char *l_buf = lhs.GetDataUnsafe(); + + buf[0] = l_buf[0]; + for (idx_t i = 1; i < lhs.GetSize(); i++) { + buf[i] = l_buf[i] & r_buf[i]; + } +} + +void Bit::BitwiseOr(const string_t &rhs, const string_t &lhs, string_t &result) { + if (Bit::BitLength(lhs) != Bit::BitLength(rhs)) { + throw InvalidInputException("Cannot OR bit strings of different sizes"); + } + + char *buf = result.GetDataWriteable(); + const char *r_buf = rhs.GetDataUnsafe(); + const char *l_buf = lhs.GetDataUnsafe(); + + buf[0] = l_buf[0]; + for (idx_t i = 1; i < lhs.GetSize(); i++) { + buf[i] = l_buf[i] | r_buf[i]; + } +} + +void Bit::BitwiseXor(const string_t &rhs, const string_t &lhs, string_t &result) { + if (Bit::BitLength(lhs) != Bit::BitLength(rhs)) { + throw InvalidInputException("Cannot XOR bit strings of different sizes"); + } + + char *buf = result.GetDataWriteable(); + const char *r_buf = rhs.GetDataUnsafe(); + const char *l_buf = lhs.GetDataUnsafe(); + + buf[0] = l_buf[0]; + for (idx_t i = 1; i < lhs.GetSize(); i++) { + buf[i] = l_buf[i] ^ r_buf[i]; + } +} + +void Bit::BitwiseNot(const string_t &input, string_t &result) { + char *result_buf = result.GetDataWriteable(); + const char *buf = input.GetDataUnsafe(); + + result_buf[0] = buf[0]; + for (idx_t i = 1; i < input.GetSize(); i++) { + result_buf[i] = ~buf[i]; + } +} +} // namespace duckdb + + + + @@ -51135,19 +54165,19 @@ void ChunkCollection::Merge(ChunkCollection &other) { return; } if (count == 0) { - chunks = move(other.chunks); - types = move(other.types); + chunks = std::move(other.chunks); + types = std::move(other.types); count = other.count; return; } unique_ptr old_back; if (!chunks.empty() && chunks.back()->size() != STANDARD_VECTOR_SIZE) { - old_back = move(chunks.back()); + old_back = std::move(chunks.back()); chunks.pop_back(); count -= old_back->size(); } for (auto &chunk : other.chunks) { - chunks.push_back(move(chunk)); + chunks.push_back(std::move(chunk)); } count += other.count; if (old_back) { @@ -51219,7 +54249,7 @@ void ChunkCollection::Append(DataChunk &new_chunk) { auto chunk = make_unique(); chunk->Initialize(allocator, types); new_chunk.Copy(*chunk, offset); - chunks.push_back(move(chunk)); + chunks.push_back(std::move(chunk)); } } @@ -51229,7 +54259,7 @@ void ChunkCollection::Append(unique_ptr new_chunk) { } D_ASSERT(types == new_chunk->GetTypes()); count += new_chunk->size(); - chunks.push_back(move(new_chunk)); + chunks.push_back(std::move(new_chunk)); } void ChunkCollection::Fuse(ChunkCollection &other) { @@ -51243,7 +54273,7 @@ void ChunkCollection::Fuse(ChunkCollection &other) { lhs->data.emplace_back(Vector(v)); } lhs->SetCardinality(rhs.size()); - chunks.push_back(move(lhs)); + chunks.push_back(std::move(lhs)); } count = other.Count(); } else { @@ -51260,267 +54290,6 @@ void ChunkCollection::Fuse(ChunkCollection &other) { types.insert(types.end(), other.types.begin(), other.types.end()); } -// returns an int similar to a C comparator: -// -1 if left < right -// 0 if left == right -// 1 if left > right - -template -static int8_t TemplatedCompareValue(Vector &left_vec, Vector &right_vec, idx_t left_idx, idx_t right_idx) { - D_ASSERT(left_vec.GetType() == right_vec.GetType()); - auto left_val = FlatVector::GetData(left_vec)[left_idx]; - auto right_val = FlatVector::GetData(right_vec)[right_idx]; - if (Equals::Operation(left_val, right_val)) { - return 0; - } - if (LessThan::Operation(left_val, right_val)) { - return -1; - } - return 1; -} - -template <> -int8_t TemplatedCompareValue(Vector &left_vec, Vector &right_vec, idx_t left_idx, idx_t right_idx) { - auto left_val = left_vec.GetValue(left_idx); - auto right_val = right_vec.GetValue(right_idx); - if (ValueOperations::Equals(left_val, right_val)) { - return 0; - } - if (ValueOperations::LessThan(left_val, right_val)) { - return -1; - } - return 1; -} - -// return type here is int32 because strcmp() on some platforms returns rather large values -static int32_t CompareValue(Vector &left_vec, Vector &right_vec, idx_t vector_idx_left, idx_t vector_idx_right, - OrderByNullType null_order) { - auto left_null = FlatVector::IsNull(left_vec, vector_idx_left); - auto right_null = FlatVector::IsNull(right_vec, vector_idx_right); - - if (left_null && right_null) { - return 0; - } else if (right_null) { - return null_order == OrderByNullType::NULLS_FIRST ? 1 : -1; - } else if (left_null) { - return null_order == OrderByNullType::NULLS_FIRST ? -1 : 1; - } - - switch (left_vec.GetType().InternalType()) { - case PhysicalType::BOOL: - case PhysicalType::INT8: - return TemplatedCompareValue(left_vec, right_vec, vector_idx_left, vector_idx_right); - case PhysicalType::INT16: - return TemplatedCompareValue(left_vec, right_vec, vector_idx_left, vector_idx_right); - case PhysicalType::INT32: - return TemplatedCompareValue(left_vec, right_vec, vector_idx_left, vector_idx_right); - case PhysicalType::INT64: - return TemplatedCompareValue(left_vec, right_vec, vector_idx_left, vector_idx_right); - case PhysicalType::UINT8: - return TemplatedCompareValue(left_vec, right_vec, vector_idx_left, vector_idx_right); - case PhysicalType::UINT16: - return TemplatedCompareValue(left_vec, right_vec, vector_idx_left, vector_idx_right); - case PhysicalType::UINT32: - return TemplatedCompareValue(left_vec, right_vec, vector_idx_left, vector_idx_right); - case PhysicalType::UINT64: - return TemplatedCompareValue(left_vec, right_vec, vector_idx_left, vector_idx_right); - case PhysicalType::INT128: - return TemplatedCompareValue(left_vec, right_vec, vector_idx_left, vector_idx_right); - case PhysicalType::FLOAT: - return TemplatedCompareValue(left_vec, right_vec, vector_idx_left, vector_idx_right); - case PhysicalType::DOUBLE: - return TemplatedCompareValue(left_vec, right_vec, vector_idx_left, vector_idx_right); - case PhysicalType::VARCHAR: - return TemplatedCompareValue(left_vec, right_vec, vector_idx_left, vector_idx_right); - case PhysicalType::INTERVAL: - return TemplatedCompareValue(left_vec, right_vec, vector_idx_left, vector_idx_right); - default: - return TemplatedCompareValue(left_vec, right_vec, vector_idx_left, vector_idx_right); - } -} - -static int CompareTuple(ChunkCollection *sort_by, vector &desc, vector &null_order, - idx_t left, idx_t right) { - D_ASSERT(sort_by); - - idx_t chunk_idx_left = left / STANDARD_VECTOR_SIZE; - idx_t chunk_idx_right = right / STANDARD_VECTOR_SIZE; - idx_t vector_idx_left = left % STANDARD_VECTOR_SIZE; - idx_t vector_idx_right = right % STANDARD_VECTOR_SIZE; - - auto &left_chunk = sort_by->GetChunk(chunk_idx_left); - auto &right_chunk = sort_by->GetChunk(chunk_idx_right); - - for (idx_t col_idx = 0; col_idx < desc.size(); col_idx++) { - auto order_type = desc[col_idx]; - - auto &left_vec = left_chunk.data[col_idx]; - auto &right_vec = right_chunk.data[col_idx]; - - D_ASSERT(left_vec.GetVectorType() == VectorType::FLAT_VECTOR); - D_ASSERT(right_vec.GetVectorType() == VectorType::FLAT_VECTOR); - D_ASSERT(left_vec.GetType() == right_vec.GetType()); - - auto comp_res = CompareValue(left_vec, right_vec, vector_idx_left, vector_idx_right, null_order[col_idx]); - - if (comp_res == 0) { - continue; - } - return comp_res < 0 ? (order_type == OrderType::ASCENDING ? -1 : 1) - : (order_type == OrderType::ASCENDING ? 1 : -1); - } - return 0; -} - -static int64_t QuicksortInitial(ChunkCollection *sort_by, vector &desc, vector &null_order, - idx_t *result) { - // select pivot - int64_t pivot = 0; - int64_t low = 0, high = sort_by->Count() - 1; - // now insert elements - for (idx_t i = 1; i < sort_by->Count(); i++) { - if (CompareTuple(sort_by, desc, null_order, i, pivot) <= 0) { - result[low++] = i; - } else { - result[high--] = i; - } - } - D_ASSERT(low == high); - result[low] = pivot; - return low; -} - -struct QuicksortInfo { - QuicksortInfo(int64_t left_p, int64_t right_p) : left(left_p), right(right_p) { - } - - int64_t left; - int64_t right; -}; - -struct QuicksortStack { - std::queue info_queue; - - QuicksortInfo Pop() { - auto element = info_queue.front(); - info_queue.pop(); - return element; - } - - bool IsEmpty() { - return info_queue.empty(); - } - - void Enqueue(int64_t left, int64_t right) { - if (left >= right) { - return; - } - info_queue.emplace(left, right); - } -}; - -static void QuicksortInPlace(ChunkCollection *sort_by, vector &desc, vector &null_order, - idx_t *result, QuicksortInfo info, QuicksortStack &stack) { - auto left = info.left; - auto right = info.right; - - D_ASSERT(left < right); - - int64_t middle = left + (right - left) / 2; - int64_t pivot = result[middle]; - // move the mid point value to the front. - int64_t i = left + 1; - int64_t j = right; - - std::swap(result[middle], result[left]); - bool all_equal = true; - while (i <= j) { - if (result) { - while (i <= j) { - int cmp = CompareTuple(sort_by, desc, null_order, result[i], pivot); - if (cmp < 0) { - all_equal = false; - } else if (cmp > 0) { - all_equal = false; - break; - } - i++; - } - } - - while (i <= j && CompareTuple(sort_by, desc, null_order, result[j], pivot) > 0) { - j--; - } - - if (i < j) { - std::swap(result[i], result[j]); - } - } - std::swap(result[i - 1], result[left]); - int64_t part = i - 1; - - if (all_equal) { - return; - } - - stack.Enqueue(left, part - 1); - stack.Enqueue(part + 1, right); -} - -void ChunkCollection::Sort(vector &desc, vector &null_order, idx_t result[]) { - if (count == 0) { - return; - } - D_ASSERT(result); - - // start off with an initial quicksort - int64_t part = QuicksortInitial(this, desc, null_order, result); - - // now continuously perform - QuicksortStack stack; - stack.Enqueue(0, part); - stack.Enqueue(part + 1, count - 1); - while (!stack.IsEmpty()) { - auto element = stack.Pop(); - QuicksortInPlace(this, desc, null_order, result, element, stack); - } -} - -// FIXME make this more efficient by not using the Value API -// just use memcpy in the vectors -// assert that there is no selection list -void ChunkCollection::Reorder(idx_t order_org[]) { - auto order = unique_ptr(new idx_t[count]); - memcpy(order.get(), order_org, sizeof(idx_t) * count); - - // adapted from https://stackoverflow.com/a/7366196/2652376 - - auto val_buf = vector(); - val_buf.resize(ColumnCount()); - - idx_t j, k; - for (idx_t i = 0; i < count; i++) { - for (idx_t col_idx = 0; col_idx < ColumnCount(); col_idx++) { - val_buf[col_idx] = GetValue(col_idx, i); - } - j = i; - while (true) { - k = order[j]; - order[j] = j; - if (k == i) { - break; - } - for (idx_t col_idx = 0; col_idx < ColumnCount(); col_idx++) { - SetValue(col_idx, j, GetValue(col_idx, k)); - } - j = k; - } - for (idx_t col_idx = 0; col_idx < ColumnCount(); col_idx++) { - SetValue(col_idx, j, val_buf[col_idx]); - } - } -} - Value ChunkCollection::GetValue(idx_t column, idx_t index) { return chunks[LocateChunk(index)]->GetValue(column, index % STANDARD_VECTOR_SIZE); } @@ -51545,60 +54314,6 @@ void ChunkCollection::Print() const { Printer::Print(ToString()); } -bool ChunkCollection::Equals(ChunkCollection &other) { - if (count != other.count) { - return false; - } - if (ColumnCount() != other.ColumnCount()) { - return false; - } - // first try to compare the results as-is - bool compare_equals = true; - for (idx_t row_idx = 0; row_idx < count; row_idx++) { - for (idx_t col_idx = 0; col_idx < ColumnCount(); col_idx++) { - auto lvalue = GetValue(col_idx, row_idx); - auto rvalue = other.GetValue(col_idx, row_idx); - if (!Value::DefaultValuesAreEqual(lvalue, rvalue)) { - compare_equals = false; - break; - } - } - if (!compare_equals) { - break; - } - } - if (compare_equals) { - return true; - } - for (auto &type : types) { - // sort not supported - if (type.InternalType() == PhysicalType::LIST || type.InternalType() == PhysicalType::STRUCT) { - return false; - } - } - // if the results are not equal, - // sort both chunk collections to ensure the comparison is not order insensitive - vector desc(ColumnCount(), OrderType::DESCENDING); - vector null_order(ColumnCount(), OrderByNullType::NULLS_FIRST); - auto this_order = unique_ptr(new idx_t[count]); - auto other_order = unique_ptr(new idx_t[count]); - Sort(desc, null_order, this_order.get()); - other.Sort(desc, null_order, other_order.get()); - - for (idx_t row_idx = 0; row_idx < count; row_idx++) { - auto lrow = this_order[row_idx]; - auto rrow = other_order[row_idx]; - for (idx_t col_idx = 0; col_idx < ColumnCount(); col_idx++) { - auto lvalue = GetValue(col_idx, lrow); - auto rvalue = other.GetValue(col_idx, rrow); - if (!Value::DefaultValuesAreEqual(lvalue, rvalue)) { - return false; - } - } - } - return true; -} - } // namespace duckdb @@ -51639,12 +54354,26 @@ struct VectorDataIndex { } }; +struct SwizzleMetaData { + SwizzleMetaData(VectorDataIndex child_index_p, uint16_t offset_p, uint16_t count_p) + : child_index(child_index_p), offset(offset_p), count(count_p) { + } + //! Index of block storing heap + VectorDataIndex child_index; + //! Offset into the string_t vector + uint16_t offset; + //! Number of strings starting at 'offset' that have strings stored in the block with index 'child_index' + uint16_t count; +}; + struct VectorMetaData { //! Where the vector data lives uint32_t block_id; uint32_t offset; //! The number of entries present in this vector uint16_t count; + //! Meta data about string pointers + vector swizzle_data; //! Child data of this vector (used only for lists and structs) //! Note: child indices are stored with one layer of indirection @@ -51683,8 +54412,7 @@ class ColumnDataCollectionSegment { vector vector_data; //! The set of child indices vector child_indices; - //! The string heap for the column data collection - // FIXME: we should get rid of the string heap and store strings as LIST + //! The string heap for the column data collection (only used for IN_MEMORY_ALLOCATOR) StringHeap heap; public: @@ -51693,9 +54421,12 @@ class ColumnDataCollectionSegment { VectorDataIndex AllocateVector(const LogicalType &type, ChunkMetaData &chunk_data, ChunkManagementState *chunk_state = nullptr, VectorDataIndex prev_index = VectorDataIndex()); - //! Allocate space for a vector during append, + //! Allocate space for a vector during append VectorDataIndex AllocateVector(const LogicalType &type, ChunkMetaData &chunk_data, ColumnDataAppendState &append_state, VectorDataIndex prev_index = VectorDataIndex()); + //! Allocate space for string data during append (BUFFER_MANAGER_ALLOCATOR only) + VectorDataIndex AllocateStringHeap(idx_t size, ChunkMetaData &chunk_meta, ColumnDataAppendState &append_state, + VectorDataIndex prev_index = VectorDataIndex()); void InitializeChunkState(idx_t chunk_index, ChunkManagementState &state); void ReadChunk(idx_t chunk_index, ChunkManagementState &state, DataChunk &chunk, @@ -51757,27 +54488,42 @@ ColumnDataAllocator::ColumnDataAllocator(ClientContext &context, ColumnDataAlloc } } +ColumnDataAllocator::ColumnDataAllocator(ColumnDataAllocator &other) { + type = other.GetType(); + switch (type) { + case ColumnDataAllocatorType::BUFFER_MANAGER_ALLOCATOR: + alloc.allocator = other.alloc.allocator; + break; + case ColumnDataAllocatorType::IN_MEMORY_ALLOCATOR: + alloc.buffer_manager = other.alloc.buffer_manager; + break; + default: + throw InternalException("Unrecognized column data allocator type"); + } +} + BufferHandle ColumnDataAllocator::Pin(uint32_t block_id) { D_ASSERT(type == ColumnDataAllocatorType::BUFFER_MANAGER_ALLOCATOR); + shared_ptr handle; if (shared) { + // we only need to grab the lock when accessing the vector, because vector access is not thread-safe: + // the vector can be resized by another thread while we try to access it lock_guard guard(lock); - return PinInternal(block_id); + handle = blocks[block_id].handle; } else { - return PinInternal(block_id); + handle = blocks[block_id].handle; } + return alloc.buffer_manager->Pin(handle); } -BufferHandle ColumnDataAllocator::PinInternal(uint32_t block_id) { - return alloc.buffer_manager->Pin(blocks[block_id].handle); -} - -BufferHandle ColumnDataAllocator::AllocateBlock() { +BufferHandle ColumnDataAllocator::AllocateBlock(idx_t size) { D_ASSERT(type == ColumnDataAllocatorType::BUFFER_MANAGER_ALLOCATOR); + auto block_size = MaxValue(size, Storage::BLOCK_SIZE); BlockMetaData data; data.size = 0; - data.capacity = Storage::BLOCK_SIZE; - auto pin = alloc.buffer_manager->Allocate(Storage::BLOCK_SIZE, false, &data.handle); - blocks.push_back(move(data)); + data.capacity = block_size; + auto pin = alloc.buffer_manager->Allocate(block_size, false, &data.handle); + blocks.push_back(std::move(data)); return pin; } @@ -51793,7 +54539,7 @@ void ColumnDataAllocator::AllocateEmptyBlock(idx_t size) { data.size = 0; data.capacity = allocation_amount; data.handle = nullptr; - blocks.push_back(move(data)); + blocks.push_back(std::move(data)); } void ColumnDataAllocator::AssignPointer(uint32_t &block_id, uint32_t &offset, data_ptr_t pointer) { @@ -51812,16 +54558,20 @@ void ColumnDataAllocator::AllocateBuffer(idx_t size, uint32_t &block_id, uint32_ ChunkManagementState *chunk_state) { D_ASSERT(allocated_data.empty()); if (blocks.empty() || blocks.back().Capacity() < size) { - auto pinned_block = AllocateBlock(); + auto pinned_block = AllocateBlock(size); if (chunk_state) { D_ASSERT(!blocks.empty()); auto new_block_id = blocks.size() - 1; - chunk_state->handles[new_block_id] = move(pinned_block); + chunk_state->handles[new_block_id] = std::move(pinned_block); } } auto &block = blocks.back(); D_ASSERT(size <= block.capacity - block.size); block_id = blocks.size() - 1; + if (chunk_state && chunk_state->handles.find(block_id) == chunk_state->handles.end()) { + // not guaranteed to be pinned already by this thread (if shared allocator) + chunk_state->handles[block_id] = alloc.buffer_manager->Pin(blocks[block_id].handle); + } offset = block.size; block.size += size; } @@ -51833,7 +54583,7 @@ void ColumnDataAllocator::AllocateMemory(idx_t size, uint32_t &block_id, uint32_ AllocateEmptyBlock(size); auto &last_block = blocks.back(); auto allocated = alloc.allocator->Allocate(last_block.capacity); - allocated_data.push_back(move(allocated)); + allocated_data.push_back(std::move(allocated)); } auto &block = blocks.back(); D_ASSERT(size <= block.capacity - block.size); @@ -51883,6 +54633,47 @@ data_ptr_t ColumnDataAllocator::GetDataPointer(ChunkManagementState &state, uint return state.handles[block_id].Ptr() + offset; } +void ColumnDataAllocator::UnswizzlePointers(ChunkManagementState &state, Vector &result, uint16_t v_offset, + uint16_t count, uint32_t block_id, uint32_t offset) { + D_ASSERT(result.GetType().InternalType() == PhysicalType::VARCHAR); + lock_guard guard(lock); + + auto &validity = FlatVector::Validity(result); + auto strings = FlatVector::GetData(result); + + // find first non-inlined string + uint32_t i = v_offset; + const uint32_t end = v_offset + count; + for (; i < end; i++) { + if (!validity.RowIsValid(i)) { + continue; + } + if (!strings[i].IsInlined()) { + break; + } + } + // at least one string must be non-inlined, otherwise this function should not be called + D_ASSERT(i < end); + + auto base_ptr = (char *)GetDataPointer(state, block_id, offset); + if (strings[i].GetDataUnsafe() == base_ptr) { + // pointers are still valid + return; + } + + // pointer mismatch! pointers are invalid, set them correctly + for (; i < end; i++) { + if (!validity.RowIsValid(i)) { + continue; + } + if (strings[i].IsInlined()) { + continue; + } + strings[i].SetPointer(base_ptr); + base_ptr += strings[i].GetSize(); + } +} + void ColumnDataAllocator::DeleteBlock(uint32_t block_id) { blocks[block_id].handle->SetCanDestroy(true); } @@ -51981,23 +54772,23 @@ ColumnDataCollection::ColumnDataCollection(Allocator &allocator_p) { } ColumnDataCollection::ColumnDataCollection(Allocator &allocator_p, vector types_p) { - Initialize(move(types_p)); + Initialize(std::move(types_p)); allocator = make_shared(allocator_p); } ColumnDataCollection::ColumnDataCollection(BufferManager &buffer_manager, vector types_p) { - Initialize(move(types_p)); + Initialize(std::move(types_p)); allocator = make_shared(buffer_manager); } ColumnDataCollection::ColumnDataCollection(shared_ptr allocator_p, vector types_p) { - Initialize(move(types_p)); - this->allocator = move(allocator_p); + Initialize(std::move(types_p)); + this->allocator = std::move(allocator_p); } ColumnDataCollection::ColumnDataCollection(ClientContext &context, vector types_p, ColumnDataAllocatorType type) - : ColumnDataCollection(make_shared(context, type), move(types_p)) { + : ColumnDataCollection(make_shared(context, type), std::move(types_p)) { D_ASSERT(!types.empty()); } @@ -52011,7 +54802,7 @@ ColumnDataCollection::~ColumnDataCollection() { } void ColumnDataCollection::Initialize(vector types_p) { - this->types = move(types_p); + this->types = std::move(types_p); this->count = 0; this->finished_append = false; D_ASSERT(!types.empty()); @@ -52025,6 +54816,10 @@ void ColumnDataCollection::CreateSegment() { segments.emplace_back(make_unique(allocator, types)); } +Allocator &ColumnDataCollection::GetAllocator() const { + return allocator->GetAllocator(); +} + //===--------------------------------------------------------------------===// // ColumnDataRow //===--------------------------------------------------------------------===// @@ -52051,21 +54846,14 @@ ColumnDataRowCollection::ColumnDataRowCollection(const ColumnDataCollection &col } // read all the chunks ColumnDataScanState temp_scan_state; - collection.InitializeScan(temp_scan_state); + collection.InitializeScan(temp_scan_state, ColumnDataScanProperties::DISALLOW_ZERO_COPY); while (true) { auto chunk = make_unique(); collection.InitializeScanChunk(*chunk); if (!collection.Scan(temp_scan_state, *chunk)) { break; } - // we keep the BufferHandles that are needed for the materialized collection pinned in the supplied scan_state - auto &temp_handles = temp_scan_state.current_chunk_state.handles; - auto &scan_handles = scan_state.current_chunk_state.handles; - for (auto &temp_handle_pair : temp_handles) { - auto handle_copy = make_pair(scan_handles.size(), move(temp_handle_pair.second)); - scan_state.current_chunk_state.handles.insert(move(handle_copy)); - } - chunks.push_back(move(chunk)); + chunks.push_back(std::move(chunk)); } // now create all of the column data rows rows.reserve(collection.Count()); @@ -52102,12 +54890,12 @@ ColumnDataChunkIterationHelper ColumnDataCollection::Chunks() const { } ColumnDataChunkIterationHelper ColumnDataCollection::Chunks(vector column_ids) const { - return ColumnDataChunkIterationHelper(*this, move(column_ids)); + return ColumnDataChunkIterationHelper(*this, std::move(column_ids)); } ColumnDataChunkIterationHelper::ColumnDataChunkIterationHelper(const ColumnDataCollection &collection_p, vector column_ids_p) - : collection(collection_p), column_ids(move(column_ids_p)) { + : collection(collection_p), column_ids(std::move(column_ids_p)) { } ColumnDataChunkIterationHelper::ColumnDataChunkIterator::ColumnDataChunkIterator( @@ -52116,7 +54904,7 @@ ColumnDataChunkIterationHelper::ColumnDataChunkIterator::ColumnDataChunkIterator if (!collection) { return; } - collection->InitializeScan(scan_state, move(column_ids_p)); + collection->InitializeScan(scan_state, std::move(column_ids_p)); collection->InitializeScanChunk(scan_state, *scan_chunk); collection->Scan(scan_state, *scan_chunk); } @@ -52269,11 +55057,21 @@ struct StringValueCopy : public BaseValueCopy { } }; +struct ConstListValueCopy : public BaseValueCopy { + using TYPE = list_entry_t; + + static TYPE Operation(ColumnDataMetaData &meta_data, TYPE input) { + input.offset = meta_data.child_list_size; + return input; + } +}; + struct ListValueCopy : public BaseValueCopy { using TYPE = list_entry_t; static TYPE Operation(ColumnDataMetaData &meta_data, TYPE input) { - input.offset += meta_data.child_list_size; + input.offset = meta_data.child_list_size; + meta_data.child_list_size += input.length; return input; } }; @@ -52301,8 +55099,8 @@ static void TemplatedColumnDataCopy(ColumnDataMetaData &meta_data, const Unified auto ¤t_segment = segment.GetVectorData(current_index); idx_t append_count = MinValue(STANDARD_VECTOR_SIZE - current_segment.count, remaining); - auto base_ptr = meta_data.segment.allocator->GetDataPointer(append_state.current_chunk_state, - current_segment.block_id, current_segment.offset); + auto base_ptr = segment.allocator->GetDataPointer(append_state.current_chunk_state, current_segment.block_id, + current_segment.offset); auto validity_data = ColumnDataCollectionSegment::GetValidityPointer(base_ptr, OP::TypeSize()); ValidityMask result_validity(validity_data); @@ -52326,7 +55124,7 @@ static void TemplatedColumnDataCopy(ColumnDataMetaData &meta_data, const Unified if (remaining > 0) { // need to append more, check if we need to allocate a new vector or not if (!current_segment.next_data.IsValid()) { - segment.AllocateVector(source.GetType(), meta_data.chunk_data, meta_data.state, current_index); + segment.AllocateVector(source.GetType(), meta_data.chunk_data, append_state, current_index); } D_ASSERT(segment.GetVectorData(current_index).next_data.IsValid()); current_index = segment.GetVectorData(current_index).next_data; @@ -52343,28 +55141,146 @@ static void ColumnDataCopy(ColumnDataMetaData &meta_data, const UnifiedVectorFor template <> void ColumnDataCopy(ColumnDataMetaData &meta_data, const UnifiedVectorFormat &source_data, Vector &source, idx_t offset, idx_t copy_count) { - TemplatedColumnDataCopy(meta_data, source_data, source, offset, copy_count); + + const auto &allocator_type = meta_data.segment.allocator->GetType(); + if (allocator_type == ColumnDataAllocatorType::IN_MEMORY_ALLOCATOR) { + // strings cannot be spilled to disk - use StringHeap + TemplatedColumnDataCopy(meta_data, source_data, source, offset, copy_count); + return; + } + D_ASSERT(allocator_type == ColumnDataAllocatorType::BUFFER_MANAGER_ALLOCATOR); + + auto &segment = meta_data.segment; + auto &append_state = meta_data.state; + + VectorDataIndex child_index; + if (meta_data.GetVectorMetaData().child_index.IsValid()) { + // find the last child index + child_index = segment.GetChildIndex(meta_data.GetVectorMetaData().child_index); + auto next_child_index = segment.GetVectorData(child_index).next_data; + while (next_child_index.IsValid()) { + child_index = next_child_index; + next_child_index = segment.GetVectorData(child_index).next_data; + } + } + + auto current_index = meta_data.vector_data_index; + idx_t remaining = copy_count; + while (remaining > 0) { + // how many values fit in the current string vector + idx_t vector_remaining = + MinValue(STANDARD_VECTOR_SIZE - segment.GetVectorData(current_index).count, remaining); + + // 'append_count' is less if we cannot fit that amount of non-inlined strings on one buffer-managed block + idx_t append_count; + idx_t heap_size = 0; + const auto source_entries = (string_t *)source_data.data; + for (append_count = 0; append_count < vector_remaining; append_count++) { + auto source_idx = source_data.sel->get_index(offset + append_count); + if (!source_data.validity.RowIsValid(source_idx)) { + continue; + } + const auto &entry = source_entries[source_idx]; + if (entry.IsInlined()) { + continue; + } + if (heap_size + entry.GetSize() > Storage::BLOCK_SIZE) { + break; + } + heap_size += entry.GetSize(); + } + + if (vector_remaining != 0 && append_count == 0) { + // single string is longer than Storage::BLOCK_SIZE + // we allocate one block at a time for long strings + auto source_idx = source_data.sel->get_index(offset + append_count); + D_ASSERT(source_data.validity.RowIsValid(source_idx)); + D_ASSERT(!source_entries[source_idx].IsInlined()); + D_ASSERT(source_entries[source_idx].GetSize() > Storage::BLOCK_SIZE); + heap_size += source_entries[source_idx].GetSize(); + append_count++; + } + + // allocate string heap for the next 'append_count' strings + data_ptr_t heap_ptr = nullptr; + if (heap_size != 0) { + child_index = segment.AllocateStringHeap(heap_size, meta_data.chunk_data, append_state, child_index); + if (!meta_data.GetVectorMetaData().child_index.IsValid()) { + meta_data.GetVectorMetaData().child_index = meta_data.segment.AddChildIndex(child_index); + } + auto &child_segment = segment.GetVectorData(child_index); + heap_ptr = segment.allocator->GetDataPointer(append_state.current_chunk_state, child_segment.block_id, + child_segment.offset); + } + + auto ¤t_segment = segment.GetVectorData(current_index); + auto base_ptr = segment.allocator->GetDataPointer(append_state.current_chunk_state, current_segment.block_id, + current_segment.offset); + auto validity_data = ColumnDataCollectionSegment::GetValidityPointer(base_ptr, sizeof(string_t)); + ValidityMask target_validity(validity_data); + if (current_segment.count == 0) { + // first time appending to this vector + // all data here is still uninitialized + // initialize the validity mask to set all to valid + target_validity.SetAllValid(STANDARD_VECTOR_SIZE); + } + + auto target_entries = (string_t *)base_ptr; + for (idx_t i = 0; i < append_count; i++) { + auto source_idx = source_data.sel->get_index(offset + i); + auto target_idx = current_segment.count + i; + if (!source_data.validity.RowIsValid(source_idx)) { + target_validity.SetInvalid(target_idx); + continue; + } + const auto &source_entry = source_entries[source_idx]; + auto &target_entry = target_entries[target_idx]; + if (source_entry.IsInlined()) { + target_entry = source_entry; + } else { + D_ASSERT(heap_ptr != nullptr); + memcpy(heap_ptr, source_entry.GetDataUnsafe(), source_entry.GetSize()); + target_entry = string_t((const char *)heap_ptr, source_entry.GetSize()); + heap_ptr += source_entry.GetSize(); + } + } + + if (heap_size != 0) { + current_segment.swizzle_data.emplace_back(child_index, current_segment.count, append_count); + } + + current_segment.count += append_count; + offset += append_count; + remaining -= append_count; + + if (vector_remaining - append_count == 0) { + // need to append more, check if we need to allocate a new vector or not + if (!current_segment.next_data.IsValid()) { + segment.AllocateVector(source.GetType(), meta_data.chunk_data, append_state, current_index); + } + D_ASSERT(segment.GetVectorData(current_index).next_data.IsValid()); + current_index = segment.GetVectorData(current_index).next_data; + } + } } template <> void ColumnDataCopy(ColumnDataMetaData &meta_data, const UnifiedVectorFormat &source_data, Vector &source, idx_t offset, idx_t copy_count) { + auto &segment = meta_data.segment; - // first append the child entries of the list auto &child_vector = ListVector::GetEntry(source); - idx_t child_list_size = ListVector::GetListSize(source); auto &child_type = child_vector.GetType(); - UnifiedVectorFormat child_vector_data; - child_vector.ToUnifiedFormat(child_list_size, child_vector_data); - if (!meta_data.GetVectorMetaData().child_index.IsValid()) { auto child_index = segment.AllocateVector(child_type, meta_data.chunk_data, meta_data.state); meta_data.GetVectorMetaData().child_index = meta_data.segment.AddChildIndex(child_index); } + auto &child_function = meta_data.copy_function.child_functions[0]; auto child_index = segment.GetChildIndex(meta_data.GetVectorMetaData().child_index); + // figure out the current list size by traversing the set of child entries idx_t current_list_size = 0; auto current_child_index = child_index; @@ -52373,14 +55289,37 @@ void ColumnDataCopy(ColumnDataMetaData &meta_data, const UnifiedVe current_list_size += child_vdata.count; current_child_index = child_vdata.next_data; } + + // set the child vector + UnifiedVectorFormat child_vector_data; ColumnDataMetaData child_meta_data(child_function, meta_data, child_index); - // FIXME: appending the entire child list here is not required - // We can also scan the actual list entries required per the offset/copy_count - child_function.function(child_meta_data, child_vector_data, child_vector, 0, child_list_size); + auto info = ListVector::GetConsecutiveChildListInfo(source, offset, copy_count); + + if (info.needs_slicing) { + SelectionVector sel(info.child_list_info.length); + ListVector::GetConsecutiveChildSelVector(source, sel, offset, copy_count); + + auto sliced_child_vector = Vector(child_vector, sel, info.child_list_info.length); + sliced_child_vector.Flatten(info.child_list_info.length); + info.child_list_info.offset = 0; + + sliced_child_vector.ToUnifiedFormat(info.child_list_info.length, child_vector_data); + child_function.function(child_meta_data, child_vector_data, sliced_child_vector, info.child_list_info.offset, + info.child_list_info.length); + + } else { + child_vector.ToUnifiedFormat(info.child_list_info.length, child_vector_data); + child_function.function(child_meta_data, child_vector_data, child_vector, info.child_list_info.offset, + info.child_list_info.length); + } // now copy the list entries meta_data.child_list_size = current_list_size; - TemplatedColumnDataCopy(meta_data, source_data, source, offset, copy_count); + if (info.is_constant) { + TemplatedColumnDataCopy(meta_data, source_data, source, offset, copy_count); + } else { + TemplatedColumnDataCopy(meta_data, source_data, source, offset, copy_count); + } } void ColumnDataCopyStruct(ColumnDataMetaData &meta_data, const UnifiedVectorFormat &source_data, Vector &source, @@ -52536,7 +55475,7 @@ void ColumnDataCollection::InitializeScan(ColumnDataScanState &state, ColumnData for (idx_t i = 0; i < types.size(); i++) { column_ids.push_back(i); } - InitializeScan(state, move(column_ids), properties); + InitializeScan(state, std::move(column_ids), properties); } void ColumnDataCollection::InitializeScan(ColumnDataScanState &state, vector column_ids, @@ -52547,7 +55486,7 @@ void ColumnDataCollection::InitializeScan(ColumnDataScanState &state, vector column_ids, ColumnDataScanProperties properties) const { - InitializeScan(state.scan_state, move(column_ids), properties); + InitializeScan(state.scan_state, std::move(column_ids), properties); } bool ColumnDataCollection::Scan(ColumnDataParallelScanState &state, ColumnDataLocalScanState &lstate, @@ -52666,7 +55605,7 @@ void ColumnDataCollection::Combine(ColumnDataCollection &other) { this->count += other.count; this->segments.reserve(segments.size() + other.segments.size()); for (auto &other_seg : other.segments) { - segments.push_back(move(other_seg)); + segments.push_back(std::move(other_seg)); } Verify(); } @@ -52721,6 +55660,9 @@ void ColumnDataCollection::Print() const { void ColumnDataCollection::Reset() { count = 0; segments.clear(); + + // Refreshes the ColumnDataAllocator to prevent holding on to allocated data unnecessarily + allocator = make_shared(*allocator); } bool ColumnDataCollection::ResultEquals(const ColumnDataCollection &left, const ColumnDataCollection &right, @@ -52760,7 +55702,7 @@ namespace duckdb { ColumnDataCollectionSegment::ColumnDataCollectionSegment(shared_ptr allocator_p, vector types_p) - : allocator(move(allocator_p)), types(move(types_p)), count(0), heap(allocator->GetAllocator()) { + : allocator(std::move(allocator_p)), types(std::move(types_p)), count(0), heap(allocator->GetAllocator()) { } idx_t ColumnDataCollectionSegment::GetDataSize(idx_t type_size) { @@ -52819,6 +55761,28 @@ VectorDataIndex ColumnDataCollectionSegment::AllocateVector(const LogicalType &t return AllocateVector(type, chunk_meta, &append_state.current_chunk_state, prev_index); } +VectorDataIndex ColumnDataCollectionSegment::AllocateStringHeap(idx_t size, ChunkMetaData &chunk_meta, + ColumnDataAppendState &append_state, + VectorDataIndex prev_index) { + D_ASSERT(allocator->GetType() == ColumnDataAllocatorType::BUFFER_MANAGER_ALLOCATOR); + D_ASSERT(size != 0); + + VectorMetaData meta_data; + meta_data.count = 0; + + allocator->AllocateData(AlignValue(size), meta_data.block_id, meta_data.offset, &append_state.current_chunk_state); + chunk_meta.block_ids.insert(meta_data.block_id); + + VectorDataIndex index(vector_data.size()); + vector_data.push_back(meta_data); + + if (prev_index.IsValid()) { + GetVectorData(prev_index).next_data = index; + } + + return index; +} + void ColumnDataCollectionSegment::AllocateNewChunk() { ChunkMetaData meta_data; meta_data.count = 0; @@ -52827,7 +55791,7 @@ void ColumnDataCollectionSegment::AllocateNewChunk() { auto vector_idx = AllocateVector(types[i], meta_data); meta_data.vector_data.push_back(vector_idx); } - chunk_data.push_back(move(meta_data)); + chunk_data.push_back(std::move(meta_data)); } void ColumnDataCollectionSegment::InitializeChunkState(idx_t chunk_index, ChunkManagementState &state) { @@ -52921,7 +55885,7 @@ idx_t ColumnDataCollectionSegment::ReadVector(ChunkManagementState &state, Vecto if (vdata.count == 0) { return 0; } - auto count = ReadVectorInternal(state, vector_index, result); + auto vcount = ReadVectorInternal(state, vector_index, result); if (internal_type == PhysicalType::LIST) { // list: copy child auto &child_vector = ListVector::GetEntry(result); @@ -52932,12 +55896,19 @@ idx_t ColumnDataCollectionSegment::ReadVector(ChunkManagementState &state, Vecto for (idx_t child_idx = 0; child_idx < child_vectors.size(); child_idx++) { auto child_count = ReadVector(state, GetChildIndex(vdata.child_index, child_idx), *child_vectors[child_idx]); - if (child_count != count) { + if (child_count != vcount) { throw InternalException("Column Data Collection: mismatch in struct child sizes"); } } + } else if (internal_type == PhysicalType::VARCHAR && + allocator->GetType() == ColumnDataAllocatorType::BUFFER_MANAGER_ALLOCATOR) { + for (auto &swizzle_segment : vdata.swizzle_data) { + auto &string_heap_segment = GetVectorData(swizzle_segment.child_index); + allocator->UnswizzlePointers(state, result, swizzle_segment.offset, swizzle_segment.count, + string_heap_segment.block_id, string_heap_segment.offset); + } } - return count; + return vcount; } void ColumnDataCollectionSegment::ReadChunk(idx_t chunk_index, ChunkManagementState &state, DataChunk &chunk, @@ -53085,7 +56056,7 @@ uint32_t ChunkReference::GetMinimumBlockID() const { } ColumnDataConsumer::ColumnDataConsumer(ColumnDataCollection &collection_p, vector column_ids) - : collection(collection_p), column_ids(move(column_ids)) { + : collection(collection_p), column_ids(std::move(column_ids)) { } void ColumnDataConsumer::InitializeScan() { @@ -53172,6 +56143,352 @@ void ColumnDataConsumer::ConsumeChunks(idx_t delete_index_start, idx_t delete_in +namespace duckdb { + +bool ConflictInfo::ConflictTargetMatches(Index &index) const { + if (only_check_unique && !index.IsUnique()) { + // We only support checking ON CONFLICT for Unique/Primary key constraints + return false; + } + if (column_ids.empty()) { + return true; + } + // Check whether the column ids match + return column_ids == index.column_id_set; +} + +} // namespace duckdb + + + + + + + +namespace duckdb { + +class Index; +class ConflictInfo; + +enum class ConflictManagerMode : uint8_t { + SCAN, // gather conflicts without throwing + THROW // throw on the conflicts that were not found during the scan +}; + +enum class LookupResultType : uint8_t { LOOKUP_MISS, LOOKUP_HIT, LOOKUP_NULL }; + +class ConflictManager { +public: + ConflictManager(VerifyExistenceType lookup_type, idx_t input_size, ConflictInfo *conflict_info = nullptr); + +public: + void SetIndexCount(idx_t count); + // These methods return a boolean indicating whether we should throw or not + bool AddMiss(idx_t chunk_index); + bool AddHit(idx_t chunk_index, row_t row_id); + bool AddNull(idx_t chunk_index); + VerifyExistenceType LookupType() const; + // This should be called before using the conflicts selection vector + void Finalize(); + idx_t ConflictCount() const; + const ManagedSelection &Conflicts() const; + Vector &RowIds(); + const ConflictInfo &GetConflictInfo() const; + void FinishLookup(); + void SetMode(ConflictManagerMode mode); + +private: + bool IsConflict(LookupResultType type); + const unordered_set &InternalConflictSet() const; + Vector &InternalRowIds(); + Vector &InternalIntermediate(); + ManagedSelection &InternalSelection(); + bool SingleIndexTarget() const; + bool ShouldThrow(idx_t chunk_index) const; + bool ShouldIgnoreNulls() const; + void AddConflictInternal(idx_t chunk_index, row_t row_id); + void AddToConflictSet(idx_t chunk_index); + +private: + VerifyExistenceType lookup_type; + idx_t input_size; + ConflictInfo *conflict_info; + idx_t index_count; + bool finalized = false; + ManagedSelection conflicts; + unique_ptr row_ids; + // Used to check if a given conflict is part of the conflict target or not + unique_ptr> conflict_set; + // Contains 'input_size' booleans, indicating if a given index in the input chunk has a conflict + unique_ptr intermediate_vector; + // Mapping from chunk_index to row_id + vector row_id_map; + // Whether we have already found the one conflict target we're interested in + bool single_index_finished = false; + ConflictManagerMode mode; +}; + +} // namespace duckdb + + + + + +namespace duckdb { + +ConflictManager::ConflictManager(VerifyExistenceType lookup_type, idx_t input_size, ConflictInfo *conflict_info) + : lookup_type(lookup_type), input_size(input_size), conflict_info(conflict_info), conflicts(input_size, false), + mode(ConflictManagerMode::THROW) { +} + +ManagedSelection &ConflictManager::InternalSelection() { + if (!conflicts.Initialized()) { + conflicts.Initialize(input_size); + } + return conflicts; +} + +const unordered_set &ConflictManager::InternalConflictSet() const { + D_ASSERT(conflict_set); + return *conflict_set; +} + +Vector &ConflictManager::InternalRowIds() { + if (!row_ids) { + row_ids = make_unique(LogicalType::ROW_TYPE, input_size); + } + return *row_ids; +} + +Vector &ConflictManager::InternalIntermediate() { + if (!intermediate_vector) { + intermediate_vector = make_unique(LogicalType::BOOLEAN, true, true, input_size); + } + return *intermediate_vector; +} + +const ConflictInfo &ConflictManager::GetConflictInfo() const { + D_ASSERT(conflict_info); + return *conflict_info; +} + +void ConflictManager::FinishLookup() { + if (mode == ConflictManagerMode::THROW) { + return; + } + if (!SingleIndexTarget()) { + return; + } + if (conflicts.Count() != 0) { + // We have recorded conflicts from the one index we're interested in + // We set this so we don't duplicate the conflicts when there are duplicate indexes + // that also match our conflict target + single_index_finished = true; + } +} + +void ConflictManager::SetMode(ConflictManagerMode mode) { + // Only allow SCAN when we have conflict info + D_ASSERT(mode != ConflictManagerMode::SCAN || conflict_info != nullptr); + this->mode = mode; +} + +void ConflictManager::AddToConflictSet(idx_t chunk_index) { + if (!conflict_set) { + conflict_set = make_unique>(); + } + auto &set = *conflict_set; + set.insert(chunk_index); +} + +void ConflictManager::AddConflictInternal(idx_t chunk_index, row_t row_id) { + D_ASSERT(mode == ConflictManagerMode::SCAN); + + // Only when we should not throw on conflict should we get here + D_ASSERT(!ShouldThrow(chunk_index)); + AddToConflictSet(chunk_index); + if (SingleIndexTarget()) { + // If we have identical indexes, only the conflicts of the first index should be recorded + // as the other index(es) would produce the exact same conflicts anyways + if (single_index_finished) { + return; + } + + // We can be more efficient because we don't need to merge conflicts of multiple indexes + auto &selection = InternalSelection(); + auto &row_ids = InternalRowIds(); + auto data = FlatVector::GetData(row_ids); + data[selection.Count()] = row_id; + selection.Append(chunk_index); + } else { + auto &intermediate = InternalIntermediate(); + auto data = FlatVector::GetData(intermediate); + // Mark this index in the chunk as producing a conflict + data[chunk_index] = true; + if (row_id_map.empty()) { + row_id_map.resize(input_size); + } + row_id_map[chunk_index] = row_id; + } +} + +bool ConflictManager::IsConflict(LookupResultType type) { + switch (type) { + case LookupResultType::LOOKUP_NULL: { + if (ShouldIgnoreNulls()) { + return false; + } + // If nulls are not ignored, treat this as a hit instead + return IsConflict(LookupResultType::LOOKUP_HIT); + } + case LookupResultType::LOOKUP_HIT: { + return true; + } + case LookupResultType::LOOKUP_MISS: { + // FIXME: If we record a miss as a conflict when the verify type is APPEND_FK, then we can simplify the checks + // in VerifyForeignKeyConstraint This also means we should not record a hit as a conflict when the verify type + // is APPEND_FK + return false; + } + default: { + throw NotImplementedException("Type not implemented for LookupResultType"); + } + } +} + +bool ConflictManager::AddHit(idx_t chunk_index, row_t row_id) { + D_ASSERT(chunk_index < input_size); + // First check if this causes a conflict + if (!IsConflict(LookupResultType::LOOKUP_HIT)) { + return false; + } + + // Then check if we should throw on a conflict + if (ShouldThrow(chunk_index)) { + return true; + } + if (mode == ConflictManagerMode::THROW) { + // When our mode is THROW, and the chunk index is part of the previously scanned conflicts + // then we ignore the conflict instead + D_ASSERT(!ShouldThrow(chunk_index)); + return false; + } + D_ASSERT(conflict_info); + // Because we don't throw, we need to register the conflict + AddConflictInternal(chunk_index, row_id); + return false; +} + +bool ConflictManager::AddMiss(idx_t chunk_index) { + D_ASSERT(chunk_index < input_size); + return IsConflict(LookupResultType::LOOKUP_MISS); +} + +bool ConflictManager::AddNull(idx_t chunk_index) { + D_ASSERT(chunk_index < input_size); + if (!IsConflict(LookupResultType::LOOKUP_NULL)) { + return false; + } + return AddHit(chunk_index, DConstants::INVALID_INDEX); +} + +bool ConflictManager::SingleIndexTarget() const { + D_ASSERT(conflict_info); + // We are only interested in a specific index + return !conflict_info->column_ids.empty(); +} + +bool ConflictManager::ShouldThrow(idx_t chunk_index) const { + if (mode == ConflictManagerMode::SCAN) { + return false; + } + D_ASSERT(mode == ConflictManagerMode::THROW); + if (conflict_set == nullptr) { + // No conflicts were scanned, so this conflict is not in the set + return true; + } + auto &set = InternalConflictSet(); + if (set.count(chunk_index)) { + return false; + } + // None of the scanned conflicts arose from this insert tuple + return true; +} + +bool ConflictManager::ShouldIgnoreNulls() const { + switch (lookup_type) { + case VerifyExistenceType::APPEND: + return true; + case VerifyExistenceType::APPEND_FK: + return false; + case VerifyExistenceType::DELETE_FK: + return true; + default: + throw InternalException("Type not implemented for VerifyExistenceType"); + } +} + +Vector &ConflictManager::RowIds() { + D_ASSERT(finalized); + return *row_ids; +} + +const ManagedSelection &ConflictManager::Conflicts() const { + D_ASSERT(finalized); + return conflicts; +} + +idx_t ConflictManager::ConflictCount() const { + return conflicts.Count(); +} + +void ConflictManager::Finalize() { + D_ASSERT(!finalized); + if (SingleIndexTarget()) { + // Selection vector has been directly populated already, no need to finalize + finalized = true; + return; + } + finalized = true; + if (!intermediate_vector) { + // No conflicts were found, we're done + return; + } + auto &intermediate = InternalIntermediate(); + auto data = FlatVector::GetData(intermediate); + auto &selection = InternalSelection(); + // Create the selection vector from the encountered conflicts + for (idx_t i = 0; i < input_size; i++) { + if (data[i]) { + selection.Append(i); + } + } + // Now create the row_ids Vector, aligned with the selection vector + auto &row_ids = InternalRowIds(); + auto row_id_data = FlatVector::GetData(row_ids); + + for (idx_t i = 0; i < selection.Count(); i++) { + D_ASSERT(!row_id_map.empty()); + auto index = selection[i]; + D_ASSERT(index < row_id_map.size()); + auto row_id = row_id_map[index]; + row_id_data[i] = row_id; + } + intermediate_vector.reset(); +} + +VerifyExistenceType ConflictManager::LookupType() const { + return this->lookup_type; +} + +void ConflictManager::SetIndexCount(idx_t count) { + index_count = count; +} + +} // namespace duckdb + + + @@ -53245,7 +56562,7 @@ void DataChunk::Initialize(Allocator &allocator, vector::const_iter for (; begin != end; begin++) { VectorCache cache(allocator, *begin, capacity); data.emplace_back(cache); - vector_caches.push_back(move(cache)); + vector_caches.push_back(std::move(cache)); } } @@ -53314,8 +56631,8 @@ void DataChunk::Reference(DataChunk &chunk) { void DataChunk::Move(DataChunk &chunk) { SetCardinality(chunk); SetCapacity(chunk); - data = move(chunk.data); - vector_caches = move(chunk.vector_caches); + data = std::move(chunk.data); + vector_caches = std::move(chunk.vector_caches); chunk.Destroy(); } @@ -53349,8 +56666,8 @@ void DataChunk::Split(DataChunk &other, idx_t split_idx) { D_ASSERT(split_idx < data.size()); const idx_t num_cols = data.size(); for (idx_t col_idx = split_idx; col_idx < num_cols; col_idx++) { - other.data.push_back(move(data[col_idx])); - other.vector_caches.push_back(move(vector_caches[col_idx])); + other.data.push_back(std::move(data[col_idx])); + other.vector_caches.push_back(std::move(vector_caches[col_idx])); } for (idx_t col_idx = split_idx; col_idx < num_cols; col_idx++) { data.pop_back(); @@ -53364,8 +56681,8 @@ void DataChunk::Fuse(DataChunk &other) { D_ASSERT(other.size() == size()); const idx_t num_cols = other.data.size(); for (idx_t col_idx = 0; col_idx < num_cols; ++col_idx) { - data.emplace_back(move(other.data[col_idx])); - vector_caches.emplace_back(move(other.vector_caches[col_idx])); + data.emplace_back(std::move(other.data[col_idx])); + vector_caches.emplace_back(std::move(other.vector_caches[col_idx])); } other.Destroy(); } @@ -53504,6 +56821,16 @@ void DataChunk::Hash(Vector &result) { } } +void DataChunk::Hash(vector &column_ids, Vector &result) { + D_ASSERT(result.GetType().id() == LogicalType::HASH); + D_ASSERT(column_ids.size() > 0); + + VectorOperations::Hash(data[column_ids[0]], result, size()); + for (idx_t i = 1; i < column_ids.size(); i++) { + VectorOperations::CombineHash(result, data[column_ids[i]], size()); + } +} + void DataChunk::Verify() { #ifdef DEBUG D_ASSERT(size() <= capacity); @@ -53946,13 +57273,18 @@ int64_t Date::Epoch(date_t date) { } int64_t Date::EpochNanoseconds(date_t date) { - return ((int64_t)date.days) * (Interval::MICROS_PER_DAY * 1000); + int64_t result; + if (!TryMultiplyOperator::Operation(date.days, Interval::MICROS_PER_DAY * 1000, + result)) { + throw ConversionException("Could not convert DATE (%s) to nanoseconds", Date::ToString(date)); + } + return result; } int64_t Date::EpochMicroseconds(date_t date) { int64_t result; if (!TryMultiplyOperator::Operation(date.days, Interval::MICROS_PER_DAY, result)) { - throw ConversionException("Could not convert DATE to microseconds"); + throw ConversionException("Could not convert DATE (%s) to microseconds", Date::ToString(date)); } return result; } @@ -54023,32 +57355,51 @@ int32_t Date::ExtractISODayOfTheWeek(date_t date) { } } -static int32_t GetISOYearWeek(int32_t &year, int32_t month, int32_t day) { - auto day_of_the_year = - (Date::IsLeapYear(year) ? Date::CUMULATIVE_LEAP_DAYS[month] : Date::CUMULATIVE_DAYS[month]) + day; - // get the first day of the first week of the year - // the first week is the week that has the 4th of January in it - const auto weekday_of_the_fourth = Date::ExtractISODayOfTheWeek(Date::FromDate(year, 1, 4)); - // if fourth is monday, then fourth is the first day - // if fourth is tuesday, third is the first day - // if fourth is wednesday, second is the first day - // if fourth is thursday, first is the first day - // if fourth is friday - sunday, day is in the previous year - // (day is 0-based, weekday is 1-based) - const auto first_day_of_the_first_isoweek = 4 - weekday_of_the_fourth; - if (day_of_the_year < first_day_of_the_first_isoweek) { - // day is part of last year (13th month) - --year; - return GetISOYearWeek(year, 12, day); - } else { - return ((day_of_the_year - first_day_of_the_first_isoweek) / 7) + 1; +template +static T PythonDivMod(const T &x, const T &y, T &r) { + // D_ASSERT(y > 0); + T quo = x / y; + r = x - quo * y; + if (r < 0) { + --quo; + r += y; } + // D_ASSERT(0 <= r && r < y); + return quo; } -void Date::ExtractISOYearWeek(date_t date, int32_t &year, int32_t &week) { +static date_t GetISOWeekOne(int32_t year) { + const auto first_day = Date::FromDate(year, 1, 1); /* ord of 1/1 */ + /* 0 if 1/1 is a Monday, 1 if a Tue, etc. */ + const auto first_weekday = Date::ExtractISODayOfTheWeek(first_day) - 1; + /* ordinal of closest Monday at or before 1/1 */ + auto week1_monday = first_day - first_weekday; + + if (first_weekday > 3) { /* if 1/1 was Fri, Sat, Sun */ + week1_monday += 7; + } + + return week1_monday; +} + +static int32_t GetISOYearWeek(const date_t date, int32_t &year) { int32_t month, day; Date::Convert(date, year, month, day); - week = GetISOYearWeek(year, month - 1, day - 1); + auto week1_monday = GetISOWeekOne(year); + auto week = PythonDivMod((date.days - week1_monday.days), 7, day); + if (week < 0) { + week1_monday = GetISOWeekOne(--year); + week = PythonDivMod((date.days - week1_monday.days), 7, day); + } else if (week >= 52 && date >= GetISOWeekOne(year + 1)) { + ++year; + week = 0; + } + + return week + 1; +} + +void Date::ExtractISOYearWeek(date_t date, int32_t &year, int32_t &week) { + week = GetISOYearWeek(date, year); } int32_t Date::ExtractISOWeekNumber(date_t date) { @@ -54177,7 +57528,7 @@ template <> hash_t Hash(float val) { static_assert(sizeof(float) == sizeof(uint32_t), ""); FloatingPointEqualityTransform::OP(val); - uint32_t uval = *((uint32_t *)&val); + uint32_t uval = Load((const_data_ptr_t)&val); return murmurhash64(uval); } @@ -54185,7 +57536,7 @@ template <> hash_t Hash(double val) { static_assert(sizeof(double) == sizeof(uint64_t), ""); FloatingPointEqualityTransform::OP(val); - uint64_t uval = *((uint64_t *)&val); + uint64_t uval = Load((const_data_ptr_t)&val); return murmurhash64(uval); } @@ -55571,7 +58922,7 @@ bool TrySubtractOperator::Operation(hugeint_t left, hugeint_t right, hugeint_t & struct SubtractOperatorOverflowCheck { template - static inline TR Operation(TA left, TB right) { + DUCKDB_API static inline TR Operation(TA left, TB right) { TR result; if (!TrySubtractOperator::Operation(left, right, result)) { throw OutOfRangeException("Overflow in subtraction of %s (%d - %d)!", TypeIdToString(GetTypeId()), left, @@ -56129,11 +59480,12 @@ timestamp_t Interval::Add(timestamp_t left, interval_t right) { + namespace duckdb { PartitionedColumnData::PartitionedColumnData(PartitionedColumnDataType type_p, ClientContext &context_p, vector types_p) - : type(type_p), context(context_p), types(move(types_p)), allocators(make_shared()) { + : type(type_p), context(context_p), types(std::move(types_p)), allocators(make_shared()) { } PartitionedColumnData::PartitionedColumnData(const PartitionedColumnData &other) @@ -56144,6 +59496,8 @@ unique_ptr PartitionedColumnData::CreateShared() { switch (type) { case PartitionedColumnDataType::RADIX: return make_unique((RadixPartitionedColumnData &)*this); + case PartitionedColumnDataType::HIVE: + return make_unique((HivePartitionedColumnData &)*this); default: throw NotImplementedException("CreateShared for this type of PartitionedColumnData"); } @@ -56267,10 +59621,12 @@ void PartitionedColumnData::FlushAppendState(PartitionedColumnDataAppendState &s void PartitionedColumnData::Combine(PartitionedColumnData &other) { // Now combine the state's partitions into this lock_guard guard(lock); + if (partitions.empty()) { // This is the first merge, we just copy them over - partitions = move(other.partitions); + partitions = std::move(other.partitions); } else { + D_ASSERT(partitions.size() == other.partitions.size()); // Combine the append state's partitions into this PartitionedColumnData for (idx_t i = 0; i < other.partitions.size(); i++) { partitions[i]->Combine(*other.partitions[i]); @@ -56357,7 +59713,7 @@ vector RowDataCollection::Build(idx_t added_count, data_ptr_t key_ // now append to the block idx_t append_count = AppendToBlock(last_block, handle, append_entries, remaining, entry_sizes); remaining -= append_count; - handles.push_back(move(handle)); + handles.push_back(std::move(handle)); } } while (remaining > 0) { @@ -56373,9 +59729,9 @@ vector RowDataCollection::Build(idx_t added_count, data_ptr_t key_ remaining -= append_count; if (keep_pinned) { - pinned_blocks.push_back(move(handle)); + pinned_blocks.push_back(std::move(handle)); } else { - handles.push_back(move(handle)); + handles.push_back(std::move(handle)); } } } @@ -56411,8 +59767,8 @@ void RowDataCollection::Merge(RowDataCollection &other) { temp.count = other.count; temp.block_capacity = other.block_capacity; temp.entry_size = other.entry_size; - temp.blocks = move(other.blocks); - temp.pinned_blocks = move(other.pinned_blocks); + temp.blocks = std::move(other.blocks); + temp.pinned_blocks = std::move(other.pinned_blocks); } other.Clear(); @@ -56421,10 +59777,10 @@ void RowDataCollection::Merge(RowDataCollection &other) { block_capacity = MaxValue(block_capacity, temp.block_capacity); entry_size = MaxValue(entry_size, temp.entry_size); for (auto &block : temp.blocks) { - blocks.emplace_back(move(block)); + blocks.emplace_back(std::move(block)); } for (auto &handle : temp.pinned_blocks) { - pinned_blocks.emplace_back(move(handle)); + pinned_blocks.emplace_back(std::move(handle)); } } @@ -56487,7 +59843,7 @@ void RowDataCollectionScanner::AlignHeapBlocks(RowDataCollection &swizzled_block auto heap_offset = heap_ptr - heap_handle.Ptr(); RowOperations::SwizzleHeapPointer(layout, data_ptr, heap_ptr, data_block->count, heap_offset); } else { - swizzled_string_heap.pinned_blocks.emplace_back(move(heap_handle)); + swizzled_string_heap.pinned_blocks.emplace_back(std::move(heap_handle)); } // Update counter @@ -56534,7 +59890,7 @@ void RowDataCollectionScanner::AlignHeapBlocks(RowDataCollection &swizzled_block auto new_heap_ptr = new_heap_handle.Ptr(); if (swizzled_string_heap.keep_pinned) { // Since the heap blocks are pinned, we can unswizzle the data again. - swizzled_string_heap.pinned_blocks.emplace_back(move(new_heap_handle)); + swizzled_string_heap.pinned_blocks.emplace_back(std::move(new_heap_handle)); RowOperations::UnswizzlePointers(layout, base_row_ptr, new_heap_ptr, data_block->count); RowOperations::UnswizzleHeapPointer(layout, base_row_ptr, new_heap_ptr, data_block->count); } @@ -56702,6 +60058,14 @@ void RowDataCollectionScanner::Scan(DataChunk &chunk) { } } +void RowDataCollectionScanner::Reset(bool flush_p) { + flush = flush_p; + total_scanned = 0; + + read_state.block_idx = 0; + read_state.entry_idx = 0; +} + } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB @@ -56723,7 +60087,7 @@ RowLayout::RowLayout() void RowLayout::Initialize(vector types_p, Aggregates aggregates_p, bool align) { offsets.clear(); - types = move(types_p); + types = std::move(types_p); // Null mask at the front - 1 bit per value. flag_width = ValidityBytes::ValidityMaskSize(types.size()); @@ -56766,7 +60130,7 @@ void RowLayout::Initialize(vector types_p, Aggregates aggregates_p, data_width = row_width - flag_width; // Aggregate fields. - aggregates = move(aggregates_p); + aggregates = std::move(aggregates_p); for (auto &aggregate : aggregates) { offsets.push_back(row_width); row_width += aggregate.payload_size; @@ -56785,11 +60149,11 @@ void RowLayout::Initialize(vector types_p, Aggregates aggregates_p, } void RowLayout::Initialize(vector types_p, bool align) { - Initialize(move(types_p), Aggregates(), align); + Initialize(std::move(types_p), Aggregates(), align); } void RowLayout::Initialize(Aggregates aggregates_p, bool align) { - Initialize(vector(), move(aggregates_p), align); + Initialize(vector(), std::move(aggregates_p), align); } } // namespace duckdb @@ -56902,6 +60266,7 @@ string_t StringHeap::EmptyString(idx_t len) { + namespace duckdb { void string_t::Verify() const { @@ -56933,9 +60298,10 @@ void string_t::Verify() const { + +#include #include #include -#include namespace duckdb { @@ -57042,6 +60408,9 @@ bool Time::TryConvertTime(const char *buf, idx_t len, idx_t &pos, dtime_t &resul // last chance, check if we can parse as timestamp timestamp_t timestamp; if (Timestamp::TryConvertTimestamp(buf, len, timestamp)) { + if (!Timestamp::IsFinite(timestamp)) { + return false; + } result = Timestamp::GetTime(timestamp); return true; } @@ -57173,9 +60542,6 @@ static_assert(sizeof(timestamp_t) == sizeof(int64_t), "timestamp_t was padded"); // T may be a space // Z is optional // ISO 8601 -static inline bool CharacterIsTimeZone(char c) { - return StringUtil::CharacterIsAlpha(c) || StringUtil::CharacterIsDigit(c) || c == '_' || c == '/'; -} bool Timestamp::TryConvertTimestampTZ(const char *str, idx_t len, timestamp_t &result, bool &has_offset, string_t &tz) { idx_t pos; @@ -57584,7 +60950,7 @@ void ValidityMask::Combine(const ValidityMask &other, idx_t count) { } // have to merge // create a new validity mask that contains the combined mask - auto owned_data = move(validity_data); + auto owned_data = std::move(validity_data); auto data = GetData(); auto other_data = other.GetData(); @@ -57621,7 +60987,7 @@ void ValidityMask::Resize(idx_t old_size, idx_t new_size) { for (idx_t entry_idx = old_size_count; entry_idx < new_size_count; entry_idx++) { new_owned_data[entry_idx] = ValidityData::MAX_ENTRY; } - validity_data = move(new_validity_data); + validity_data = std::move(new_validity_data); validity_mask = validity_data->owned_data.get(); } else { Initialize(new_size); @@ -57792,6 +61158,7 @@ hugeint_t ModuloOperator::Operation(hugeint_t left, hugeint_t right); + //===----------------------------------------------------------------------===// // DuckDB // @@ -57934,7 +61301,7 @@ class ErrorManager { namespace duckdb { -Value::Value(LogicalType type) : type_(move(type)), is_null(true) { +Value::Value(LogicalType type) : type_(std::move(type)), is_null(true) { } Value::Value(int32_t val) : type_(LogicalType::INTEGER), is_null(false) { @@ -57962,7 +61329,7 @@ Value::Value(std::nullptr_t val) : Value(LogicalType::VARCHAR) { Value::Value(string_t val) : Value(string(val.GetDataUnsafe(), val.GetSize())) { } -Value::Value(string val) : type_(LogicalType::VARCHAR), is_null(false), str_value(move(val)) { +Value::Value(string val) : type_(LogicalType::VARCHAR), is_null(false), str_value(std::move(val)) { if (!Value::StringIsValid(str_value.c_str(), str_value.size())) { throw Exception(ErrorManager::InvalidUnicodeError(str_value, "value construction")); } @@ -57977,8 +61344,9 @@ Value::Value(const Value &other) } Value::Value(Value &&other) noexcept - : type_(move(other.type_)), is_null(other.is_null), value_(other.value_), str_value(move(other.str_value)), - struct_value(move(other.struct_value)), list_value(move(other.list_value)) { + : type_(std::move(other.type_)), is_null(other.is_null), value_(other.value_), + str_value(std::move(other.str_value)), struct_value(std::move(other.struct_value)), + list_value(std::move(other.list_value)) { } Value &Value::operator=(const Value &other) { @@ -57992,12 +61360,12 @@ Value &Value::operator=(const Value &other) { } Value &Value::operator=(Value &&other) noexcept { - type_ = move(other.type_); + type_ = std::move(other.type_); is_null = other.is_null; value_ = other.value_; - str_value = move(other.str_value); - struct_value = move(other.struct_value); - list_value = move(other.list_value); + str_value = std::move(other.str_value); + struct_value = std::move(other.struct_value); + list_value = std::move(other.list_value); return *this; } @@ -58267,19 +61635,11 @@ bool Value::StringIsValid(const char *str, idx_t length) { } Value Value::DECIMAL(int16_t value, uint8_t width, uint8_t scale) { - D_ASSERT(width <= Decimal::MAX_WIDTH_INT16); - Value result(LogicalType::DECIMAL(width, scale)); - result.value_.smallint = value; - result.is_null = false; - return result; + return Value::DECIMAL(int64_t(value), width, scale); } Value Value::DECIMAL(int32_t value, uint8_t width, uint8_t scale) { - D_ASSERT(width >= Decimal::MAX_WIDTH_INT16 && width <= Decimal::MAX_WIDTH_INT32); - Value result(LogicalType::DECIMAL(width, scale)); - result.value_.integer = value; - result.is_null = false; - return result; + return Value::DECIMAL(int64_t(value), width, scale); } Value Value::DECIMAL(int64_t value, uint8_t width, uint8_t scale) { @@ -58419,26 +61779,24 @@ Value Value::STRUCT(child_list_t values) { Value result; child_list_t child_types; for (auto &child : values) { - child_types.push_back(make_pair(move(child.first), child.second.type())); - result.struct_value.push_back(move(child.second)); + child_types.push_back(make_pair(std::move(child.first), child.second.type())); + result.struct_value.push_back(std::move(child.second)); } - result.type_ = LogicalType::STRUCT(move(child_types)); + result.type_ = LogicalType::STRUCT(std::move(child_types)); result.is_null = false; return result; } -Value Value::MAP(Value key, Value value) { +Value Value::MAP(LogicalType child_type, vector values) { Value result; - child_list_t child_types; - child_types.push_back({"key", key.type()}); - child_types.push_back({"value", value.type()}); - - result.type_ = LogicalType::MAP(move(child_types)); - result.struct_value.push_back(move(key)); - result.struct_value.push_back(move(value)); + result.type_ = LogicalType::MAP(std::move(child_type)); result.is_null = false; + if (values.empty()) { + return result; + } + result.list_value = std::move(values); return result; } @@ -58460,9 +61818,9 @@ Value Value::UNION(child_list_t members, uint8_t tag, Value value) result.struct_value.emplace_back(nullptr); } } - result.struct_value[tag + 1] = move(value); + result.struct_value[tag + 1] = std::move(value); - result.type_ = LogicalType::UNION(move(members)); + result.type_ = LogicalType::UNION(std::move(members)); return result; } @@ -58478,24 +61836,24 @@ Value Value::LIST(vector values) { #endif Value result; result.type_ = LogicalType::LIST(values[0].type()); - result.list_value = move(values); + result.list_value = std::move(values); result.is_null = false; return result; } Value Value::LIST(LogicalType child_type, vector values) { if (values.empty()) { - return Value::EMPTYLIST(move(child_type)); + return Value::EMPTYLIST(std::move(child_type)); } for (auto &val : values) { val = val.DefaultCastAs(child_type); } - return Value::LIST(move(values)); + return Value::LIST(std::move(values)); } Value Value::EMPTYLIST(LogicalType child_type) { Value result; - result.type_ = LogicalType::LIST(move(child_type)); + result.type_ = LogicalType::LIST(std::move(child_type)); result.is_null = false; return result; } @@ -58514,21 +61872,17 @@ Value Value::BLOB(const string &data) { return result; } -Value Value::JSON(const char *val) { - auto result = Value(val); - result.type_ = LogicalTypeId::JSON; - return result; -} - -Value Value::JSON(string_t val) { - auto result = Value(val); - result.type_ = LogicalTypeId::JSON; +Value Value::BIT(const_data_ptr_t data, idx_t len) { + Value result(LogicalType::BIT); + result.is_null = false; + result.str_value = string((const char *)data, len); return result; } -Value Value::JSON(string val) { - auto result = Value(move(val)); - result.type_ = LogicalTypeId::JSON; +Value Value::BIT(const string &data) { + Value result(LogicalType::BIT); + result.is_null = false; + result.str_value = Bit::ToBit(string_t(data)); return result; } @@ -58545,9 +61899,6 @@ Value Value::ENUM(uint64_t value, const LogicalType &original_type) { case PhysicalType::UINT32: result.value_.uinteger = value; break; - case PhysicalType::UINT64: // DEDUP_POINTER_ENUM - result.value_.ubigint = value; - break; default: throw InternalException("Incorrect Physical Type for ENUM"); } @@ -59491,6 +62842,10 @@ bool Value::DefaultTryCastAs(const LogicalType &target_type, bool strict) { return TryCastAs(set, get_input, target_type, strict); } +void Value::Reinterpret(LogicalType new_type) { + this->type_ = std::move(new_type); +} + void Value::Serialize(Serializer &main_serializer) const { FieldWriter writer(main_serializer); writer.WriteSerializable(type_); @@ -59711,6 +63066,7 @@ bool Value::DefaultValuesAreEqual(const Value &result_value, const Value &value) + namespace duckdb { enum class MapInvalidReason : uint8_t { VALID, NULL_KEY_LIST, NULL_KEY, DUPLICATE_KEY }; @@ -59719,7 +63075,7 @@ enum class UnionInvalidReason : uint8_t { VALID, TAG_OUT_OF_RANGE, NO_MEMBERS, V struct VariableReturnBindData : public FunctionData { LogicalType stype; - explicit VariableReturnBindData(LogicalType stype_p) : stype(move(stype_p)) { + explicit VariableReturnBindData(LogicalType stype_p) : stype(std::move(stype_p)) { } unique_ptr Copy() const override { @@ -59739,7 +63095,7 @@ struct VariableReturnBindData : public FunctionData { static unique_ptr Deserialize(ClientContext &context, FieldReader &reader, ScalarFunction &bound_function) { auto stype = reader.ReadRequiredSerializable(); - return make_unique(move(stype)); + return make_unique(std::move(stype)); } }; @@ -59873,17 +63229,17 @@ UnionInvalidReason CheckUnionValidity(Vector &vector, idx_t count, namespace duckdb { Vector::Vector(LogicalType type_p, bool create_data, bool zero_data, idx_t capacity) - : vector_type(VectorType::FLAT_VECTOR), type(move(type_p)), data(nullptr) { + : vector_type(VectorType::FLAT_VECTOR), type(std::move(type_p)), data(nullptr) { if (create_data) { Initialize(zero_data, capacity); } } -Vector::Vector(LogicalType type_p, idx_t capacity) : Vector(move(type_p), true, false, capacity) { +Vector::Vector(LogicalType type_p, idx_t capacity) : Vector(std::move(type_p), true, false, capacity) { } Vector::Vector(LogicalType type_p, data_ptr_t dataptr) - : vector_type(VectorType::FLAT_VECTOR), type(move(type_p)), data(dataptr) { + : vector_type(VectorType::FLAT_VECTOR), type(std::move(type_p)), data(dataptr) { if (dataptr && !type.IsValid()) { throw InternalException("Cannot create a vector of type INVALID!"); } @@ -59910,8 +63266,8 @@ Vector::Vector(const Value &value) : type(value.type()) { } Vector::Vector(Vector &&other) noexcept - : vector_type(other.vector_type), type(move(other.type)), data(other.data), validity(move(other.validity)), - buffer(move(other.buffer)), auxiliary(move(other.auxiliary)) { + : vector_type(other.vector_type), type(std::move(other.type)), data(other.data), + validity(std::move(other.validity)), buffer(std::move(other.buffer)), auxiliary(std::move(other.auxiliary)) { } void Vector::Reference(const Value &value) { @@ -59926,15 +63282,15 @@ void Vector::Reference(const Value &value) { auto &value_children = StructValue::GetChildren(value); for (idx_t i = 0; i < child_types.size(); i++) { auto vector = make_unique(value.IsNull() ? Value(child_types[i].second) : value_children[i]); - child_vectors.push_back(move(vector)); + child_vectors.push_back(std::move(vector)); } - auxiliary = move(struct_buffer); + auxiliary = std::move(struct_buffer); if (value.IsNull()) { SetValue(0, value); } } else if (internal_type == PhysicalType::LIST) { auto list_buffer = make_unique(value.type()); - auxiliary = move(list_buffer); + auxiliary = std::move(list_buffer); data = buffer->GetData(); SetValue(0, value); } else { @@ -60011,13 +63367,13 @@ void Vector::Slice(const SelectionVector &sel, idx_t count) { // already a dictionary, slice the current dictionary auto ¤t_sel = DictionaryVector::SelVector(*this); auto sliced_dictionary = current_sel.Slice(sel, count); - buffer = make_buffer(move(sliced_dictionary)); + buffer = make_buffer(std::move(sliced_dictionary)); if (GetType().InternalType() == PhysicalType::STRUCT) { auto &child_vector = DictionaryVector::Child(*this); Vector new_child(child_vector); new_child.auxiliary = make_buffer(new_child, sel, count); - auxiliary = make_buffer(move(new_child)); + auxiliary = make_buffer(std::move(new_child)); } return; } @@ -60032,11 +63388,11 @@ void Vector::Slice(const SelectionVector &sel, idx_t count) { if (internal_type == PhysicalType::STRUCT) { child_vector.auxiliary = make_buffer(*this, sel, count); } - auto child_ref = make_buffer(move(child_vector)); + auto child_ref = make_buffer(std::move(child_vector)); auto dict_buffer = make_buffer(sel); vector_type = VectorType::DICTIONARY_VECTOR; - buffer = move(dict_buffer); - auxiliary = move(child_ref); + buffer = std::move(dict_buffer); + auxiliary = std::move(child_ref); } void Vector::Slice(const SelectionVector &sel, idx_t count, SelCache &cache) { @@ -60066,10 +63422,10 @@ void Vector::Initialize(bool zero_data, idx_t capacity) { auto internal_type = type.InternalType(); if (internal_type == PhysicalType::STRUCT) { auto struct_buffer = make_unique(type, capacity); - auxiliary = move(struct_buffer); + auxiliary = std::move(struct_buffer); } else if (internal_type == PhysicalType::LIST) { auto list_buffer = make_unique(type, capacity); - auxiliary = move(list_buffer); + auxiliary = std::move(list_buffer); } auto type_size = GetTypeIdSize(internal_type); if (type_size > 0) { @@ -60147,7 +63503,7 @@ void Vector::Resize(idx_t cur_size, idx_t new_size) { if (!data_to_resize.is_nested) { auto new_data = unique_ptr(new data_t[new_size * data_to_resize.type_size]); memcpy(new_data.get(), data_to_resize.data, cur_size * data_to_resize.type_size * sizeof(data_t)); - data_to_resize.buffer->SetData(move(new_data)); + data_to_resize.buffer->SetData(std::move(new_data)); data_to_resize.vec.data = data_to_resize.buffer->GetData(); } data_to_resize.vec.validity.Resize(cur_size, new_size); @@ -60370,8 +63726,6 @@ Value Vector::GetValueInternal(const Vector &v_p, idx_t index_p) { return Value::ENUM(((uint16_t *)data)[index], type); case PhysicalType::UINT32: return Value::ENUM(((uint32_t *)data)[index], type); - case PhysicalType::UINT64: // DEDUP_POINTER_ENUM - return Value::ENUM(((uint64_t *)data)[index], type); default: throw InternalException("ENUM can only have unsigned integers as physical types"); } @@ -60388,26 +63742,29 @@ Value Vector::GetValueInternal(const Vector &v_p, idx_t index_p) { auto str = ((string_t *)data)[index]; return Value(str.GetString()); } - case LogicalTypeId::JSON: { - auto str = ((string_t *)data)[index]; - return Value::JSON(str.GetString()); - } case LogicalTypeId::AGGREGATE_STATE: case LogicalTypeId::BLOB: { auto str = ((string_t *)data)[index]; return Value::BLOB((const_data_ptr_t)str.GetDataUnsafe(), str.GetSize()); } + case LogicalTypeId::BIT: { + auto str = ((string_t *)data)[index]; + return Value::BIT((const_data_ptr_t)str.GetDataUnsafe(), str.GetSize()); + } case LogicalTypeId::MAP: { - auto &child_entries = StructVector::GetEntries(*vector); - Value key = child_entries[0]->GetValue(index); - Value value = child_entries[1]->GetValue(index); - return Value::MAP(move(key), move(value)); + auto offlen = ((list_entry_t *)data)[index]; + auto &child_vec = ListVector::GetEntry(*vector); + std::vector children; + for (idx_t i = offlen.offset; i < offlen.offset + offlen.length; i++) { + children.push_back(child_vec.GetValue(i)); + } + return Value::MAP(ListType::GetChildType(type), std::move(children)); } case LogicalTypeId::UNION: { auto tag = UnionVector::GetTag(*vector, index); auto value = UnionVector::GetMember(*vector, tag).GetValue(index); auto members = UnionType::CopyMemberTypes(type); - return Value::UNION(members, tag, move(value)); + return Value::UNION(members, tag, std::move(value)); } case LogicalTypeId::STRUCT: { // we can derive the value schema from the vector schema @@ -60417,7 +63774,7 @@ Value Vector::GetValueInternal(const Vector &v_p, idx_t index_p) { auto &struct_child = child_entries[child_idx]; children.push_back(make_pair(StructType::GetChildName(type, child_idx), struct_child->GetValue(index_p))); } - return Value::STRUCT(move(children)); + return Value::STRUCT(std::move(children)); } case LogicalTypeId::LIST: { auto offlen = ((list_entry_t *)data)[index]; @@ -60426,7 +63783,7 @@ Value Vector::GetValueInternal(const Vector &v_p, idx_t index_p) { for (idx_t i = offlen.offset; i < offlen.offset + offlen.length; i++) { children.push_back(child_vec.GetValue(i)); } - return Value::LIST(ListType::GetChildType(type), move(children)); + return Value::LIST(ListType::GetChildType(type), std::move(children)); } default: throw InternalException("Unimplemented type for value access"); @@ -60437,9 +63794,10 @@ Value Vector::GetValue(const Vector &v_p, idx_t index_p) { auto value = GetValueInternal(v_p, index_p); // set the alias of the type to the correct value, if there is a type alias if (v_p.GetType().HasAlias()) { - value.type().CopyAuxInfo(v_p.GetType()); + value.GetTypeMutable().CopyAuxInfo(v_p.GetType()); } if (v_p.GetType().id() != LogicalTypeId::AGGREGATE_STATE && value.type().id() != LogicalTypeId::AGGREGATE_STATE) { + D_ASSERT(v_p.GetType() == value.type()); } return value; @@ -60505,7 +63863,7 @@ string Vector::ToString(idx_t count) const { return retval; } -void Vector::Print(idx_t count) { +void Vector::Print(idx_t count) const { Printer::Print(ToString(count)); } @@ -60529,7 +63887,7 @@ string Vector::ToString() const { return retval; } -void Vector::Print() { +void Vector::Print() const { Printer::Print(ToString()); } // LCOV_EXCL_STOP @@ -60572,7 +63930,7 @@ void Vector::Flatten(idx_t count) { case VectorType::CONSTANT_VECTOR: { bool is_null = ConstantVector::IsNull(*this); // allocate a new buffer for the vector - auto old_buffer = move(buffer); + auto old_buffer = std::move(buffer); auto old_data = data; buffer = VectorBuffer::CreateStandardVector(type, MaxValue(STANDARD_VECTOR_SIZE, count)); data = buffer->GetData(); @@ -60641,9 +63999,9 @@ void Vector::Flatten(idx_t count) { D_ASSERT(child->GetVectorType() == VectorType::CONSTANT_VECTOR); auto vector = make_unique(*child); vector->Flatten(count); - new_children.push_back(move(vector)); + new_children.push_back(std::move(vector)); } - auxiliary = move(normalified_buffer); + auxiliary = std::move(normalified_buffer); } break; default: throw InternalException("Unimplemented type for VectorOperations::Flatten"); @@ -60705,12 +64063,12 @@ void Vector::ToUnifiedFormat(idx_t count, UnifiedVectorFormat &data) { // dictionary with non-flat child: create a new reference to the child and normalify it Vector child_vector(child); child_vector.Flatten(sel, count); - auto new_aux = make_buffer(move(child_vector)); + auto new_aux = make_buffer(std::move(child_vector)); data.sel = &sel; data.data = FlatVector::GetData(new_aux->data); data.validity = FlatVector::Validity(new_aux->data); - this->auxiliary = move(new_aux); + this->auxiliary = std::move(new_aux); } break; } @@ -60963,7 +64321,7 @@ void Vector::Verify(Vector &vector_p, const SelectionVector &sel_p, idx_t count) (vtype == VectorType::CONSTANT_VECTOR || vtype == VectorType::FLAT_VECTOR)) { D_ASSERT(!vector->auxiliary); } - if (type.id() == LogicalTypeId::VARCHAR || type.id() == LogicalTypeId::JSON) { + if (type.id() == LogicalTypeId::VARCHAR) { // verify that the string is correct unicode switch (vtype) { case VectorType::FLAT_VECTOR: { @@ -60982,6 +64340,25 @@ void Vector::Verify(Vector &vector_p, const SelectionVector &sel_p, idx_t count) } } + if (type.id() == LogicalTypeId::BIT) { + switch (vtype) { + case VectorType::FLAT_VECTOR: { + auto &validity = FlatVector::Validity(*vector); + auto strings = FlatVector::GetData(*vector); + for (idx_t i = 0; i < count; i++) { + auto oidx = sel->get_index(i); + if (validity.RowIsValid(oidx)) { + auto buf = strings[oidx].GetDataUnsafe(); + D_ASSERT(*buf >= 0 && *buf < 8); + } + } + break; + } + default: + break; + } + } + if (type.InternalType() == PhysicalType::STRUCT) { auto &child_types = StructType::GetChildTypes(type); D_ASSERT(!child_types.empty()); @@ -61175,6 +64552,7 @@ void ConstantVector::Reference(Vector &vector, Vector &source, idx_t position, i ConstantVector::Reference(*target_entries[i], *source_entries[i], position, count); } vector.SetVectorType(VectorType::CONSTANT_VECTOR); + vector.validity.Set(0, true); break; } default: @@ -61204,7 +64582,7 @@ string_t StringVector::AddString(Vector &vector, const string &data) { } string_t StringVector::AddString(Vector &vector, string_t data) { - D_ASSERT(vector.GetType().id() == LogicalTypeId::VARCHAR || vector.GetType().id() == LogicalTypeId::JSON); + D_ASSERT(vector.GetType().id() == LogicalTypeId::VARCHAR); if (data.IsInlined()) { // string will be inlined: no need to store in string heap return data; @@ -61250,7 +64628,7 @@ void StringVector::AddHandle(Vector &vector, BufferHandle handle) { vector.auxiliary = make_buffer(); } auto &string_buffer = (VectorStringBuffer &)*vector.auxiliary; - string_buffer.AddHeapReference(make_buffer(move(handle))); + string_buffer.AddHeapReference(make_buffer(std::move(handle))); } void StringVector::AddBuffer(Vector &vector, buffer_ptr buffer) { @@ -61260,7 +64638,7 @@ void StringVector::AddBuffer(Vector &vector, buffer_ptr buffer) { vector.auxiliary = make_buffer(); } auto &string_buffer = (VectorStringBuffer &)*vector.auxiliary; - string_buffer.AddHeapReference(move(buffer)); + string_buffer.AddHeapReference(std::move(buffer)); } void StringVector::AddHeapReference(Vector &vector, Vector &other) { @@ -61363,12 +64741,12 @@ void FSSTVector::DecompressVector(const Vector &src, Vector &dst, idx_t src_offs } Vector &MapVector::GetKeys(Vector &vector) { - auto &entries = StructVector::GetEntries(vector); + auto &entries = StructVector::GetEntries(ListVector::GetEntry(vector)); D_ASSERT(entries.size() == 2); return *entries[0]; } Vector &MapVector::GetValues(Vector &vector) { - auto &entries = StructVector::GetEntries(vector); + auto &entries = StructVector::GetEntries(ListVector::GetEntry(vector)); D_ASSERT(entries.size() == 2); return *entries[1]; } @@ -61381,8 +64759,7 @@ const Vector &MapVector::GetValues(const Vector &vector) { } vector> &StructVector::GetEntries(Vector &vector) { - D_ASSERT(vector.GetType().id() == LogicalTypeId::STRUCT || vector.GetType().id() == LogicalTypeId::MAP || - vector.GetType().id() == LogicalTypeId::UNION); + D_ASSERT(vector.GetType().id() == LogicalTypeId::STRUCT || vector.GetType().id() == LogicalTypeId::UNION); if (vector.GetVectorType() == VectorType::DICTIONARY_VECTOR) { auto &child = DictionaryVector::Child(vector); @@ -61400,7 +64777,7 @@ const vector> &StructVector::GetEntries(const Vector &vector) } const Vector &ListVector::GetEntry(const Vector &vector) { - D_ASSERT(vector.GetType().id() == LogicalTypeId::LIST); + D_ASSERT(vector.GetType().id() == LogicalTypeId::LIST || vector.GetType().id() == LogicalTypeId::MAP); if (vector.GetVectorType() == VectorType::DICTIONARY_VECTOR) { auto &child = DictionaryVector::Child(vector); return ListVector::GetEntry(child); @@ -61418,7 +64795,7 @@ Vector &ListVector::GetEntry(Vector &vector) { } void ListVector::Reserve(Vector &vector, idx_t required_capacity) { - D_ASSERT(vector.GetType().id() == LogicalTypeId::LIST); + D_ASSERT(vector.GetType().id() == LogicalTypeId::LIST || vector.GetType().id() == LogicalTypeId::MAP); D_ASSERT(vector.GetVectorType() == VectorType::FLAT_VECTOR || vector.GetVectorType() == VectorType::CONSTANT_VECTOR); D_ASSERT(vector.auxiliary); @@ -61428,10 +64805,10 @@ void ListVector::Reserve(Vector &vector, idx_t required_capacity) { } template -void TemplatedSearchInMap(Vector &list, T key, vector &offsets, bool is_key_null, idx_t offset, idx_t length) { - auto &list_vector = ListVector::GetEntry(list); +void TemplatedSearchInMap(Vector &keys, idx_t count, T key, vector &offsets, bool is_key_null, idx_t offset, + idx_t length) { UnifiedVectorFormat vector_data; - list_vector.ToUnifiedFormat(ListVector::GetListSize(list), vector_data); + keys.ToUnifiedFormat(count, vector_data); auto data = (T *)vector_data.data; auto validity_mask = vector_data.validity; @@ -61454,16 +64831,15 @@ void TemplatedSearchInMap(Vector &list, T key, vector &offsets, bool is_k } template -void TemplatedSearchInMap(Vector &list, const Value &key, vector &offsets, bool is_key_null, idx_t offset, - idx_t length) { - TemplatedSearchInMap(list, key.template GetValueUnsafe(), offsets, is_key_null, offset, length); +void TemplatedSearchInMap(Vector &keys, idx_t count, const Value &key, vector &offsets, bool is_key_null, + idx_t offset, idx_t length) { + TemplatedSearchInMap(keys, count, key.template GetValueUnsafe(), offsets, is_key_null, offset, length); } -void SearchStringInMap(Vector &list, const string &key, vector &offsets, bool is_key_null, idx_t offset, - idx_t length) { - auto &list_vector = ListVector::GetEntry(list); +void SearchStringInMap(Vector &keys, idx_t count, const string &key, vector &offsets, bool is_key_null, + idx_t offset, idx_t length) { UnifiedVectorFormat vector_data; - list_vector.ToUnifiedFormat(ListVector::GetListSize(list), vector_data); + keys.ToUnifiedFormat(count, vector_data); auto data = (string_t *)vector_data.data; auto validity_mask = vector_data.validity; if (is_key_null) { @@ -61485,64 +64861,63 @@ void SearchStringInMap(Vector &list, const string &key, vector &offsets, } } -vector ListVector::Search(Vector &list, const Value &key, idx_t row) { +vector MapVector::Search(Vector &keys, idx_t count, const Value &key, list_entry_t &entry) { vector offsets; - auto &list_vector = ListVector::GetEntry(list); - auto &entry = ListVector::GetData(list)[row]; - - switch (list_vector.GetType().InternalType()) { + switch (keys.GetType().InternalType()) { case PhysicalType::BOOL: case PhysicalType::INT8: - TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); + TemplatedSearchInMap(keys, count, key, offsets, key.IsNull(), entry.offset, entry.length); break; case PhysicalType::INT16: - TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); + TemplatedSearchInMap(keys, count, key, offsets, key.IsNull(), entry.offset, entry.length); break; case PhysicalType::INT32: - TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); + TemplatedSearchInMap(keys, count, key, offsets, key.IsNull(), entry.offset, entry.length); break; case PhysicalType::INT64: - TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); + TemplatedSearchInMap(keys, count, key, offsets, key.IsNull(), entry.offset, entry.length); break; case PhysicalType::INT128: - TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); + TemplatedSearchInMap(keys, count, key, offsets, key.IsNull(), entry.offset, entry.length); break; case PhysicalType::UINT8: - TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); + TemplatedSearchInMap(keys, count, key, offsets, key.IsNull(), entry.offset, entry.length); break; case PhysicalType::UINT16: - TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); + TemplatedSearchInMap(keys, count, key, offsets, key.IsNull(), entry.offset, entry.length); break; case PhysicalType::UINT32: - TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); + TemplatedSearchInMap(keys, count, key, offsets, key.IsNull(), entry.offset, entry.length); break; case PhysicalType::UINT64: - TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); + TemplatedSearchInMap(keys, count, key, offsets, key.IsNull(), entry.offset, entry.length); break; case PhysicalType::FLOAT: - TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); + TemplatedSearchInMap(keys, count, key, offsets, key.IsNull(), entry.offset, entry.length); break; case PhysicalType::DOUBLE: - TemplatedSearchInMap(list, key, offsets, key.IsNull(), entry.offset, entry.length); + TemplatedSearchInMap(keys, count, key, offsets, key.IsNull(), entry.offset, entry.length); + break; + case PhysicalType::INTERVAL: + TemplatedSearchInMap(keys, count, key, offsets, key.IsNull(), entry.offset, entry.length); break; case PhysicalType::VARCHAR: - SearchStringInMap(list, StringValue::Get(key), offsets, key.IsNull(), entry.offset, entry.length); + SearchStringInMap(keys, count, StringValue::Get(key), offsets, key.IsNull(), entry.offset, entry.length); break; default: - throw InvalidTypeException(list.GetType().id(), "Invalid type for List Vector Search"); + throw InvalidTypeException(keys.GetType().id(), "Invalid type for List Vector Search"); } return offsets; } -Value ListVector::GetValuesFromOffsets(Vector &list, vector &offsets) { - auto &child_vec = ListVector::GetEntry(list); +Value FlatVector::GetValuesFromOffsets(Vector &values, vector &offsets) { vector list_values; list_values.reserve(offsets.size()); for (auto &offset : offsets) { - list_values.push_back(child_vec.GetValue(offset)); + list_values.push_back(values.GetValue(offset)); } - return Value::LIST(ListType::GetChildType(list.GetType()), move(list_values)); + return Value::LIST(values.GetType(), std::move(list_values)); } idx_t ListVector::GetListSize(const Vector &vec) { @@ -61604,6 +64979,97 @@ void ListVector::PushBack(Vector &target, const Value &insert) { target_buffer.PushBack(insert); } +idx_t ListVector::GetConsecutiveChildList(Vector &list, Vector &result, idx_t offset, idx_t count) { + + auto info = ListVector::GetConsecutiveChildListInfo(list, offset, count); + if (info.needs_slicing) { + SelectionVector sel(info.child_list_info.length); + ListVector::GetConsecutiveChildSelVector(list, sel, offset, count); + + result.Slice(sel, info.child_list_info.length); + result.Flatten(info.child_list_info.length); + } + return info.child_list_info.length; +} + +ConsecutiveChildListInfo ListVector::GetConsecutiveChildListInfo(Vector &list, idx_t offset, idx_t count) { + + ConsecutiveChildListInfo info; + UnifiedVectorFormat unified_list_data; + list.ToUnifiedFormat(offset + count, unified_list_data); + auto list_data = (list_entry_t *)unified_list_data.data; + + // find the first non-NULL entry + idx_t first_length = 0; + for (idx_t i = offset; i < offset + count; i++) { + auto idx = unified_list_data.sel->get_index(i); + if (!unified_list_data.validity.RowIsValid(idx)) { + continue; + } + info.child_list_info.offset = list_data[idx].offset; + first_length = list_data[idx].length; + break; + } + + // small performance improvement for constant vectors + // avoids iterating over all their (constant) elements + if (list.GetVectorType() == VectorType::CONSTANT_VECTOR) { + info.child_list_info.length = first_length; + return info; + } + + // now get the child count and determine whether the children are stored consecutively + // also determine if a flat vector has pseudo constant values (all offsets + length the same) + // this can happen e.g. for UNNESTs + bool is_consecutive = true; + for (idx_t i = offset; i < offset + count; i++) { + auto idx = unified_list_data.sel->get_index(i); + if (!unified_list_data.validity.RowIsValid(idx)) { + continue; + } + if (list_data[idx].offset != info.child_list_info.offset || list_data[idx].length != first_length) { + info.is_constant = false; + } + if (list_data[idx].offset != info.child_list_info.offset + info.child_list_info.length) { + is_consecutive = false; + } + info.child_list_info.length += list_data[idx].length; + } + + if (info.is_constant) { + info.child_list_info.length = first_length; + } + if (!info.is_constant && !is_consecutive) { + info.needs_slicing = true; + } + + return info; +} + +void ListVector::GetConsecutiveChildSelVector(Vector &list, SelectionVector &sel, idx_t offset, idx_t count) { + + UnifiedVectorFormat unified_list_data; + list.ToUnifiedFormat(offset + count, unified_list_data); + auto list_data = (list_entry_t *)unified_list_data.data; + + // SelectionVector child_sel(info.second.length); + idx_t entry = 0; + for (idx_t i = offset; i < offset + count; i++) { + auto idx = unified_list_data.sel->get_index(i); + if (!unified_list_data.validity.RowIsValid(idx)) { + continue; + } + for (idx_t k = 0; k < list_data[idx].length; k++) { + // child_sel.set_index(entry++, list_data[idx].offset + k); + sel.set_index(entry++, list_data[idx].offset + k); + } + } + // + // result.Slice(child_sel, info.second.length); + // result.Flatten(info.second.length); + // info.second.offset = 0; +} + // Union vector const Vector &UnionVector::GetMember(const Vector &vector, idx_t member_index) { D_ASSERT(member_index < UnionType::GetMemberCount(vector.GetType())); @@ -61735,7 +65201,7 @@ VectorStructBuffer::VectorStructBuffer(const LogicalType &type, idx_t capacity) auto &child_types = StructType::GetChildTypes(type); for (auto &child_type : child_types) { auto vector = make_unique(child_type.second, capacity); - children.push_back(move(vector)); + children.push_back(std::move(vector)); } } @@ -61744,7 +65210,7 @@ VectorStructBuffer::VectorStructBuffer(Vector &other, const SelectionVector &sel auto &other_vector = StructVector::GetEntries(other); for (auto &child_vector : other_vector) { auto vector = make_unique(*child_vector, sel, count); - children.push_back(move(vector)); + children.push_back(std::move(vector)); } } @@ -61752,7 +65218,7 @@ VectorStructBuffer::~VectorStructBuffer() { } VectorListBuffer::VectorListBuffer(unique_ptr vector, idx_t initial_capacity) - : VectorBuffer(VectorBufferType::LIST_BUFFER), capacity(initial_capacity), child(move(vector)) { + : VectorBuffer(VectorBufferType::LIST_BUFFER), capacity(initial_capacity), child(std::move(vector)) { } VectorListBuffer::VectorListBuffer(const LogicalType &list_type, idx_t initial_capacity) @@ -61794,7 +65260,7 @@ VectorListBuffer::~VectorListBuffer() { } ManagedVectorBuffer::ManagedVectorBuffer(BufferHandle handle) - : VectorBuffer(VectorBufferType::MANAGED_BUFFER), handle(move(handle)) { + : VectorBuffer(VectorBufferType::MANAGED_BUFFER), handle(std::move(handle)) { } ManagedVectorBuffer::~ManagedVectorBuffer() { @@ -61821,7 +65287,7 @@ class VectorCacheBuffer : public VectorBuffer { auto &child_type = ListType::GetChildType(type); child_caches.push_back(make_buffer(allocator, child_type)); auto child_vector = make_unique(child_type, false, false); - auxiliary = make_unique(move(child_vector)); + auxiliary = make_unique(std::move(child_vector)); break; } case PhysicalType::STRUCT: { @@ -61830,7 +65296,7 @@ class VectorCacheBuffer : public VectorBuffer { child_caches.push_back(make_buffer(allocator, child_type.second)); } auto struct_buffer = make_unique(type); - auxiliary = move(struct_buffer); + auxiliary = std::move(struct_buffer); break; } default: @@ -61943,36 +65409,6 @@ const sel_t ConstantVector::ZERO_VECTOR[STANDARD_VECTOR_SIZE] = {0}; - - - - - - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/function/cast_rules.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { -//! Contains a list of rules for casting -class CastRules { -public: - //! Returns the cost of performing an implicit cost from "from" to "to", or -1 if an implicit cast is not possible - static int64_t ImplicitCast(const LogicalType &from, const LogicalType &to); -}; - -} // namespace duckdb - //===----------------------------------------------------------------------===// // DuckDB // @@ -62011,6 +65447,37 @@ using string_set_t = unordered_set; } // namespace duckdb + + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/function/cast_rules.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { +//! Contains a list of rules for casting +class CastRules { +public: + //! Returns the cost of performing an implicit cost from "from" to "to", or -1 if an implicit cast is not possible + static int64_t ImplicitCast(const LogicalType &from, const LogicalType &to); +}; + +} // namespace duckdb + + + + #include namespace duckdb { @@ -62022,7 +65489,7 @@ LogicalType::LogicalType(LogicalTypeId id) : id_(id) { physical_type_ = GetInternalType(); } LogicalType::LogicalType(LogicalTypeId id, shared_ptr type_info_p) - : id_(id), type_info_(move(type_info_p)) { + : id_(id), type_info_(std::move(type_info_p)) { physical_type_ = GetInternalType(); } @@ -62031,7 +65498,7 @@ LogicalType::LogicalType(const LogicalType &other) } LogicalType::LogicalType(LogicalType &&other) noexcept - : id_(other.id_), physical_type_(other.physical_type_), type_info_(move(other.type_info_)) { + : id_(other.id_), physical_type_(other.physical_type_), type_info_(std::move(other.type_info_)) { } hash_t LogicalType::Hash() const { @@ -62095,15 +65562,15 @@ PhysicalType LogicalType::GetInternalType() { case LogicalTypeId::VARCHAR: case LogicalTypeId::CHAR: case LogicalTypeId::BLOB: - case LogicalTypeId::JSON: + case LogicalTypeId::BIT: return PhysicalType::VARCHAR; case LogicalTypeId::INTERVAL: return PhysicalType::INTERVAL; - case LogicalTypeId::MAP: case LogicalTypeId::UNION: case LogicalTypeId::STRUCT: return PhysicalType::STRUCT; case LogicalTypeId::LIST: + case LogicalTypeId::MAP: return PhysicalType::LIST; case LogicalTypeId::POINTER: // LCOV_EXCL_START @@ -62118,7 +65585,9 @@ PhysicalType LogicalType::GetInternalType() { case LogicalTypeId::VALIDITY: return PhysicalType::BIT; case LogicalTypeId::ENUM: { - D_ASSERT(type_info_); + if (!type_info_) { + return PhysicalType::INVALID; + } return EnumType::GetPhysicalType(*this); } case LogicalTypeId::TABLE: @@ -62167,9 +65636,9 @@ constexpr const LogicalTypeId LogicalType::HASH; constexpr const LogicalTypeId LogicalType::POINTER; constexpr const LogicalTypeId LogicalType::VARCHAR; -constexpr const LogicalTypeId LogicalType::JSON; constexpr const LogicalTypeId LogicalType::BLOB; +constexpr const LogicalTypeId LogicalType::BIT; constexpr const LogicalTypeId LogicalType::INTERVAL; constexpr const LogicalTypeId LogicalType::ROW_TYPE; @@ -62196,13 +65665,13 @@ const vector LogicalType::Integral() { const vector LogicalType::AllTypes() { vector types = { - LogicalType::BOOLEAN, LogicalType::TINYINT, LogicalType::SMALLINT, LogicalType::INTEGER, - LogicalType::BIGINT, LogicalType::DATE, LogicalType::TIMESTAMP, LogicalType::DOUBLE, - LogicalType::FLOAT, LogicalType::VARCHAR, LogicalType::BLOB, LogicalType::INTERVAL, - LogicalType::HUGEINT, LogicalTypeId::DECIMAL, LogicalType::UTINYINT, LogicalType::USMALLINT, - LogicalType::UINTEGER, LogicalType::UBIGINT, LogicalType::TIME, LogicalTypeId::LIST, - LogicalTypeId::STRUCT, LogicalType::TIME_TZ, LogicalType::TIMESTAMP_TZ, LogicalTypeId::MAP, - LogicalTypeId::UNION, LogicalType::UUID, LogicalType::JSON}; + LogicalType::BOOLEAN, LogicalType::TINYINT, LogicalType::SMALLINT, LogicalType::INTEGER, + LogicalType::BIGINT, LogicalType::DATE, LogicalType::TIMESTAMP, LogicalType::DOUBLE, + LogicalType::FLOAT, LogicalType::VARCHAR, LogicalType::BLOB, LogicalType::BIT, + LogicalType::INTERVAL, LogicalType::HUGEINT, LogicalTypeId::DECIMAL, LogicalType::UTINYINT, + LogicalType::USMALLINT, LogicalType::UINTEGER, LogicalType::UBIGINT, LogicalType::TIME, + LogicalTypeId::LIST, LogicalTypeId::STRUCT, LogicalType::TIME_TZ, LogicalType::TIMESTAMP_TZ, + LogicalTypeId::MAP, LogicalTypeId::UNION, LogicalType::UUID}; return types; } @@ -62247,8 +65716,6 @@ string TypeIdToString(PhysicalType type) { return "INVALID"; case PhysicalType::BIT: return "BIT"; - case PhysicalType::MAP: - return "MAP"; case PhysicalType::UNKNOWN: return "UNKNOWN"; } @@ -62396,8 +65863,8 @@ string LogicalTypeIdToString(LogicalTypeId id) { return "AGGREGATE_STATE"; case LogicalTypeId::USER: return "USER"; - case LogicalTypeId::JSON: - return "JSON"; + case LogicalTypeId::BIT: + return "BIT"; } return "UNDEFINED"; } @@ -62433,15 +65900,9 @@ string LogicalType::ToString() const { if (!type_info_) { return "MAP"; } - auto &child_types = StructType::GetChildTypes(*this); - if (child_types.empty()) { - return "MAP(?)"; - } - if (child_types.size() != 2) { - throw InternalException("Map needs exactly two child elements"); - } - return "MAP(" + ListType::GetChildType(child_types[0].second).ToString() + ", " + - ListType::GetChildType(child_types[1].second).ToString() + ")"; + auto &key_type = MapType::KeyType(*this); + auto &value_type = MapType::ValueType(*this); + return "MAP(" + key_type.ToString() + ", " + value_type.ToString() + ")"; } case LogicalTypeId::UNION: { if (!type_info_) { @@ -62450,7 +65911,7 @@ string LogicalType::ToString() const { string ret = "UNION("; size_t count = UnionType::GetMemberCount(*this); for (size_t i = 0; i < count; i++) { - ret += UnionType::GetMemberType(*this, i).ToString(); + ret += UnionType::GetMemberName(*this, i) + " " + UnionType::GetMemberType(*this, i).ToString(); if (i < count - 1) { ret += ", "; } @@ -62501,6 +65962,13 @@ LogicalType TransformStringToLogicalType(const string &str) { return Parser::ParseColumnList("dummy " + str).GetColumn(LogicalIndex(0)).Type(); } +LogicalType TransformStringToLogicalType(const string &str, ClientContext &context) { + auto type = TransformStringToLogicalType(str); + return type.id() == LogicalTypeId::USER + ? Catalog::GetSystemCatalog(context).GetType(context, SYSTEM_CATALOG, DEFAULT_SCHEMA, str) + : type; +} + bool LogicalType::IsIntegral() const { switch (id_) { case LogicalTypeId::TINYINT: @@ -62735,9 +66203,14 @@ LogicalType LogicalType::MaxLogicalType(const LogicalType &left, const LogicalTy if (type_id == LogicalTypeId::LIST) { // list: perform max recursively on child type auto new_child = MaxLogicalType(ListType::GetChildType(left), ListType::GetChildType(right)); - return LogicalType::LIST(move(new_child)); + return LogicalType::LIST(std::move(new_child)); + } + if (type_id == LogicalTypeId::MAP) { + // list: perform max recursively on child type + auto new_child = MaxLogicalType(ListType::GetChildType(left), ListType::GetChildType(right)); + return LogicalType::MAP(std::move(new_child)); } - if (type_id == LogicalTypeId::STRUCT || type_id == LogicalTypeId::MAP) { + if (type_id == LogicalTypeId::STRUCT) { // struct: perform recursively auto &left_child_types = StructType::GetChildTypes(left); auto &right_child_types = StructType::GetChildTypes(right); @@ -62749,11 +66222,10 @@ LogicalType LogicalType::MaxLogicalType(const LogicalType &left, const LogicalTy child_list_t child_types; for (idx_t i = 0; i < left_child_types.size(); i++) { auto child_type = MaxLogicalType(left_child_types[i].second, right_child_types[i].second); - child_types.push_back(make_pair(left_child_types[i].first, move(child_type))); + child_types.push_back(make_pair(left_child_types[i].first, std::move(child_type))); } - return type_id == LogicalTypeId::STRUCT ? LogicalType::STRUCT(move(child_types)) - : LogicalType::MAP(move(child_types)); + return LogicalType::STRUCT(std::move(child_types)); } if (type_id == LogicalTypeId::UNION) { auto left_member_count = UnionType::GetMemberCount(left); @@ -62818,7 +66290,7 @@ enum class ExtraTypeInfoType : uint8_t { struct ExtraTypeInfo { explicit ExtraTypeInfo(ExtraTypeInfoType type) : type(type) { } - explicit ExtraTypeInfo(ExtraTypeInfoType type, string alias) : type(type), alias(move(alias)) { + explicit ExtraTypeInfo(ExtraTypeInfoType type, string alias) : type(type), alias(std::move(alias)) { } virtual ~ExtraTypeInfo() { } @@ -62867,9 +66339,9 @@ struct ExtraTypeInfo { void LogicalType::SetAlias(string alias) { if (!type_info_) { - type_info_ = make_shared(ExtraTypeInfoType::GENERIC_TYPE_INFO, move(alias)); + type_info_ = make_shared(ExtraTypeInfoType::GENERIC_TYPE_INFO, std::move(alias)); } else { - type_info_->alias = move(alias); + type_info_->alias = std::move(alias); } } @@ -62953,7 +66425,7 @@ uint8_t DecimalType::MaxWidth() { LogicalType LogicalType::DECIMAL(int width, int scale) { D_ASSERT(width >= scale); auto type_info = make_shared(width, scale); - return LogicalType(LogicalTypeId::DECIMAL, move(type_info)); + return LogicalType(LogicalTypeId::DECIMAL, std::move(type_info)); } //===--------------------------------------------------------------------===// @@ -62961,7 +66433,7 @@ LogicalType LogicalType::DECIMAL(int width, int scale) { //===--------------------------------------------------------------------===// struct StringTypeInfo : public ExtraTypeInfo { explicit StringTypeInfo(string collation_p) - : ExtraTypeInfo(ExtraTypeInfoType::STRING_TYPE_INFO), collation(move(collation_p)) { + : ExtraTypeInfo(ExtraTypeInfoType::STRING_TYPE_INFO), collation(std::move(collation_p)) { } string collation; @@ -62973,7 +66445,7 @@ struct StringTypeInfo : public ExtraTypeInfo { static shared_ptr Deserialize(FieldReader &reader) { auto collation = reader.ReadRequired(); - return make_shared(move(collation)); + return make_shared(std::move(collation)); } protected: @@ -62998,8 +66470,8 @@ string StringType::GetCollation(const LogicalType &type) { } LogicalType LogicalType::VARCHAR_COLLATION(string collation) { // NOLINT - auto string_info = make_shared(move(collation)); - return LogicalType(LogicalTypeId::VARCHAR, move(string_info)); + auto string_info = make_shared(std::move(collation)); + return LogicalType(LogicalTypeId::VARCHAR, std::move(string_info)); } //===--------------------------------------------------------------------===// @@ -63007,7 +66479,7 @@ LogicalType LogicalType::VARCHAR_COLLATION(string collation) { // NOLINT //===--------------------------------------------------------------------===// struct ListTypeInfo : public ExtraTypeInfo { explicit ListTypeInfo(LogicalType child_type_p) - : ExtraTypeInfo(ExtraTypeInfoType::LIST_TYPE_INFO), child_type(move(child_type_p)) { + : ExtraTypeInfo(ExtraTypeInfoType::LIST_TYPE_INFO), child_type(std::move(child_type_p)) { } LogicalType child_type; @@ -63019,7 +66491,7 @@ struct ListTypeInfo : public ExtraTypeInfo { static shared_ptr Deserialize(FieldReader &reader) { auto child_type = reader.ReadRequiredSerializable(); - return make_shared(move(child_type)); + return make_shared(std::move(child_type)); } protected: @@ -63030,15 +66502,15 @@ struct ListTypeInfo : public ExtraTypeInfo { }; const LogicalType &ListType::GetChildType(const LogicalType &type) { - D_ASSERT(type.id() == LogicalTypeId::LIST); + D_ASSERT(type.id() == LogicalTypeId::LIST || type.id() == LogicalTypeId::MAP); auto info = type.AuxInfo(); D_ASSERT(info); return ((ListTypeInfo &)*info).child_type; } LogicalType LogicalType::LIST(LogicalType child) { - auto info = make_shared(move(child)); - return LogicalType(LogicalTypeId::LIST, move(info)); + auto info = make_shared(std::move(child)); + return LogicalType(LogicalTypeId::LIST, std::move(info)); } //===--------------------------------------------------------------------===// @@ -63046,7 +66518,7 @@ LogicalType LogicalType::LIST(LogicalType child) { //===--------------------------------------------------------------------===// struct StructTypeInfo : public ExtraTypeInfo { explicit StructTypeInfo(child_list_t child_types_p) - : ExtraTypeInfo(ExtraTypeInfoType::STRUCT_TYPE_INFO), child_types(move(child_types_p)) { + : ExtraTypeInfo(ExtraTypeInfoType::STRUCT_TYPE_INFO), child_types(std::move(child_types_p)) { } child_list_t child_types; @@ -63068,9 +66540,9 @@ struct StructTypeInfo : public ExtraTypeInfo { for (uint32_t i = 0; i < child_types_size; i++) { auto name = source.Read(); auto type = LogicalType::Deserialize(source); - child_list.push_back(make_pair(move(name), move(type))); + child_list.push_back(make_pair(std::move(name), std::move(type))); } - return make_shared(move(child_list)); + return make_shared(std::move(child_list)); } protected: @@ -63082,7 +66554,7 @@ struct StructTypeInfo : public ExtraTypeInfo { struct AggregateStateTypeInfo : public ExtraTypeInfo { explicit AggregateStateTypeInfo(aggregate_state_t state_type_p) - : ExtraTypeInfo(ExtraTypeInfoType::AGGREGATE_STATE_TYPE_INFO), state_type(move(state_type_p)) { + : ExtraTypeInfo(ExtraTypeInfoType::AGGREGATE_STATE_TYPE_INFO), state_type(std::move(state_type_p)) { } aggregate_state_t state_type; @@ -63108,10 +66580,10 @@ struct AggregateStateTypeInfo : public ExtraTypeInfo { for (uint32_t i = 0; i < bound_argument_types_size; i++) { auto type = LogicalType::Deserialize(source); - bound_argument_types.push_back(move(type)); + bound_argument_types.push_back(std::move(type)); } return make_shared( - aggregate_state_t(move(function_name), move(return_type), move(bound_argument_types))); + aggregate_state_t(std::move(function_name), std::move(return_type), std::move(bound_argument_types))); } protected: @@ -63144,8 +66616,7 @@ const string AggregateStateType::GetTypeName(const LogicalType &type) { } const child_list_t &StructType::GetChildTypes(const LogicalType &type) { - D_ASSERT(type.id() == LogicalTypeId::STRUCT || type.id() == LogicalTypeId::MAP || - type.id() == LogicalTypeId::UNION); + D_ASSERT(type.id() == LogicalTypeId::STRUCT || type.id() == LogicalTypeId::UNION); auto info = type.AuxInfo(); D_ASSERT(info); @@ -63169,38 +66640,38 @@ idx_t StructType::GetChildCount(const LogicalType &type) { } LogicalType LogicalType::STRUCT(child_list_t children) { - auto info = make_shared(move(children)); - return LogicalType(LogicalTypeId::STRUCT, move(info)); + auto info = make_shared(std::move(children)); + return LogicalType(LogicalTypeId::STRUCT, std::move(info)); } LogicalType LogicalType::AGGREGATE_STATE(aggregate_state_t state_type) { // NOLINT - auto info = make_shared(move(state_type)); - return LogicalType(LogicalTypeId::AGGREGATE_STATE, move(info)); + auto info = make_shared(std::move(state_type)); + return LogicalType(LogicalTypeId::AGGREGATE_STATE, std::move(info)); } //===--------------------------------------------------------------------===// // Map Type //===--------------------------------------------------------------------===// -LogicalType LogicalType::MAP(child_list_t children) { - auto info = make_shared(move(children)); - return LogicalType(LogicalTypeId::MAP, move(info)); +LogicalType LogicalType::MAP(LogicalType child) { + auto info = make_shared(std::move(child)); + return LogicalType(LogicalTypeId::MAP, std::move(info)); } LogicalType LogicalType::MAP(LogicalType key, LogicalType value) { child_list_t child_types; - child_types.push_back({"key", LogicalType::LIST(move(key))}); - child_types.push_back({"value", LogicalType::LIST(move(value))}); - return LogicalType::MAP(move(child_types)); + child_types.push_back({"key", std::move(key)}); + child_types.push_back({"value", std::move(value)}); + return LogicalType::MAP(LogicalType::STRUCT(std::move(child_types))); } const LogicalType &MapType::KeyType(const LogicalType &type) { D_ASSERT(type.id() == LogicalTypeId::MAP); - return ListType::GetChildType(StructType::GetChildTypes(type)[0].second); + return StructType::GetChildTypes(ListType::GetChildType(type))[0].second; } const LogicalType &MapType::ValueType(const LogicalType &type) { D_ASSERT(type.id() == LogicalTypeId::MAP); - return ListType::GetChildType(StructType::GetChildTypes(type)[1].second); + return StructType::GetChildTypes(ListType::GetChildType(type))[1].second; } //===--------------------------------------------------------------------===// @@ -63212,8 +66683,8 @@ LogicalType LogicalType::UNION(child_list_t members) { D_ASSERT(members.size() <= UnionType::MAX_UNION_MEMBERS); // union types always have a hidden "tag" field in front members.insert(members.begin(), {"", LogicalType::TINYINT}); - auto info = make_shared(move(members)); - return LogicalType(LogicalTypeId::UNION, move(info)); + auto info = make_shared(std::move(members)); + return LogicalType(LogicalTypeId::UNION, std::move(info)); } const LogicalType &UnionType::GetMemberType(const LogicalType &type, idx_t index) { @@ -63245,7 +66716,7 @@ const child_list_t UnionType::CopyMemberTypes(const LogicalType &ty //===--------------------------------------------------------------------===// struct UserTypeInfo : public ExtraTypeInfo { explicit UserTypeInfo(string name_p) - : ExtraTypeInfo(ExtraTypeInfoType::USER_TYPE_INFO), user_type_name(move(name_p)) { + : ExtraTypeInfo(ExtraTypeInfoType::USER_TYPE_INFO), user_type_name(std::move(name_p)) { } string user_type_name; @@ -63257,7 +66728,7 @@ struct UserTypeInfo : public ExtraTypeInfo { static shared_ptr Deserialize(FieldReader &reader) { auto enum_name = reader.ReadRequired(); - return make_shared(move(enum_name)); + return make_shared(std::move(enum_name)); } protected: @@ -63276,23 +66747,19 @@ const string &UserType::GetTypeName(const LogicalType &type) { LogicalType LogicalType::USER(const string &user_type_name) { auto info = make_shared(user_type_name); - return LogicalType(LogicalTypeId::USER, move(info)); + return LogicalType(LogicalTypeId::USER, std::move(info)); } //===--------------------------------------------------------------------===// // Enum Type //===--------------------------------------------------------------------===// -enum EnumDictType : uint8_t { INVALID = 0, VECTOR_DICT = 1, DEDUP_POINTER = 2 }; +enum EnumDictType : uint8_t { INVALID = 0, VECTOR_DICT = 1 }; struct EnumTypeInfo : public ExtraTypeInfo { explicit EnumTypeInfo(string enum_name_p, Vector &values_insert_order_p, idx_t dict_size_p) : ExtraTypeInfo(ExtraTypeInfoType::ENUM_TYPE_INFO), dict_type(EnumDictType::VECTOR_DICT), - enum_name(move(enum_name_p)), values_insert_order(values_insert_order_p), dict_size(dict_size_p) { - } - explicit EnumTypeInfo() - : ExtraTypeInfo(ExtraTypeInfoType::ENUM_TYPE_INFO), dict_type(EnumDictType::DEDUP_POINTER), - enum_name("dedup_pointer"), values_insert_order(Vector(LogicalType::VARCHAR)), dict_size(0) { + enum_name(std::move(enum_name_p)), values_insert_order(values_insert_order_p), dict_size(dict_size_p) { } EnumDictType dict_type; string enum_name; @@ -63306,9 +66773,6 @@ struct EnumTypeInfo : public ExtraTypeInfo { if (dict_type != other.dict_type) { return false; } - if (dict_type == EnumDictType::DEDUP_POINTER) { - return true; - } D_ASSERT(dict_type == EnumDictType::VECTOR_DICT); // We must check if both enums have the same size if (other.dict_size != dict_size) { @@ -63363,7 +66827,7 @@ struct EnumTypeInfoTemplated : public EnumTypeInfo { auto enum_name = reader.ReadRequired(); Vector values_insert_order(LogicalType::VARCHAR, size); values_insert_order.Deserialize(size, reader.GetSource()); - return make_shared(move(enum_name), values_insert_order, size); + return make_shared(std::move(enum_name), values_insert_order, size); } string_map_t values; @@ -63409,12 +66873,6 @@ LogicalType LogicalType::ENUM(const string &enum_name, Vector &ordered_data, idx return LogicalType(LogicalTypeId::ENUM, info); } -LogicalType LogicalType::DEDUP_POINTER_ENUM() { // NOLINT - auto info = make_shared(); - D_ASSERT(info->dict_type == EnumDictType::DEDUP_POINTER); - return LogicalType(LogicalTypeId::ENUM, info); -} - template int64_t TemplatedGetPos(string_map_t &map, const string_t &key) { auto it = map.find(key); @@ -63440,10 +66898,6 @@ int64_t EnumType::GetPos(const LogicalType &type, const string_t &key) { const string EnumType::GetValue(const Value &val) { auto info = val.type().AuxInfo(); - auto &enum_info = ((EnumTypeInfo &)*info); - if (enum_info.dict_type == EnumDictType::DEDUP_POINTER) { - return (const char *)val.GetValue(); - } auto &values_insert_order = ((EnumTypeInfo &)*info).values_insert_order; return StringValue::Get(values_insert_order.GetValue(val.GetValue())); } @@ -63480,10 +66934,6 @@ PhysicalType EnumType::GetPhysicalType(const LogicalType &type) { auto aux_info = type.AuxInfo(); D_ASSERT(aux_info); auto &info = (EnumTypeInfo &)*aux_info; - - if (info.dict_type == EnumDictType::DEDUP_POINTER) { - return PhysicalType::UINT64; // for pointer enum types - } D_ASSERT(info.dict_type == EnumDictType::VECTOR_DICT); return EnumVectorDictType(info.dict_size); } @@ -63580,7 +67030,7 @@ LogicalType LogicalType::Deserialize(Deserializer &source) { auto info = ExtraTypeInfo::Deserialize(reader); reader.Finalize(); - return LogicalType(id, move(info)); + return LogicalType(id, std::move(info)); } bool LogicalType::EqualTypeInfo(const LogicalType &rhs) const { @@ -64285,7 +67735,6 @@ struct ComparisonExecutor { TemplatedExecute(left, right, result, count); break; case PhysicalType::LIST: - case PhysicalType::MAP: case PhysicalType::STRUCT: NestedComparisonExecutor(left, right, result, count); break; @@ -65193,7 +68642,6 @@ static void ExecuteDistinct(Vector &left, Vector &right, Vector &result, idx_t c TemplatedDistinctExecute(left, right, result, count); break; case PhysicalType::LIST: - case PhysicalType::MAP: case PhysicalType::STRUCT: NestedDistinctExecute(left, right, result, count); break; @@ -65234,7 +68682,6 @@ static idx_t TemplatedDistinctSelectOperation(Vector &left, Vector &right, const return DistinctSelect(left, right, sel, count, true_sel, false_sel); case PhysicalType::VARCHAR: return DistinctSelect(left, right, sel, count, true_sel, false_sel); - case PhysicalType::MAP: case PhysicalType::STRUCT: case PhysicalType::LIST: return DistinctSelectNested(left, right, sel, count, true_sel, false_sel); @@ -65507,12 +68954,17 @@ void VectorOperations::AddInPlace(Vector &input, int64_t right, idx_t count) { + namespace duckdb { bool VectorOperations::TryCast(CastFunctionSet &set, GetCastFunctionInput &input, Vector &source, Vector &result, idx_t count, string *error_message, bool strict) { auto cast_function = set.GetCastFunction(source.GetType(), result.GetType(), input); - CastParameters parameters(cast_function.cast_data.get(), strict, error_message); + unique_ptr local_state; + if (cast_function.init_local_state) { + local_state = cast_function.init_local_state(*input.context); + } + CastParameters parameters(cast_function.cast_data.get(), strict, error_message, local_state.get()); return cast_function.function(source, result, count, parameters); } @@ -66029,7 +69481,6 @@ static inline void HashTypeSwitch(Vector &input, Vector &result, const Selection case PhysicalType::VARCHAR: TemplatedLoopHash(input, result, rsel, count); break; - case PhysicalType::MAP: case PhysicalType::STRUCT: StructLoopHash(input, result, rsel, count); break; @@ -66161,7 +69612,6 @@ static inline void CombineHashTypeSwitch(Vector &hashes, Vector &input, const Se case PhysicalType::VARCHAR: TemplatedLoopCombineHash(input, hashes, rsel, count); break; - case PhysicalType::MAP: case PhysicalType::STRUCT: StructLoopHash(input, hashes, rsel, count); break; @@ -66377,8 +69827,9 @@ class VirtualFileSystem : public FileSystem { FindFileSystem(directory)->RemoveDirectory(directory); } - bool ListFiles(const string &directory, const std::function &callback) override { - return FindFileSystem(directory)->ListFiles(directory, callback); + bool ListFiles(const string &directory, const std::function &callback, + FileOpener *opener = nullptr) override { + return FindFileSystem(directory)->ListFiles(directory, callback, opener); } void MoveFile(const string &source, const string &target) override { @@ -66401,11 +69852,29 @@ class VirtualFileSystem : public FileSystem { } void RegisterSubSystem(unique_ptr fs) override { - sub_systems.push_back(move(fs)); + sub_systems.push_back(std::move(fs)); + } + + void UnregisterSubSystem(const string &name) override { + for (auto sub_system = sub_systems.begin(); sub_system != sub_systems.end(); sub_system++) { + if (sub_system->get()->GetName() == name) { + sub_systems.erase(sub_system); + return; + } + } + throw InvalidInputException("Could not find filesystem with name %s", name); } void RegisterSubSystem(FileCompressionType compression_type, unique_ptr fs) override { - compressed_fs[compression_type] = move(fs); + compressed_fs[compression_type] = std::move(fs); + } + + vector ListSubSystems() override { + vector names(sub_systems.size()); + for (idx_t i = 0; i < sub_systems.size(); i++) { + names[i] = sub_systems[i]->GetName(); + } + return names; } std::string GetName() const override { @@ -66438,7 +69907,7 @@ class VirtualFileSystem : public FileSystem { namespace duckdb { VirtualFileSystem::VirtualFileSystem() : default_fs(FileSystem::CreateLocal()) { - RegisterSubSystem(FileCompressionType::GZIP, make_unique()); + VirtualFileSystem::RegisterSubSystem(FileCompressionType::GZIP, make_unique()); } unique_ptr VirtualFileSystem::OpenFile(const string &path, uint8_t flags, FileLockType lock, @@ -66457,14 +69926,14 @@ unique_ptr VirtualFileSystem::OpenFile(const string &path, uint8_t f // open the base file handle auto file_handle = FindFileSystem(path)->OpenFile(path, flags, lock, FileCompressionType::UNCOMPRESSED, opener); if (file_handle->GetType() == FileType::FILE_TYPE_FIFO) { - file_handle = PipeFileSystem::OpenPipe(move(file_handle)); + file_handle = PipeFileSystem::OpenPipe(std::move(file_handle)); } else if (compression != FileCompressionType::UNCOMPRESSED) { auto entry = compressed_fs.find(compression); if (entry == compressed_fs.end()) { throw NotImplementedException( "Attempting to open a compressed file, but the compression type is not supported"); } - file_handle = entry->second->OpenCompressedFile(move(file_handle), flags & FileFlags::FILE_FLAGS_WRITE); + file_handle = entry->second->OpenCompressedFile(std::move(file_handle), flags & FileFlags::FILE_FLAGS_WRITE); } return file_handle; } @@ -66637,13 +70106,13 @@ GroupedAggregateHashTable::GroupedAggregateHashTable(ClientContext &context, All vector group_types, vector payload_types, const vector &bindings, HtEntryType entry_type) - : GroupedAggregateHashTable(context, allocator, move(group_types), move(payload_types), + : GroupedAggregateHashTable(context, allocator, std::move(group_types), std::move(payload_types), AggregateObject::CreateAggregateObjects(bindings), entry_type) { } GroupedAggregateHashTable::GroupedAggregateHashTable(ClientContext &context, Allocator &allocator, vector group_types) - : GroupedAggregateHashTable(context, allocator, move(group_types), {}, vector()) { + : GroupedAggregateHashTable(context, allocator, std::move(group_types), {}, vector()) { } GroupedAggregateHashTable::GroupedAggregateHashTable(ClientContext &context, Allocator &allocator, @@ -66651,14 +70120,15 @@ GroupedAggregateHashTable::GroupedAggregateHashTable(ClientContext &context, All vector payload_types_p, vector aggregate_objects_p, HtEntryType entry_type) - : BaseAggregateHashTable(context, allocator, aggregate_objects_p, move(payload_types_p)), entry_type(entry_type), - capacity(0), entries(0), payload_page_offset(0), is_finalized(false), ht_offsets(LogicalTypeId::BIGINT), - hash_salts(LogicalTypeId::SMALLINT), group_compare_vector(STANDARD_VECTOR_SIZE), - no_match_vector(STANDARD_VECTOR_SIZE), empty_vector(STANDARD_VECTOR_SIZE) { + : BaseAggregateHashTable(context, allocator, aggregate_objects_p, std::move(payload_types_p)), + entry_type(entry_type), capacity(0), entries(0), payload_page_offset(0), is_finalized(false), + ht_offsets(LogicalTypeId::BIGINT), hash_salts(LogicalTypeId::SMALLINT), + group_compare_vector(STANDARD_VECTOR_SIZE), no_match_vector(STANDARD_VECTOR_SIZE), + empty_vector(STANDARD_VECTOR_SIZE) { // Append hash column to the end and initialise the row layout group_types_p.emplace_back(LogicalType::HASH); - layout.Initialize(move(group_types_p), move(aggregate_objects_p)); + layout.Initialize(std::move(group_types_p), std::move(aggregate_objects_p)); // HT layout hash_offset = layout.GetOffsets()[layout.ColumnCount() - 1]; @@ -66717,7 +70187,7 @@ void GroupedAggregateHashTable::PayloadApply(FUNC fun) { void GroupedAggregateHashTable::NewBlock() { auto pin = buffer_manager.Allocate(Storage::BLOCK_SIZE); - payload_hds.push_back(move(pin)); + payload_hds.push_back(std::move(pin)); payload_hds_ptrs.push_back(payload_hds.back().Ptr()); payload_page_offset = 0; } @@ -66765,6 +70235,7 @@ void GroupedAggregateHashTable::VerifyInternal() { count++; } } + (void)count; D_ASSERT(count == entries); } @@ -67283,7 +70754,7 @@ BaseAggregateHashTable::BaseAggregateHashTable(ClientContext &context, Allocator const vector &aggregates, vector payload_types_p) : allocator(allocator), buffer_manager(BufferManager::GetBufferManager(context)), - payload_types(move(payload_types_p)) { + payload_types(std::move(payload_types_p)) { filter_set.Initialize(context, aggregates, payload_types); } @@ -67388,12 +70859,12 @@ class JoinSide { } static JoinSide CombineJoinSide(JoinSide left, JoinSide right); - static JoinSide GetJoinSide(idx_t table_binding, unordered_set &left_bindings, - unordered_set &right_bindings); - static JoinSide GetJoinSide(Expression &expression, unordered_set &left_bindings, - unordered_set &right_bindings); - static JoinSide GetJoinSide(const unordered_set &bindings, unordered_set &left_bindings, - unordered_set &right_bindings); + static JoinSide GetJoinSide(idx_t table_binding, const unordered_set &left_bindings, + const unordered_set &right_bindings); + static JoinSide GetJoinSide(Expression &expression, const unordered_set &left_bindings, + const unordered_set &right_bindings); + static JoinSide GetJoinSide(const unordered_set &bindings, const unordered_set &left_bindings, + const unordered_set &right_bindings); private: JoinValue value; @@ -67473,9 +70944,26 @@ class LogicalComparisonJoin : public LogicalJoin { public: static unique_ptr CreateJoin(JoinType type, unique_ptr left_child, unique_ptr right_child, - unordered_set &left_bindings, - unordered_set &right_bindings, - vector> &expressions); + unique_ptr condition); + static unique_ptr CreateJoin(JoinType type, unique_ptr left_child, + unique_ptr right_child, + vector conditions, + vector> arbitrary_expressions); + + static void ExtractJoinConditions(JoinType type, unique_ptr &left_child, + unique_ptr &right_child, unique_ptr condition, + vector &conditions, + vector> &arbitrary_expressions); + static void ExtractJoinConditions(JoinType type, unique_ptr &left_child, + unique_ptr &right_child, + vector> &expressions, vector &conditions, + vector> &arbitrary_expressions); + static void ExtractJoinConditions(JoinType type, unique_ptr &left_child, + unique_ptr &right_child, + const unordered_set &left_bindings, + const unordered_set &right_bindings, + vector> &expressions, vector &conditions, + vector> &arbitrary_expressions); }; } // namespace duckdb @@ -67501,13 +70989,13 @@ class LogicalCreateIndex : public LogicalOperator { LogicalCreateIndex(unique_ptr bind_data_p, unique_ptr info_p, vector> expressions_p, TableCatalogEntry &table_p, TableFunction function_p) - : LogicalOperator(LogicalOperatorType::LOGICAL_CREATE_INDEX), bind_data(move(bind_data_p)), info(move(info_p)), - table(table_p), function(move(function_p)) { + : LogicalOperator(LogicalOperatorType::LOGICAL_CREATE_INDEX), bind_data(std::move(bind_data_p)), + info(std::move(info_p)), table(table_p), function(std::move(function_p)) { for (auto &expr : expressions_p) { this->unbound_expressions.push_back(expr->Copy()); } - this->expressions = move(expressions_p); + this->expressions = std::move(expressions_p); if (info->column_ids.empty()) { throw BinderException("CREATE INDEX does not refer to any columns in the base table!"); @@ -67568,6 +71056,292 @@ class LogicalDelimJoin : public LogicalComparisonJoin { } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/operator/logical_insert.hpp +// +// +//===----------------------------------------------------------------------===// + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/index_vector.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +template +class IndexVector { +public: + void push_back(T element) { + internal_vector.push_back(std::move(element)); + } + + T &operator[](INDEX_TYPE idx) { + return internal_vector[idx.index]; + } + + const T &operator[](INDEX_TYPE idx) const { + return internal_vector[idx.index]; + } + + idx_t size() const { + return internal_vector.size(); + } + + bool empty() const { + return internal_vector.empty(); + } + + void reserve(idx_t size) { + internal_vector.reserve(size); + } + + typename vector::iterator begin() { + return internal_vector.begin(); + } + typename vector::iterator end() { + return internal_vector.end(); + } + typename vector::const_iterator cbegin() { + return internal_vector.cbegin(); + } + typename vector::const_iterator cend() { + return internal_vector.cend(); + } + typename vector::const_iterator begin() const { + return internal_vector.begin(); + } + typename vector::const_iterator end() const { + return internal_vector.end(); + } + +private: + vector internal_vector; +}; + +template +using physical_index_vector_t = IndexVector; + +template +using logical_index_vector_t = IndexVector; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/statement/insert_statement.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/statement/update_statement.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + + + +namespace duckdb { + +class UpdateSetInfo { +public: + UpdateSetInfo(); + +public: + unique_ptr Copy() const; + +public: + // The condition that needs to be met to perform the update + unique_ptr condition; + // The columns to update + vector columns; + // The set expressions to execute + vector> expressions; + +protected: + UpdateSetInfo(const UpdateSetInfo &other); +}; + +class UpdateStatement : public SQLStatement { +public: + UpdateStatement(); + + unique_ptr table; + unique_ptr from_table; + //! keep track of optional returningList if statement contains a RETURNING keyword + vector> returning_list; + unique_ptr set_info; + //! CTEs + CommonTableExpressionMap cte_map; + +protected: + UpdateStatement(const UpdateStatement &other); + +public: + string ToString() const override; + unique_ptr Copy() const override; +}; + +} // namespace duckdb + + +namespace duckdb { +class ExpressionListRef; +class UpdateSetInfo; + +enum class OnConflictAction : uint8_t { + THROW, + NOTHING, + UPDATE, + REPLACE // Only used in transform/bind step, changed to UPDATE later +}; + +class OnConflictInfo { +public: + OnConflictInfo(); + +public: + unique_ptr Copy() const; + +public: + OnConflictAction action_type; + + vector indexed_columns; + //! The SET information (if action_type == UPDATE) + unique_ptr set_info; + //! The condition determining whether we apply the DO .. for conflicts that arise + unique_ptr condition; + +protected: + OnConflictInfo(const OnConflictInfo &other); +}; + +class InsertStatement : public SQLStatement { +public: + InsertStatement(); + + //! The select statement to insert from + unique_ptr select_statement; + //! Column names to insert into + vector columns; + + //! Table name to insert to + string table; + //! Schema name to insert to + string schema; + //! The catalog name to insert to + string catalog; + + //! keep track of optional returningList if statement contains a RETURNING keyword + vector> returning_list; + + unique_ptr on_conflict_info; + unique_ptr table_ref; + + //! CTEs + CommonTableExpressionMap cte_map; + +protected: + InsertStatement(const InsertStatement &other); + +public: + static string OnConflictActionToString(OnConflictAction action); + string ToString() const override; + unique_ptr Copy() const override; + + //! If the INSERT statement is inserted DIRECTLY from a values list (i.e. INSERT INTO tbl VALUES (...)) this returns + //! the expression list Otherwise, this returns NULL + ExpressionListRef *GetValuesList() const; +}; + +} // namespace duckdb + + +namespace duckdb { +class TableCatalogEntry; + +class Index; + +//! LogicalInsert represents an insertion of data into a base table +class LogicalInsert : public LogicalOperator { +public: + LogicalInsert(TableCatalogEntry *table, idx_t table_index); + + vector>> insert_values; + //! The insertion map ([table_index -> index in result, or DConstants::INVALID_INDEX if not specified]) + physical_index_vector_t column_index_map; + //! The expected types for the INSERT statement (obtained from the column types) + vector expected_types; + //! The base table to insert into + TableCatalogEntry *table; + idx_t table_index; + //! if returning option is used, return actual chunk to projection + bool return_chunk; + //! The default statements used by the table + vector> bound_defaults; + + //! Which action to take on conflict + OnConflictAction action_type; + // The types that the DO UPDATE .. SET (expressions) are cast to + vector expected_set_types; + // The (distinct) column ids to apply the ON CONFLICT on + unordered_set on_conflict_filter; + // The WHERE clause of the conflict_target (ON CONFLICT .. WHERE ) + unique_ptr on_conflict_condition; + // The WHERE clause of the DO UPDATE clause + unique_ptr do_update_condition; + // The columns targeted by the DO UPDATE SET expressions + vector set_columns; + // The types of the columns targeted by the DO UPDATE SET expressions + vector set_types; + // The table_index referring to the column references qualified with 'excluded' + idx_t excluded_table_index; + // The columns to fetch from the 'destination' table + vector columns_to_fetch; + // The columns to fetch from the 'source' table + vector source_columns; + +public: + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(LogicalDeserializationState &state, FieldReader &reader); + +protected: + vector GetColumnBindings() override; + void ResolveTypes() override; + + idx_t EstimateCardinality(ClientContext &context) override; + vector GetTableIndex() const override; +}; +} // namespace duckdb + @@ -67616,7 +71390,7 @@ void ColumnBindingResolver::VisitOperator(LogicalOperator &op) { // CREATE INDEX statement, add the columns of the table with table index 0 to the binding set // afterwards bind the expressions of the CREATE INDEX statement auto &create_index = (LogicalCreateIndex &)op; - bindings = LogicalOperator::GenerateColumnBindings(0, create_index.table.columns.LogicalColumnCount()); + bindings = LogicalOperator::GenerateColumnBindings(0, create_index.table.GetColumns().LogicalColumnCount()); VisitOperatorExpressions(op); return; } else if (op.type == LogicalOperatorType::LOGICAL_GET) { @@ -67624,6 +71398,25 @@ void ColumnBindingResolver::VisitOperator(LogicalOperator &op) { bindings = op.GetColumnBindings(); VisitOperatorExpressions(op); return; + } else if (op.type == LogicalOperatorType::LOGICAL_INSERT) { + //! We want to execute the normal path, but also add a dummy 'excluded' binding if there is a + // ON CONFLICT DO UPDATE clause + auto &insert_op = (LogicalInsert &)op; + if (insert_op.action_type != OnConflictAction::THROW) { + VisitOperatorChildren(op); + auto dummy_bindings = LogicalOperator::GenerateColumnBindings( + insert_op.excluded_table_index, insert_op.table->GetColumns().PhysicalColumnCount()); + bindings.insert(bindings.begin(), dummy_bindings.begin(), dummy_bindings.end()); + if (insert_op.on_conflict_condition) { + VisitExpression(&insert_op.on_conflict_condition); + } + if (insert_op.do_update_condition) { + VisitExpression(&insert_op.do_update_condition); + } + VisitOperatorExpressions(op); + bindings = op.GetColumnBindings(); + return; + } } // general case // first visit the children of this operator @@ -67863,7 +71656,7 @@ unique_ptr ExpressionExecutor::InitializeState(const BoundCaseE } result->AddChild(expr.else_expr.get()); result->Finalize(); - return move(result); + return std::move(result); } void ExpressionExecutor::Execute(const BoundCaseExpression &expr, ExpressionState *state_p, const SelectionVector *sel, @@ -68064,18 +71857,24 @@ void ExpressionExecutor::FillSwitch(Vector &vector, Vector &result, const Select + namespace duckdb { unique_ptr ExpressionExecutor::InitializeState(const BoundCastExpression &expr, ExpressionExecutorState &root) { - auto result = make_unique(expr, root); + auto result = make_unique(expr, root); result->AddChild(expr.child.get()); result->Finalize(); - return result; + if (expr.bound_cast.init_local_state) { + result->local_state = expr.bound_cast.init_local_state(root.executor->GetContext()); + } + return std::move(result); } void ExpressionExecutor::Execute(const BoundCastExpression &expr, ExpressionState *state, const SelectionVector *sel, idx_t count, Vector &result) { + auto lstate = ExecuteFunctionState::GetFunctionState(*state); + // resolve the child state->intermediate_chunk.Reset(); @@ -68085,12 +71884,12 @@ void ExpressionExecutor::Execute(const BoundCastExpression &expr, ExpressionStat Execute(*expr.child, child_state, sel, count, child); if (expr.try_cast) { string error_message; - CastParameters parameters(expr.bound_cast.cast_data.get(), false, &error_message); + CastParameters parameters(expr.bound_cast.cast_data.get(), false, &error_message, lstate); expr.bound_cast.function(child, result, count, parameters); } else { // cast it to the type specified by the cast expression D_ASSERT(result.GetType() == expr.return_type); - CastParameters parameters(expr.bound_cast.cast_data.get(), false, nullptr); + CastParameters parameters(expr.bound_cast.cast_data.get(), false, nullptr, lstate); expr.bound_cast.function(child, result, count, parameters); } } @@ -68192,7 +71991,6 @@ static idx_t TemplatedSelectOperation(Vector &left, Vector &right, const Selecti case PhysicalType::VARCHAR: return BinaryExecutor::Select(left, right, sel, count, true_sel, false_sel); case PhysicalType::LIST: - case PhysicalType::MAP: case PhysicalType::STRUCT: return NestedSelectOperation(left, right, sel, count, true_sel, false_sel); default: @@ -68431,7 +72229,7 @@ unique_ptr ExpressionExecutor::InitializeState(const BoundConju result->AddChild(child.get()); } result->Finalize(); - return move(result); + return std::move(result); } void ExpressionExecutor::Execute(const BoundConjunctionExpression &expr, ExpressionState *state, @@ -68593,7 +72391,7 @@ unique_ptr ExpressionExecutor::InitializeState(const BoundFunct if (expr.function.init_local_state) { result->local_state = expr.function.init_local_state(*result, expr, expr.bind_info.get()); } - return move(result); + return std::move(result); } static void VerifyNullHandling(const BoundFunctionExpression &expr, DataChunk &args, Vector &result) { @@ -68679,7 +72477,7 @@ void ExpressionExecutor::Execute(const BoundOperatorExpression &expr, Expression // IN has n children if (expr.type == ExpressionType::COMPARE_IN || expr.type == ExpressionType::COMPARE_NOT_IN) { if (expr.children.size() < 2) { - throw Exception("IN needs at least two children"); + throw InvalidInputException("IN needs at least two children"); } Vector left(expr.children[0]->return_type); @@ -68902,7 +72700,7 @@ void ExpressionExecutor::AddExpression(const Expression &expr) { auto state = make_unique(expr.ToString()); Initialize(expr, *state); state->Verify(); - states.push_back(move(state)); + states.push_back(std::move(state)); } void ExpressionExecutor::Initialize(const Expression &expression, ExpressionExecutorState &state) { @@ -69208,6 +73006,7 @@ void ExpressionExecutorState::Verify() { + #include #include #include @@ -69216,79 +73015,78 @@ namespace duckdb { ART::ART(const vector &column_ids, TableIOManager &table_io_manager, const vector> &unbound_expressions, IndexConstraintType constraint_type, - DatabaseInstance &db, idx_t block_id, idx_t block_offset) - : Index(IndexType::ART, table_io_manager, column_ids, unbound_expressions, constraint_type), db(db), - estimated_art_size(0), estimated_key_size(16) { + AttachedDatabase &db, bool track_memory, idx_t block_id, idx_t block_offset) + + : Index(db, IndexType::ART, table_io_manager, column_ids, unbound_expressions, constraint_type, track_memory) { + if (!Radix::IsLittleEndian()) { throw NotImplementedException("ART indexes are not supported on big endian architectures"); } + + // set the root node of the tree + tree = nullptr; if (block_id != DConstants::INVALID_INDEX) { tree = Node::Deserialize(*this, block_id, block_offset); - } else { - tree = nullptr; + ART::Verify(); } serialized_data_pointer = BlockPointer(block_id, block_offset); + + // validate the types of the key columns for (idx_t i = 0; i < types.size(); i++) { switch (types[i]) { case PhysicalType::BOOL: case PhysicalType::INT8: - case PhysicalType::UINT8: - estimated_key_size += sizeof(int8_t); - break; case PhysicalType::INT16: - case PhysicalType::UINT16: - estimated_key_size += sizeof(int16_t); - break; case PhysicalType::INT32: - case PhysicalType::UINT32: - case PhysicalType::FLOAT: - estimated_key_size += sizeof(int32_t); - break; case PhysicalType::INT64: + case PhysicalType::INT128: + case PhysicalType::UINT8: + case PhysicalType::UINT16: + case PhysicalType::UINT32: case PhysicalType::UINT64: + case PhysicalType::FLOAT: case PhysicalType::DOUBLE: - estimated_key_size += sizeof(int64_t); - break; - case PhysicalType::INT128: - estimated_key_size += sizeof(hugeint_t); - break; case PhysicalType::VARCHAR: - estimated_key_size += 16; // oh well break; default: - throw InvalidTypeException(logical_types[i], "Invalid type for index"); + throw InvalidTypeException(logical_types[i], "Invalid type for index key."); } } } ART::~ART() { - if (estimated_art_size > 0) { - BufferManager::GetBufferManager(db).FreeReservedMemory(estimated_art_size); - estimated_art_size = 0; + if (!tree) { + return; } - if (tree) { - Node::Delete(tree); - tree = nullptr; + ART::Verify(); + if (track_memory) { + buffer_manager.DecreaseUsedMemory(memory_size); } + Node::Delete(tree); + tree = nullptr; } -unique_ptr ART::InitializeScanSinglePredicate(Transaction &transaction, Value value, +//===--------------------------------------------------------------------===// +// Initialize Predicate Scans +//===--------------------------------------------------------------------===// + +unique_ptr ART::InitializeScanSinglePredicate(const Transaction &transaction, const Value &value, ExpressionType expression_type) { auto result = make_unique(); result->values[0] = value; result->expressions[0] = expression_type; - return move(result); + return std::move(result); } -unique_ptr ART::InitializeScanTwoPredicates(Transaction &transaction, Value low_value, - ExpressionType low_expression_type, Value high_value, +unique_ptr ART::InitializeScanTwoPredicates(Transaction &transaction, const Value &low_value, + ExpressionType low_expression_type, const Value &high_value, ExpressionType high_expression_type) { auto result = make_unique(); result->values[0] = low_value; result->expressions[0] = low_expression_type; result->values[1] = high_value; result->expressions[1] = high_expression_type; - return move(result); + return std::move(result); } //===--------------------------------------------------------------------===// @@ -69427,7 +73225,7 @@ void ART::GenerateKeys(ArenaAllocator &allocator, DataChunk &input, vector } //===--------------------------------------------------------------------===// -// Insert +// Construct from sorted data //===--------------------------------------------------------------------===// struct KeySection { @@ -69453,7 +73251,8 @@ void GetChildSections(vector &child_sections, vector &keys, Key child_sections.emplace_back(child_start_idx, key_section.end, keys, key_section); } -void Construct(vector &keys, row_t *row_ids, Node *&node, KeySection &key_section, bool &has_constraint) { +bool Construct(ART &art, vector &keys, row_t *row_ids, Node *&node, KeySection &key_section, + bool &has_constraint) { D_ASSERT(key_section.start < keys.size()); D_ASSERT(key_section.end < keys.size()); @@ -69474,90 +73273,61 @@ void Construct(vector &keys, row_t *row_ids, Node *&node, KeySection &key_s auto num_row_ids = key_section.end - key_section.start + 1; // check for possible constraint violation - if (has_constraint && num_row_ids != 1) { - throw ConstraintException("New data contains duplicates on indexed column(s)"); + auto single_row_id = num_row_ids == 1; + if (has_constraint && !single_row_id) { + return false; } - node = Leaf::New(start_key, prefix_start, row_ids + key_section.start, num_row_ids); - } else { // create a new node and recurse - - // we will find at least two child entries of this node, otherwise we'd have reached a leaf - vector child_sections; - GetChildSections(child_sections, keys, key_section); - - auto node_type = Node::GetTypeBySize(child_sections.size()); - Node::New(node_type, node); - - auto prefix_length = key_section.depth - prefix_start; - node->prefix = Prefix(start_key, prefix_start, prefix_length); - - // recurse on each child section - for (auto &child_section : child_sections) { - Node *new_child = nullptr; - Construct(keys, row_ids, new_child, child_section, has_constraint); - Node::InsertChild(node, child_section.key_byte, new_child); + if (single_row_id) { + node = Leaf::New(start_key, prefix_start, row_ids[key_section.start]); + } else { + node = Leaf::New(start_key, prefix_start, row_ids + key_section.start, num_row_ids); } + art.memory_size += node->MemorySize(art, false); + return true; } -} + // create a new node and recurse -void ART::ConstructAndMerge(IndexLock &lock, PayloadScanner &scanner, Allocator &allocator) { + // we will find at least two child entries of this node, otherwise we'd have reached a leaf + vector child_sections; + GetChildSections(child_sections, keys, key_section); - auto payload_types = logical_types; - payload_types.emplace_back(LogicalType::ROW_TYPE); - - ArenaAllocator arena_allocator(BufferAllocator::Get(db)); - vector keys(STANDARD_VECTOR_SIZE); + auto node_type = Node::GetTypeBySize(child_sections.size()); + Node::New(node_type, node); - auto temp_art = make_unique(this->column_ids, this->table_io_manager, this->unbound_expressions, - this->constraint_type, this->db); + auto prefix_length = key_section.depth - prefix_start; + node->prefix = Prefix(start_key, prefix_start, prefix_length); + art.memory_size += node->MemorySize(art, false); - for (;;) { - DataChunk ordered_chunk; - ordered_chunk.Initialize(allocator, payload_types); - ordered_chunk.SetCardinality(0); - scanner.Scan(ordered_chunk); - if (ordered_chunk.size() == 0) { - break; + // recurse on each child section + for (auto &child_section : child_sections) { + Node *new_child = nullptr; + auto no_violation = Construct(art, keys, row_ids, new_child, child_section, has_constraint); + Node::InsertChild(art, node, child_section.key_byte, new_child); + if (!no_violation) { + return false; } + } + return true; +} - // get the key chunk and the row_identifiers vector - DataChunk row_id_chunk; - ordered_chunk.Split(row_id_chunk, ordered_chunk.ColumnCount() - 1); - auto &row_identifiers = row_id_chunk.data[0]; - - D_ASSERT(row_identifiers.GetType().InternalType() == ROW_TYPE); - D_ASSERT(logical_types[0] == ordered_chunk.data[0].GetType()); - - // generate the keys for the given input - arena_allocator.Reset(); - GenerateKeys(arena_allocator, ordered_chunk, keys); - - // prepare the row_identifiers - row_identifiers.Flatten(ordered_chunk.size()); - auto row_ids = FlatVector::GetData(row_identifiers); - - // construct the ART of this chunk - auto art = make_unique(this->column_ids, this->table_io_manager, this->unbound_expressions, - this->constraint_type, this->db); - auto key_section = KeySection(0, ordered_chunk.size() - 1, 0, 0); - auto has_constraint = IsUnique(); - Construct(keys, row_ids, art->tree, key_section, has_constraint); +bool ART::ConstructFromSorted(idx_t count, vector &keys, Vector &row_identifiers) { - // merge art into temp_art - if (!temp_art->MergeIndexes(lock, art.get())) { - throw ConstraintException("Data contains duplicates on indexed column(s)"); - } - } + // prepare the row_identifiers + row_identifiers.Flatten(count); + auto row_ids = FlatVector::GetData(row_identifiers); - // NOTE: currently this code is only used for index creation, so we can assume that there are no - // duplicate violations between the existing index and the new data, - // so we do not need to revert any changes - if (!this->MergeIndexes(lock, temp_art.get())) { - throw ConstraintException("Data contains duplicates on indexed column(s)"); - } + auto key_section = KeySection(0, count - 1, 0, 0); + auto has_constraint = IsUnique(); + return Construct(*this, keys, row_ids, this->tree, key_section, has_constraint); } +//===--------------------------------------------------------------------===// +// Insert +//===--------------------------------------------------------------------===// + bool ART::Insert(IndexLock &lock, DataChunk &input, Vector &row_ids) { + D_ASSERT(row_ids.GetType().InternalType() == ROW_TYPE); D_ASSERT(logical_types[0] == input.data[0].GetType()); @@ -69566,13 +73336,13 @@ bool ART::Insert(IndexLock &lock, DataChunk &input, Vector &row_ids) { vector keys(input.size()); GenerateKeys(arena_allocator, input, keys); - idx_t extra_memory = estimated_key_size * input.size(); - BufferManager::GetBufferManager(db).ReserveMemory(extra_memory); - estimated_art_size += extra_memory; + auto old_memory_size = this->memory_size; - // now insert the elements into the index + // get the corresponding row IDs row_ids.Flatten(input.size()); auto row_identifiers = FlatVector::GetData(row_ids); + + // now insert the elements into the index idx_t failed_index = DConstants::INVALID_INDEX; for (idx_t i = 0; i < input.size(); i++) { if (keys[i].Empty()) { @@ -69596,8 +73366,15 @@ bool ART::Insert(IndexLock &lock, DataChunk &input, Vector &row_ids) { row_t row_id = row_identifiers[i]; Erase(tree, keys[i], 0, row_id); } + // nothing changed, no need to update the buffer memory size return false; } + + D_ASSERT(old_memory_size <= memory_size); + Verify(); + if (track_memory) { + buffer_manager.IncreaseUsedMemory(memory_size - old_memory_size); + } return true; } @@ -69613,15 +73390,26 @@ bool ART::Append(IndexLock &lock, DataChunk &appended_data, Vector &row_identifi } void ART::VerifyAppend(DataChunk &chunk) { - VerifyExistence(chunk, VerifyExistenceType::APPEND); + ConflictManager conflict_manager(VerifyExistenceType::APPEND, chunk.size()); + LookupValues(chunk, conflict_manager); } -void ART::VerifyAppendForeignKey(DataChunk &chunk, string *err_msg_ptr) { - VerifyExistence(chunk, VerifyExistenceType::APPEND_FK, err_msg_ptr); +void ART::VerifyAppend(DataChunk &chunk, ConflictManager &conflict_manager) { + D_ASSERT(conflict_manager.LookupType() == VerifyExistenceType::APPEND); + LookupValues(chunk, conflict_manager); } -void ART::VerifyDeleteForeignKey(DataChunk &chunk, string *err_msg_ptr) { - VerifyExistence(chunk, VerifyExistenceType::DELETE_FK, err_msg_ptr); +void ART::VerifyAppendForeignKey(DataChunk &chunk) { + ConflictManager conflict_manager(VerifyExistenceType::APPEND_FK, chunk.size()); + LookupValues(chunk, conflict_manager); +} + +void ART::VerifyDeleteForeignKey(DataChunk &chunk) { + if (!IsUnique()) { + return; + } + ConflictManager conflict_manager(VerifyExistenceType::DELETE_FK, chunk.size()); + LookupValues(chunk, conflict_manager); } bool ART::InsertToLeaf(Leaf &leaf, row_t row_id) { @@ -69633,7 +73421,7 @@ bool ART::InsertToLeaf(Leaf &leaf, row_t row_id) { if (IsUnique() && leaf.count != 0) { return false; } - leaf.Insert(row_id); + leaf.Insert(*this, row_id); return true; } @@ -69642,23 +73430,24 @@ bool ART::Insert(Node *&node, Key &key, idx_t depth, row_t row_id) { if (!node) { // node is currently empty, create a leaf here with the key node = Leaf::New(key, depth, row_id); + this->memory_size += node->MemorySize(*this, false); return true; } if (node->type == NodeType::NLeaf) { - // Replace leaf with Node4 and store both leaves in it + // replace leaf with Node4 and store both leaves in it + // or add a row ID to a leaf, if they have the same key auto leaf = (Leaf *)node; - - auto &leaf_prefix = leaf->prefix; uint32_t new_prefix_length = 0; - // Leaf node is already there (its key matches the current key), update row_id vector + // FIXME: this code (if and while) can be optimized, less branching, see Construct + // leaf node is already there (its key matches the current key), update row_id vector if (new_prefix_length == leaf->prefix.Size() && depth + leaf->prefix.Size() == key.len) { return InsertToLeaf(*leaf, row_id); } - while (leaf_prefix[new_prefix_length] == key[depth + new_prefix_length]) { + while (leaf->prefix[new_prefix_length] == key[depth + new_prefix_length]) { new_prefix_length++; - // Leaf node is already there (its key matches the current key), update row_id vector + // leaf node is already there (its key matches the current key), update row_id vector if (new_prefix_length == leaf->prefix.Size() && depth + leaf->prefix.Size() == key.len) { return InsertToLeaf(*leaf, row_id); } @@ -69666,34 +73455,44 @@ bool ART::Insert(Node *&node, Key &key, idx_t depth, row_t row_id) { Node *new_node = Node4::New(); new_node->prefix = Prefix(key, depth, new_prefix_length); - auto key_byte = node->prefix.Reduce(new_prefix_length); - Node4::InsertChild(new_node, key_byte, node); + this->memory_size += new_node->MemorySize(*this, false); + + auto key_byte = node->prefix.Reduce(*this, new_prefix_length); + Node4::InsertChild(*this, new_node, key_byte, node); + Node *leaf_node = Leaf::New(key, depth + new_prefix_length + 1, row_id); - Node4::InsertChild(new_node, key[depth + new_prefix_length], leaf_node); + Node4::InsertChild(*this, new_node, key[depth + new_prefix_length], leaf_node); + this->memory_size += leaf_node->MemorySize(*this, false); + node = new_node; return true; } - // Handle prefix of inner node + // handle prefix of inner node if (node->prefix.Size()) { + uint32_t mismatch_pos = node->prefix.KeyMismatchPosition(key, depth); if (mismatch_pos != node->prefix.Size()) { - // Prefix differs, create new node + // prefix differs, create new node Node *new_node = Node4::New(); new_node->prefix = Prefix(key, depth, mismatch_pos); - // Break up prefix - auto key_byte = node->prefix.Reduce(mismatch_pos); - Node4::InsertChild(new_node, key_byte, node); + this->memory_size += new_node->MemorySize(*this, false); + + // break up prefix + auto key_byte = node->prefix.Reduce(*this, mismatch_pos); + Node4::InsertChild(*this, new_node, key_byte, node); Node *leaf_node = Leaf::New(key, depth + mismatch_pos + 1, row_id); - Node4::InsertChild(new_node, key[depth + mismatch_pos], leaf_node); + Node4::InsertChild(*this, new_node, key[depth + mismatch_pos], leaf_node); + this->memory_size += leaf_node->MemorySize(*this, false); + node = new_node; return true; } depth += node->prefix.Size(); } - // Recurse + // recurse D_ASSERT(depth < key.len); idx_t pos = node->GetChildPos(key[depth]); if (pos != DConstants::INVALID_INDEX) { @@ -69702,30 +73501,32 @@ bool ART::Insert(Node *&node, Key &key, idx_t depth, row_t row_id) { node->ReplaceChildPointer(pos, child); return insertion_result; } - Node *new_node = Leaf::New(key, depth + 1, row_id); - Node::InsertChild(node, key[depth], new_node); + + Node *leaf_node = Leaf::New(key, depth + 1, row_id); + Node::InsertChild(*this, node, key[depth], leaf_node); + this->memory_size += leaf_node->MemorySize(*this, false); return true; } //===--------------------------------------------------------------------===// // Delete //===--------------------------------------------------------------------===// + void ART::Delete(IndexLock &state, DataChunk &input, Vector &row_ids) { + DataChunk expression; expression.Initialize(Allocator::DefaultAllocator(), logical_types); // first resolve the expressions ExecuteExpressions(input, expression); - idx_t released_memory = MinValue(estimated_art_size, estimated_key_size * input.size()); - BufferManager::GetBufferManager(db).FreeReservedMemory(released_memory); - estimated_art_size -= released_memory; - // then generate the keys for the given input ArenaAllocator arena_allocator(BufferAllocator::Get(db)); vector keys(expression.size()); GenerateKeys(arena_allocator, expression, keys); + auto old_memory_size = this->memory_size; + // now erase the elements from the database row_ids.Flatten(input.size()); auto row_identifiers = FlatVector::GetData(row_ids); @@ -69738,54 +73539,66 @@ void ART::Delete(IndexLock &state, DataChunk &input, Vector &row_ids) { #ifdef DEBUG auto node = Lookup(tree, keys[i], 0); if (node) { - auto leaf = static_cast(node); + auto leaf = (Leaf *)node; for (idx_t k = 0; k < leaf->count; k++) { D_ASSERT(leaf->GetRowId(k) != row_identifiers[i]); } } #endif } + + D_ASSERT(old_memory_size >= memory_size); + Verify(); + if (track_memory) { + buffer_manager.DecreaseUsedMemory(old_memory_size - memory_size); + } } void ART::Erase(Node *&node, Key &key, idx_t depth, row_t row_id) { + if (!node) { return; } - // Delete a leaf from a tree + + // delete a leaf from a tree if (node->type == NodeType::NLeaf) { - // Make sure we have the right leaf - auto leaf = static_cast(node); - leaf->Remove(row_id); + auto leaf = (Leaf *)node; + leaf->Remove(*this, row_id); + if (leaf->count == 0) { + D_ASSERT(this->memory_size >= leaf->MemorySize(*this, false)); + this->memory_size -= leaf->MemorySize(*this, false); Node::Delete(node); node = nullptr; } - return; } - // Handle prefix + // handle prefix if (node->prefix.Size()) { if (node->prefix.KeyMismatchPosition(key, depth) != node->prefix.Size()) { return; } depth += node->prefix.Size(); } + idx_t pos = node->GetChildPos(key[depth]); if (pos != DConstants::INVALID_INDEX) { auto child = node->GetChild(*this, pos); D_ASSERT(child); if (child->type == NodeType::NLeaf) { - // Leaf found, remove entry + // leaf found, remove entry auto leaf = (Leaf *)child; - leaf->Remove(row_id); + leaf->Remove(*this, row_id); + if (leaf->count == 0) { - // Leaf is empty, delete leaf, decrement node counter and maybe shrink node - Node::EraseChild(node, pos, *this); + // leaf is empty, delete leaf, decrement node counter and maybe shrink node + Node::EraseChild(*this, node, pos); } + } else { - // Recurse + // recurse Erase(child, key, depth + 1, row_id); node->ReplaceChildPointer(pos, child); } @@ -69795,6 +73608,7 @@ void ART::Erase(Node *&node, Key &key, idx_t depth, row_t row_id) { //===--------------------------------------------------------------------===// // Point Query //===--------------------------------------------------------------------===// + static Key CreateKey(ArenaAllocator &allocator, PhysicalType type, Value &value) { D_ASSERT(type == value.type().InternalType()); switch (type) { @@ -69831,7 +73645,7 @@ static Key CreateKey(ArenaAllocator &allocator, PhysicalType type, Value &value) bool ART::SearchEqual(Key &key, idx_t max_count, vector &result_ids) { - auto leaf = static_cast(Lookup(tree, key, 0)); + auto leaf = (Leaf *)(Lookup(tree, key, 0)); if (!leaf) { return true; } @@ -69892,6 +73706,7 @@ Leaf *ART::Lookup(Node *node, Key &key, idx_t depth) { // Returns: True (If found leaf >= key) // False (Otherwise) //===--------------------------------------------------------------------===// + bool ART::SearchGreater(ARTIndexScanState *state, Key &key, bool inclusive, idx_t max_count, vector &result_ids) { @@ -69915,6 +73730,7 @@ bool ART::SearchGreater(ARTIndexScanState *state, Key &key, bool inclusive, idx_ //===--------------------------------------------------------------------===// // Less Than //===--------------------------------------------------------------------===// + bool ART::SearchLess(ARTIndexScanState *state, Key &upper_bound, bool inclusive, idx_t max_count, vector &result_ids) { @@ -69940,6 +73756,7 @@ bool ART::SearchLess(ARTIndexScanState *state, Key &upper_bound, bool inclusive, //===--------------------------------------------------------------------===// // Closed Range Query //===--------------------------------------------------------------------===// + bool ART::SearchCloseRange(ARTIndexScanState *state, Key &lower_bound, Key &upper_bound, bool left_inclusive, bool right_inclusive, idx_t max_count, vector &result_ids) { @@ -70027,74 +73844,97 @@ bool ART::Scan(Transaction &transaction, DataTable &table, IndexScanState &table return true; } -void ART::VerifyExistence(DataChunk &chunk, VerifyExistenceType verify_type, string *err_msg_ptr) { - if (verify_type != VerifyExistenceType::DELETE_FK && !IsUnique()) { - return; - } - +string ART::GenerateErrorKeyName(DataChunk &input, idx_t row) { + // re-executing the expressions is not very fast, but we're going to throw anyways, so we don't care DataChunk expression_chunk; expression_chunk.Initialize(Allocator::DefaultAllocator(), logical_types); + ExecuteExpressions(input, expression_chunk); + + string key_name; + for (idx_t k = 0; k < expression_chunk.ColumnCount(); k++) { + if (k > 0) { + key_name += ", "; + } + key_name += unbound_expressions[k]->GetName() + ": " + expression_chunk.data[k].GetValue(row).ToString(); + } + return key_name; +} + +string ART::GenerateConstraintErrorMessage(VerifyExistenceType verify_type, const string &key_name) { + switch (verify_type) { + case VerifyExistenceType::APPEND: { + // APPEND to PK/UNIQUE table, but node/key already exists in PK/UNIQUE table + string type = IsPrimary() ? "primary key" : "unique"; + return StringUtil::Format("Duplicate key \"%s\" violates %s constraint", key_name, type); + } + case VerifyExistenceType::APPEND_FK: { + // APPEND_FK to FK table, node/key does not exist in PK/UNIQUE table + return StringUtil::Format( + "Violates foreign key constraint because key \"%s\" does not exist in the referenced table", key_name); + } + case VerifyExistenceType::DELETE_FK: { + // DELETE_FK that still exists in a FK table, i.e., not a valid delete + return StringUtil::Format("Violates foreign key constraint because key \"%s\" is still referenced by a foreign " + "key in a different table", + key_name); + } + default: + throw NotImplementedException("Type not implemented for VerifyExistenceType"); + } +} + +void ART::LookupValues(DataChunk &input, ConflictManager &conflict_manager) { - // unique index, check + // don't alter the index during constraint checking lock_guard l(lock); + // first resolve the expressions for the index - ExecuteExpressions(chunk, expression_chunk); + DataChunk expression_chunk; + expression_chunk.Initialize(Allocator::DefaultAllocator(), logical_types); + ExecuteExpressions(input, expression_chunk); // generate the keys for the given input ArenaAllocator arena_allocator(BufferAllocator::Get(db)); vector keys(expression_chunk.size()); GenerateKeys(arena_allocator, expression_chunk, keys); - for (idx_t i = 0; i < chunk.size(); i++) { + idx_t found_conflict = DConstants::INVALID_INDEX; + for (idx_t i = 0; found_conflict == DConstants::INVALID_INDEX && i < input.size(); i++) { if (keys[i].Empty()) { + if (conflict_manager.AddNull(i)) { + found_conflict = i; + } continue; } - Node *node_ptr = Lookup(tree, keys[i], 0); - bool throw_exception = - verify_type == VerifyExistenceType::APPEND_FK ? node_ptr == nullptr : node_ptr != nullptr; - if (!throw_exception) { - continue; - } - string key_name; - for (idx_t k = 0; k < expression_chunk.ColumnCount(); k++) { - if (k > 0) { - key_name += ", "; + Leaf *leaf_ptr = Lookup(tree, keys[i], 0); + if (leaf_ptr == nullptr) { + if (conflict_manager.AddMiss(i)) { + found_conflict = i; } - key_name += unbound_expressions[k]->GetName() + ": " + expression_chunk.data[k].GetValue(i).ToString(); - } - string exception_msg; - switch (verify_type) { - case VerifyExistenceType::APPEND: { - // node already exists in tree - string type = IsPrimary() ? "primary key" : "unique"; - exception_msg = "duplicate key \"" + key_name + "\" violates "; - exception_msg += type + " constraint"; - break; - } - case VerifyExistenceType::APPEND_FK: { - // found node no exists in tree - exception_msg = - "violates foreign key constraint because key \"" + key_name + "\" does not exist in referenced table"; - break; - } - case VerifyExistenceType::DELETE_FK: { - // found node exists in tree - exception_msg = - "violates foreign key constraint because key \"" + key_name + "\" exist in table has foreign key"; - break; + continue; } - } - if (err_msg_ptr) { - err_msg_ptr[i] = exception_msg; - } else { - throw ConstraintException(exception_msg); + // When we find a node, we need to update the 'matches' and 'row_ids' + // NOTE: Leafs can have more than one row_id, but for UNIQUE/PRIMARY KEY they will only have one + D_ASSERT(leaf_ptr->count == 1); + auto row_id = leaf_ptr->GetRowId(0); + if (conflict_manager.AddHit(i, row_id)) { + found_conflict = i; } } + conflict_manager.FinishLookup(); + if (found_conflict == DConstants::INVALID_INDEX) { + // No conflicts detected + return; + } + auto key_name = GenerateErrorKeyName(input, found_conflict); + auto exception_msg = GenerateConstraintErrorMessage(conflict_manager.LookupType(), key_name); + throw ConstraintException(exception_msg); } //===--------------------------------------------------------------------===// // Serialization //===--------------------------------------------------------------------===// + BlockPointer ART::Serialize(duckdb::MetaBlockWriter &writer) { lock_guard l(lock); if (tree) { @@ -70106,13 +73946,15 @@ BlockPointer ART::Serialize(duckdb::MetaBlockWriter &writer) { } //===--------------------------------------------------------------------===// -// Merge ARTs +// Merging //===--------------------------------------------------------------------===// + bool ART::MergeIndexes(IndexLock &state, Index *other_index) { + auto other_art = (ART *)other_index; - estimated_art_size += other_art->estimated_art_size; - other_art->estimated_art_size = 0; + if (!this->tree) { + this->memory_size += other_art->memory_size; this->tree = other_art->tree; other_art->tree = nullptr; return true; @@ -70121,6 +73963,10 @@ bool ART::MergeIndexes(IndexLock &state, Index *other_index) { return Node::MergeARTs(this, other_art); } +//===--------------------------------------------------------------------===// +// Utility +//===--------------------------------------------------------------------===// + string ART::ToString() { if (tree) { return tree->ToString(*this); @@ -70128,6 +73974,19 @@ string ART::ToString() { return "[empty]"; } +void ART::Verify() { +#ifdef DEBUG + idx_t current_mem_size = 0; + if (tree) { + current_mem_size = tree->MemorySize(*this, true); + } + if (memory_size != current_mem_size) { + throw InternalException("Memory_size value (%d) does not match actual memory size (%d).", memory_size, + current_mem_size); + } +#endif +} + } // namespace duckdb @@ -70150,6 +74009,11 @@ Key Key::CreateKey(ArenaAllocator &allocator, string_t value) { idx_t len = value.GetSize() + 1; auto data = allocator.Allocate(len); memcpy(data, value.GetDataUnsafe(), len - 1); + + if (len > 1 && data[len - 2] == '\0') { + // FIXME: rethink this + throw NotImplementedException("Indexes cannot have contain null-terminated decoded BLOBs."); + } data[len - 1] = '\0'; return Key(data, len); } @@ -70164,6 +74028,11 @@ void Key::CreateKey(ArenaAllocator &allocator, Key &key, string_t value) { key.len = value.GetSize() + 1; key.data = allocator.Allocate(key.len); memcpy(key.data, value.GetDataUnsafe(), key.len - 1); + + if (key.len > 1 && key.data[key.len - 2] == '\0') { + // FIXME: rethink this + throw NotImplementedException("Indexes cannot have contain null-terminated decoded BLOBs."); + } key.data[key.len - 1] = '\0'; } @@ -70521,6 +74390,7 @@ bool Iterator::LowerBound(Node *node, Key &key, bool inclusive) { + #include namespace duckdb { @@ -70550,6 +74420,9 @@ row_t *Leaf::GetRowIds() { } } +Leaf::Leaf() : Node(NodeType::NLeaf) { +} + Leaf::Leaf(Key &value, uint32_t depth, row_t row_id) : Node(NodeType::NLeaf) { count = 1; rowids.inlined = row_id; @@ -70593,6 +74466,13 @@ Leaf::~Leaf() { } } +idx_t Leaf::MemorySize(ART &, const bool &) { + if (IsInlined()) { + return prefix.MemorySize() + sizeof(*this) + sizeof(row_t); + } + return prefix.MemorySize() + sizeof(*this) + sizeof(row_t) * (GetCapacity() + 1); +} + row_t *Leaf::Resize(row_t *current_row_ids, uint32_t current_count, idx_t new_capacity) { D_ASSERT(new_capacity >= current_count); auto new_allocation = AllocateArray(new_capacity + 1); @@ -70608,34 +74488,48 @@ row_t *Leaf::Resize(row_t *current_row_ids, uint32_t current_count, idx_t new_ca return new_row_ids; } -void Leaf::Insert(row_t row_id) { +void Leaf::Insert(ART &art, row_t row_id) { auto capacity = GetCapacity(); row_t *row_ids = GetRowIds(); D_ASSERT(count <= capacity); + if (count == capacity) { - // Grow array + // grow array + if (IsInlined()) { + art.memory_size += (capacity + 1) * sizeof(row_t); + } else { + art.memory_size += capacity * sizeof(row_t); + } row_ids = Resize(row_ids, count, capacity * 2); } + // insert new row ID row_ids[count++] = row_id; } -void Leaf::Remove(row_t row_id) { +void Leaf::Remove(ART &art, row_t row_id) { idx_t entry_offset = DConstants::INVALID_INDEX; row_t *row_ids = GetRowIds(); + + // find the row ID in the leaf for (idx_t i = 0; i < count; i++) { if (row_ids[i] == row_id) { entry_offset = i; break; } } + + // didn't find the row ID if (entry_offset == DConstants::INVALID_INDEX) { return; } + + // now empty leaf if (IsInlined()) { D_ASSERT(count == 1); count--; return; } + count--; if (count == 1) { // after erasing we can now inline the leaf @@ -70643,21 +74537,31 @@ void Leaf::Remove(row_t row_id) { auto remaining_row_id = row_ids[0] == row_id ? row_ids[1] : row_ids[0]; DeleteArray(rowids.ptr, rowids.ptr[0] + 1); rowids.inlined = remaining_row_id; + D_ASSERT(art.memory_size >= sizeof(row_t)); + art.memory_size -= 2 * sizeof(row_t); return; } + + // shrink array, if less than half full auto capacity = GetCapacity(); if (capacity > 2 && count < capacity / 2) { - // Shrink array, if less than half full + auto new_capacity = capacity / 2; + D_ASSERT(art.memory_size >= (capacity - new_capacity) * sizeof(row_t)); + art.memory_size -= (capacity - new_capacity) * sizeof(row_t); + auto new_allocation = AllocateArray(new_capacity + 1); new_allocation[0] = new_capacity; + auto new_row_ids = new_allocation + 1; memcpy(new_row_ids, row_ids, entry_offset * sizeof(row_t)); memcpy(new_row_ids + entry_offset, row_ids + entry_offset + 1, (count - entry_offset) * sizeof(row_t)); + DeleteArray(rowids.ptr, rowids.ptr[0] + 1); rowids.ptr = new_allocation; + } else { - // Copy the rest + // move the trailing row IDs (after entry_offset) memmove(row_ids + entry_offset, row_ids + entry_offset + 1, (count - entry_offset) * sizeof(row_t)); } } @@ -70672,26 +74576,33 @@ string Leaf::ToString(Node *node) { return str + "]"; } -void Leaf::Merge(Node *&l_node, Node *&r_node) { +void Leaf::Merge(ART &art, Node *&l_node, Node *&r_node) { Leaf *l_n = (Leaf *)l_node; Leaf *r_n = (Leaf *)r_node; - // append non-duplicate row_ids to l_n - for (idx_t i = 0; i < r_n->count; i++) { - l_n->Insert(r_n->GetRowId(i)); + auto l_capacity = l_n->GetCapacity(); + auto l_row_ids = l_n->GetRowIds(); + auto r_row_ids = r_n->GetRowIds(); + + if (l_n->count + r_n->count > l_capacity) { + auto capacity = l_n->GetCapacity(); + auto new_capacity = NextPowerOfTwo(l_n->count + r_n->count); + art.memory_size += sizeof(row_t) * (new_capacity - capacity); + l_row_ids = l_n->Resize(l_row_ids, l_n->count, new_capacity); } + + // append row_ids to l_n + memcpy(l_row_ids + l_n->count, r_row_ids, r_n->count * sizeof(row_t)); + l_n->count += r_n->count; } BlockPointer Leaf::Serialize(duckdb::MetaBlockWriter &writer) { + auto ptr = writer.GetBlockPointer(); - // Write Node Type writer.Write(type); - // Write compression Info prefix.Serialize(writer); - // Write Row Ids - // Length writer.Write(count); - // Actual Row Ids + auto row_ids = GetRowIds(); for (idx_t i = 0; i < count; i++) { writer.Write(row_ids[i]); @@ -70699,22 +74610,23 @@ BlockPointer Leaf::Serialize(duckdb::MetaBlockWriter &writer) { return ptr; } -Leaf *Leaf::Deserialize(MetaBlockReader &reader) { - Prefix prefix; +void Leaf::Deserialize(ART &art, MetaBlockReader &reader) { + prefix.Deserialize(reader); - auto num_elements = reader.Read(); - if (num_elements == 1) { + count = reader.Read(); + if (count == 1) { // inlined - auto element = reader.Read(); - return Leaf::New(element, prefix); + auto row_id = reader.Read(); + rowids.inlined = row_id; + } else { // non-inlined - auto elements = AllocateArray(num_elements + 1); - elements[0] = num_elements; - for (idx_t i = 0; i < num_elements; i++) { - elements[i + 1] = reader.Read(); + auto row_ids = AllocateArray(count + 1); + row_ids[0] = count; + for (idx_t i = 0; i < count; i++) { + row_ids[i + 1] = reader.Read(); } - return Leaf::New(elements, num_elements, prefix); + rowids.ptr = row_ids; } } @@ -70782,6 +74694,10 @@ Node::Node(NodeType type) : count(0), type(type) { } // LCOV_EXCL_START +idx_t Node::MemorySize(ART &, const bool &) { + throw InternalException("MemorySize not implemented for the specific node type."); +} + idx_t Node::GetMin() { throw InternalException("GetMin not implemented for the specific node type."); } @@ -70793,46 +74709,50 @@ Node *Node::GetChild(ART &art, idx_t pos) { void Node::ReplaceChildPointer(idx_t pos, Node *node) { throw InternalException("ReplaceChildPointer not implemented for the specific node type."); } + +bool Node::ChildIsInMemory(idx_t) { + throw InternalException("ChildIsInMemory not implemented for the specific node type."); +} // LCOV_EXCL_STOP -void Node::InsertChild(Node *&node, uint8_t key_byte, Node *new_child) { +void Node::InsertChild(ART &art, Node *&node, uint8_t key_byte, Node *new_child) { switch (node->type) { case NodeType::N4: - Node4::InsertChild(node, key_byte, new_child); + Node4::InsertChild(art, node, key_byte, new_child); break; case NodeType::N16: - Node16::InsertChild(node, key_byte, new_child); + Node16::InsertChild(art, node, key_byte, new_child); break; case NodeType::N48: - Node48::InsertChild(node, key_byte, new_child); + Node48::InsertChild(art, node, key_byte, new_child); break; case NodeType::N256: - Node256::InsertChild(node, key_byte, new_child); + Node256::InsertChild(art, node, key_byte, new_child); break; default: - throw InternalException("Unrecognized leaf type for insert"); + throw InternalException("Unrecognized node type for insert."); } } -void Node::EraseChild(Node *&node, idx_t pos, ART &art) { +void Node::EraseChild(ART &art, Node *&node, idx_t pos) { switch (node->type) { case NodeType::N4: { - Node4::EraseChild(node, pos, art); + Node4::EraseChild(art, node, pos); break; } case NodeType::N16: { - Node16::EraseChild(node, pos, art); + Node16::EraseChild(art, node, pos); break; } case NodeType::N48: { - Node48::EraseChild(node, pos, art); + Node48::EraseChild(art, node, pos); break; } case NodeType::N256: - Node256::EraseChild(node, pos, art); + Node256::EraseChild(art, node, pos); break; default: - throw InternalException("Unrecognized leaf type for erase"); + throw InternalException("Unrecognized node type for erase."); } } @@ -70849,7 +74769,7 @@ NodeType Node::GetTypeBySize(idx_t size) { return NodeType::N256; } -void Node::New(NodeType &type, Node *&node) { +void Node::New(const NodeType &type, Node *&node) { switch (type) { case NodeType::N4: node = (Node *)Node4::New(); @@ -70864,7 +74784,7 @@ void Node::New(NodeType &type, Node *&node) { node = (Node *)Node256::New(); return; default: - throw InternalException("Unrecognized type for new node creation!"); + throw InternalException("Unrecognized node type for new node creation."); } } @@ -70884,6 +74804,10 @@ Node256 *Node256::New() { return AllocateObject(); } +Leaf *Leaf::New() { + return AllocateObject(); +} + Leaf *Leaf::New(Key &value, uint32_t depth, row_t row_id) { return AllocateObject(value, depth, row_id); } @@ -70918,7 +74842,7 @@ void Node::Delete(Node *ptr) { DestroyObject((Node256 *)ptr); break; default: - throw InternalException("eek"); + throw InternalException("Invalid node type for delete."); } } @@ -70953,23 +74877,24 @@ string Node::ToString(ART &art) { } BlockPointer Node::SerializeInternal(ART &art, duckdb::MetaBlockWriter &writer, InternalType &internal_type) { - // Iterate through children and annotate their offsets + + // iterate through children and annotate their offsets vector child_offsets; for (idx_t i = 0; i < internal_type.children_size; i++) { child_offsets.emplace_back(internal_type.children[i].Serialize(art, writer)); } auto ptr = writer.GetBlockPointer(); - // Write Node Type + writer.Write(type); - // Write count writer.Write(count); - // Write Prefix prefix.Serialize(writer); - // Write Key values + + // write key values for (idx_t i = 0; i < internal_type.key_size; i++) { writer.Write(internal_type.key[i]); } - // Write child offsets + + // write child offsets for (auto &offsets : child_offsets) { writer.Write(offsets.block_id); writer.Write(offsets.offset); @@ -70978,6 +74903,7 @@ BlockPointer Node::SerializeInternal(ART &art, duckdb::MetaBlockWriter &writer, } BlockPointer Node::Serialize(ART &art, duckdb::MetaBlockWriter &writer) { + switch (type) { case NodeType::N4: case NodeType::N16: @@ -70991,33 +74917,48 @@ BlockPointer Node::Serialize(ART &art, duckdb::MetaBlockWriter &writer) { return leaf->Serialize(writer); } default: - throw InternalException("Invalid ART Node"); + throw InternalException("Invalid ART node for serialize."); } } -void Node::DeserializeInternal(duckdb::MetaBlockReader &reader) { +void Node::DeserializeInternal(ART &art, duckdb::MetaBlockReader &reader) { + InternalType internal_type(this); count = reader.Read(); prefix.Deserialize(reader); - // Get Key values + + // read key values for (idx_t i = 0; i < internal_type.key_size; i++) { internal_type.key[i] = reader.Read(); } - // Get Child offsets + + // read child offsets for (idx_t i = 0; i < internal_type.children_size; i++) { internal_type.children[i] = ARTPointer(reader); } } Node *Node::Deserialize(ART &art, idx_t block_id, idx_t offset) { + MetaBlockReader reader(art.table_io_manager.GetIndexBlockManager(), block_id); reader.offset = offset; + auto n = reader.Read(); - NodeType node_type(static_cast(n)); - Node *deserialized_node; + NodeType node_type((NodeType)(n)); + + Node *deserialized_node = nullptr; + auto old_memory_size = art.memory_size; switch (node_type) { - case NodeType::NLeaf: - return Leaf::Deserialize(reader); + case NodeType::NLeaf: { + auto leaf = Leaf::New(); + leaf->Deserialize(art, reader); + art.memory_size += leaf->MemorySize(art, false); + D_ASSERT(art.memory_size >= old_memory_size); + if (art.track_memory) { + art.buffer_manager.IncreaseUsedMemory(art.memory_size - old_memory_size); + } + return leaf; + } case NodeType::N4: { deserialized_node = (Node *)Node4::New(); break; @@ -71034,8 +74975,15 @@ Node *Node::Deserialize(ART &art, idx_t block_id, idx_t offset) { deserialized_node = (Node *)Node256::New(); break; } + default: + throw InternalException("Unrecognized node type"); + } + deserialized_node->DeserializeInternal(art, reader); + art.memory_size += deserialized_node->MemorySize(art, false); + D_ASSERT(art.memory_size >= old_memory_size); + if (art.track_memory) { + art.buffer_manager.IncreaseUsedMemory(art.memory_size - old_memory_size); } - deserialized_node->DeserializeInternal(reader); return deserialized_node; } @@ -71048,7 +74996,31 @@ void UpdateParentsOfNodes(Node *&l_node, Node *&r_node, ParentsOfNodes &parents) } } -bool Merge(MergeInfo &info, idx_t depth, ParentsOfNodes &parents) { +// forward declaration +bool ResolvePrefixesAndMerge(MergeInfo &info, ParentsOfNodes &parents); + +void SwapNodes(MergeInfo &info, ParentsOfNodes &parents) { + // adjust the memory sizes + auto l_node_memory_size = info.l_node->MemorySize(*info.l_art, true); + auto r_node_memory_size = info.r_node->MemorySize(*info.r_art, true); + + D_ASSERT(info.root_l_art->memory_size >= l_node_memory_size); + D_ASSERT(info.root_r_art->memory_size >= r_node_memory_size); + info.root_l_art->memory_size -= l_node_memory_size; + info.root_r_art->memory_size -= r_node_memory_size; + info.root_l_art->memory_size += r_node_memory_size; + info.root_r_art->memory_size += l_node_memory_size; + + // actual swap + swap(info.l_art, info.r_art); + swap(info.l_node, info.r_node); + UpdateParentsOfNodes(info.l_node, info.r_node, parents); +} + +bool Merge(MergeInfo &info, ParentsOfNodes &parents) { + + D_ASSERT(info.l_node); + D_ASSERT(info.r_node); // always try to merge the smaller node into the bigger node // because maybe there is enough free space in the bigger node to fit the smaller one @@ -71056,55 +75028,81 @@ bool Merge(MergeInfo &info, idx_t depth, ParentsOfNodes &parents) { if (info.l_node->type < info.r_node->type) { // swap subtrees to ensure that l_node has the bigger node type - swap(info.l_art, info.r_art); - swap(info.l_node, info.r_node); - UpdateParentsOfNodes(info.l_node, info.r_node, parents); + SwapNodes(info, parents); } - switch (info.r_node->type) { - case NodeType::N256: - return Node256::Merge(info, depth, parents.l_parent, parents.l_pos); - case NodeType::N48: - return Node48::Merge(info, depth, parents.l_parent, parents.l_pos); - case NodeType::N16: - return Node16::Merge(info, depth, parents.l_parent, parents.l_pos); - case NodeType::N4: - return Node4::Merge(info, depth, parents.l_parent, parents.l_pos); - case NodeType::NLeaf: + if (info.r_node->type == NodeType::NLeaf) { D_ASSERT(info.l_node->type == NodeType::NLeaf); D_ASSERT(info.r_node->type == NodeType::NLeaf); if (info.l_art->IsUnique()) { return false; } - Leaf::Merge(info.l_node, info.r_node); + Leaf::Merge(*info.root_l_art, info.l_node, info.r_node); return true; } - throw InternalException("Invalid node type for right node in merge."); -} -bool ResolvePrefixesAndMerge(MergeInfo &info, idx_t depth, ParentsOfNodes &parents) { - auto &l_node = info.l_node; - auto &r_node = info.r_node; - Node *null_parent = nullptr; + uint8_t key_byte; + idx_t r_child_pos = DConstants::INVALID_INDEX; + + while (true) { + r_child_pos = info.r_node->GetNextPosAndByte(r_child_pos, key_byte); + if (r_child_pos == DConstants::INVALID_INDEX) { + break; + } + auto r_child = info.r_node->GetChild(*info.r_art, r_child_pos); + auto l_child_pos = info.l_node->GetChildPos(key_byte); + + if (l_child_pos == DConstants::INVALID_INDEX) { + // insert child at empty position + auto r_memory_size = r_child->MemorySize(*info.r_art, true); + Node::InsertChild(*info.root_l_art, info.l_node, key_byte, r_child); + + info.root_l_art->memory_size += r_memory_size; + D_ASSERT(info.root_r_art->memory_size >= r_memory_size); + info.root_r_art->memory_size -= r_memory_size; + if (parents.l_parent) { + parents.l_parent->ReplaceChildPointer(parents.l_pos, info.l_node); + } + info.r_node->ReplaceChildPointer(r_child_pos, nullptr); + + } else { + // recurse + auto l_child = info.l_node->GetChild(*info.l_art, l_child_pos); + MergeInfo child_info(info.l_art, info.r_art, info.root_l_art, info.root_r_art, l_child, r_child); + ParentsOfNodes child_parents(info.l_node, l_child_pos, info.r_node, r_child_pos); + if (!ResolvePrefixesAndMerge(child_info, child_parents)) { + return false; + } + } + } + return true; +} +bool ResolvePrefixesAndMerge(MergeInfo &info, ParentsOfNodes &parents) { // NOTE: we always merge into the left ART - D_ASSERT(l_node); + + D_ASSERT(info.l_node); + D_ASSERT(info.r_node); // make sure that r_node has the longer (or equally long) prefix - if (l_node->prefix.Size() > r_node->prefix.Size()) { - swap(info.l_art, info.r_art); - swap(l_node, r_node); - UpdateParentsOfNodes(l_node, r_node, parents); + if (info.l_node->prefix.Size() > info.r_node->prefix.Size()) { + SwapNodes(info, parents); } + Node *null_parent = nullptr; + auto &l_node = info.l_node; + auto &r_node = info.r_node; + auto l_prefix_size = l_node->prefix.Size(); + auto r_prefix_size = r_node->prefix.Size(); + auto mismatch_pos = l_node->prefix.MismatchPosition(r_node->prefix); // both nodes have no prefix or the same prefix - if (mismatch_pos == l_node->prefix.Size() && l_node->prefix.Size() == r_node->prefix.Size()) { - return Merge(info, depth + mismatch_pos, parents); + if (mismatch_pos == l_prefix_size && l_prefix_size == r_prefix_size) { + return Merge(info, parents); } - if (mismatch_pos == l_node->prefix.Size()) { + if (mismatch_pos == l_prefix_size) { // r_node's prefix contains l_node's prefix // l_node cannot be a leaf, otherwise the key represented by l_node would be a subset of another key // which is not possible by our construction @@ -71115,11 +75113,17 @@ bool ResolvePrefixesAndMerge(MergeInfo &info, idx_t depth, ParentsOfNodes &paren auto child_pos = l_node->GetChildPos(mismatch_byte); // update the prefix of r_node to only consist of the bytes after mismatch_pos - r_node->prefix.Reduce(mismatch_pos); + r_node->prefix.Reduce(*info.root_r_art, mismatch_pos); // insert r_node as a child of l_node at empty position if (child_pos == DConstants::INVALID_INDEX) { - Node::InsertChild(l_node, mismatch_byte, r_node); + + auto r_memory_size = r_node->MemorySize(*info.r_art, true); + Node::InsertChild(*info.root_l_art, l_node, mismatch_byte, r_node); + + info.root_l_art->memory_size += r_memory_size; + D_ASSERT(info.root_r_art->memory_size >= r_memory_size); + info.root_r_art->memory_size -= r_memory_size; UpdateParentsOfNodes(l_node, null_parent, parents); r_node = nullptr; return true; @@ -71127,9 +75131,9 @@ bool ResolvePrefixesAndMerge(MergeInfo &info, idx_t depth, ParentsOfNodes &paren // recurse auto child_node = l_node->GetChild(*info.l_art, child_pos); - MergeInfo child_info(info.l_art, info.r_art, child_node, r_node); + MergeInfo child_info(info.l_art, info.r_art, info.root_l_art, info.root_r_art, child_node, r_node); ParentsOfNodes child_parents(l_node, child_pos, parents.r_parent, parents.r_pos); - return ResolvePrefixesAndMerge(child_info, depth + mismatch_pos, child_parents); + return ResolvePrefixesAndMerge(child_info, child_parents); } // prefixes differ, create new node and insert both nodes as children @@ -71137,14 +75141,20 @@ bool ResolvePrefixesAndMerge(MergeInfo &info, idx_t depth, ParentsOfNodes &paren // create new node Node *new_node = Node4::New(); new_node->prefix = Prefix(l_node->prefix, mismatch_pos); + info.root_l_art->memory_size += new_node->MemorySize(*info.l_art, false); // insert l_node, break up prefix of l_node - auto key_byte = l_node->prefix.Reduce(mismatch_pos); - Node4::InsertChild(new_node, key_byte, l_node); + auto key_byte = l_node->prefix.Reduce(*info.root_l_art, mismatch_pos); + Node4::InsertChild(*info.root_l_art, new_node, key_byte, l_node); // insert r_node, break up prefix of r_node - key_byte = r_node->prefix.Reduce(mismatch_pos); - Node4::InsertChild(new_node, key_byte, r_node); + key_byte = r_node->prefix.Reduce(*info.root_r_art, mismatch_pos); + auto r_memory_size = r_node->MemorySize(*info.r_art, true); + Node4::InsertChild(*info.root_l_art, new_node, key_byte, r_node); + + info.root_l_art->memory_size += r_memory_size; + D_ASSERT(info.root_r_art->memory_size >= r_memory_size); + info.root_r_art->memory_size -= r_memory_size; l_node = new_node; UpdateParentsOfNodes(l_node, null_parent, parents); @@ -71152,34 +75162,29 @@ bool ResolvePrefixesAndMerge(MergeInfo &info, idx_t depth, ParentsOfNodes &paren return true; } -bool Node::MergeAtByte(MergeInfo &info, idx_t depth, idx_t &l_child_pos, idx_t &r_pos, uint8_t &key_byte, - Node *&l_parent, idx_t l_pos) { +bool Node::MergeARTs(ART *l_art, ART *r_art) { + + Node *null_parent = nullptr; + MergeInfo info(l_art, r_art, l_art, r_art, l_art->tree, r_art->tree); + ParentsOfNodes parents(null_parent, 0, null_parent, 0); + return ResolvePrefixesAndMerge(info, parents); +} + +idx_t Node::RecursiveMemorySize(ART &art) { - auto r_child = info.r_node->GetChild(*info.r_art, r_pos); + // get the size of all children + auto memory_size_children = 0; - // insert child at empty position - if (l_child_pos == DConstants::INVALID_INDEX) { - Node::InsertChild(info.l_node, key_byte, r_child); - if (l_parent) { - l_parent->ReplaceChildPointer(l_pos, info.l_node); + auto next_pos = GetNextPos(DConstants::INVALID_INDEX); + while (next_pos != DConstants::INVALID_INDEX) { + if (ChildIsInMemory(next_pos)) { + auto child = GetChild(art, next_pos); + memory_size_children += child->MemorySize(art, true); } - info.r_node->ReplaceChildPointer(r_pos, nullptr); - return true; + next_pos = GetNextPos(next_pos); } - // recurse - auto l_child = info.l_node->GetChild(*info.l_art, l_child_pos); - MergeInfo child_info(info.l_art, info.r_art, l_child, r_child); - ParentsOfNodes child_parents(info.l_node, l_child_pos, info.r_node, r_pos); - return ResolvePrefixesAndMerge(child_info, depth + 1, child_parents); -} - -bool Node::MergeARTs(ART *l_art, ART *r_art) { - - Node *null_parent = nullptr; - MergeInfo info(l_art, r_art, l_art->tree, r_art->tree); - ParentsOfNodes parents(null_parent, 0, null_parent, 0); - return ResolvePrefixesAndMerge(info, 0, parents); + return memory_size_children; } } // namespace duckdb @@ -71188,6 +75193,7 @@ bool Node::MergeARTs(ART *l_art, ART *r_art) { + #include namespace duckdb { @@ -71196,6 +75202,13 @@ Node16::Node16() : Node(NodeType::N16) { memset(key, 16, sizeof(key)); } +idx_t Node16::MemorySize(ART &art, const bool &recurse) { + if (recurse) { + return prefix.MemorySize() + sizeof(*this) + RecursiveMemorySize(art); + } + return prefix.MemorySize() + sizeof(*this); +} + idx_t Node16::GetChildPos(uint8_t k) { for (idx_t pos = 0; pos < count; pos++) { if (key[pos] == k) { @@ -71232,6 +75245,19 @@ idx_t Node16::GetNextPos(idx_t pos) { return pos < count ? pos : DConstants::INVALID_INDEX; } +idx_t Node16::GetNextPosAndByte(idx_t pos, uint8_t &byte) { + if (pos == DConstants::INVALID_INDEX) { + byte = key[0]; + return 0; + } + pos++; + if (pos < count) { + byte = key[pos]; + return pos; + } + return DConstants::INVALID_INDEX; +} + Node *Node16::GetChild(ART &art, idx_t pos) { D_ASSERT(pos < count); return children[pos].Unswizzle(art); @@ -71241,12 +75267,16 @@ void Node16::ReplaceChildPointer(idx_t pos, Node *node) { children[pos] = node; } -void Node16::InsertChild(Node *&node, uint8_t key_byte, Node *new_child) { +bool Node16::ChildIsInMemory(idx_t pos) { + return children[pos] && !children[pos].IsSwizzled(); +} + +void Node16::InsertChild(ART &art, Node *&node, uint8_t key_byte, Node *new_child) { Node16 *n = (Node16 *)node; - // Insert new child node into node - if (n->count < 16) { - // Insert element + // insert new child node into node + if (n->count < Node16::GetSize()) { + // still space, just insert the child idx_t pos = 0; while (pos < node->count && n->key[pos] < key_byte) { pos++; @@ -71260,83 +75290,94 @@ void Node16::InsertChild(Node *&node, uint8_t key_byte, Node *new_child) { n->key[pos] = key_byte; n->children[pos] = new_child; n->count++; + } else { - // Grow to Node48 + // node is full, grow to Node48 auto new_node = Node48::New(); + art.memory_size += new_node->MemorySize(art, false); + new_node->count = node->count; + new_node->prefix = std::move(n->prefix); + for (idx_t i = 0; i < node->count; i++) { new_node->child_index[n->key[i]] = i; new_node->children[i] = n->children[i]; n->children[i] = nullptr; } - new_node->prefix = move(n->prefix); - new_node->count = node->count; + + D_ASSERT(art.memory_size >= node->MemorySize(art, false)); + art.memory_size -= node->MemorySize(art, false); Node::Delete(node); node = new_node; - - Node48::InsertChild(node, key_byte, new_child); + Node48::InsertChild(art, node, key_byte, new_child); } } -void Node16::EraseChild(Node *&node, int pos, ART &art) { +void Node16::EraseChild(ART &art, Node *&node, idx_t pos) { + auto n = (Node16 *)node; + D_ASSERT(pos < n->count); + + // adjust the ART size + if (n->ChildIsInMemory(pos)) { + auto child = n->GetChild(art, pos); + D_ASSERT(art.memory_size >= child->MemorySize(art, true)); + art.memory_size -= child->MemorySize(art, true); + } + // erase the child and decrease the count n->children[pos].Reset(); n->count--; + // potentially move any children backwards for (; pos < n->count; pos++) { n->key[pos] = n->key[pos + 1]; n->children[pos] = n->children[pos + 1]; } // set any remaining nodes as nullptr - for (; pos < 16; pos++) { + for (; pos < Node16::GetSize(); pos++) { if (!n->children[pos]) { break; } n->children[pos] = nullptr; } - if (node->count <= 3) { - // Shrink node + // shrink node to Node4 + if (node->count < Node4::GetSize()) { + auto new_node = Node4::New(); - for (unsigned i = 0; i < n->count; i++) { + art.memory_size += new_node->MemorySize(art, false); + new_node->prefix = std::move(n->prefix); + + for (idx_t i = 0; i < n->count; i++) { new_node->key[new_node->count] = n->key[i]; new_node->children[new_node->count++] = n->children[i]; n->children[i] = nullptr; } - new_node->prefix = move(n->prefix); + + D_ASSERT(art.memory_size >= node->MemorySize(art, false)); + art.memory_size -= node->MemorySize(art, false); Node::Delete(node); node = new_node; } } - -bool Node16::Merge(MergeInfo &info, idx_t depth, Node *&l_parent, idx_t l_pos) { - - Node16 *r_n = (Node16 *)info.r_node; - - for (idx_t i = 0; i < info.r_node->count; i++) { - - auto l_child_pos = info.l_node->GetChildPos(r_n->key[i]); - if (!Node::MergeAtByte(info, depth, l_child_pos, i, r_n->key[i], l_parent, l_pos)) { - return false; - } - } - return true; -} - -idx_t Node16::GetSize() { - return 16; -} - } // namespace duckdb + namespace duckdb { Node256::Node256() : Node(NodeType::N256) { } +idx_t Node256::MemorySize(ART &art, const bool &recurse) { + if (recurse) { + return prefix.MemorySize() + sizeof(*this) + RecursiveMemorySize(art); + } + return prefix.MemorySize() + sizeof(*this); +} + idx_t Node256::GetChildPos(uint8_t k) { if (children[k]) { return k; @@ -71346,7 +75387,7 @@ idx_t Node256::GetChildPos(uint8_t k) { } idx_t Node256::GetChildGreaterEqual(uint8_t k, bool &equal) { - for (idx_t pos = k; pos < 256; pos++) { + for (idx_t pos = k; pos < Node256::GetSize(); pos++) { if (children[pos]) { if (pos == k) { equal = true; @@ -71360,7 +75401,7 @@ idx_t Node256::GetChildGreaterEqual(uint8_t k, bool &equal) { } idx_t Node256::GetMin() { - for (idx_t i = 0; i < 256; i++) { + for (idx_t i = 0; i < Node256::GetSize(); i++) { if (children[i]) { return i; } @@ -71369,7 +75410,8 @@ idx_t Node256::GetMin() { } idx_t Node256::GetNextPos(idx_t pos) { - for (pos == DConstants::INVALID_INDEX ? pos = 0 : pos++; pos < 256; pos++) { + pos == DConstants::INVALID_INDEX ? pos = 0 : pos++; + for (; pos < Node256::GetSize(); pos++) { if (children[pos]) { return pos; } @@ -71377,6 +75419,17 @@ idx_t Node256::GetNextPos(idx_t pos) { return Node::GetNextPos(pos); } +idx_t Node256::GetNextPosAndByte(idx_t pos, uint8_t &byte) { + pos == DConstants::INVALID_INDEX ? pos = 0 : pos++; + for (; pos < Node256::GetSize(); pos++) { + if (children[pos]) { + byte = uint8_t(pos); + return pos; + } + } + return Node::GetNextPos(pos); +} + Node *Node256::GetChild(ART &art, idx_t pos) { return children[pos].Unswizzle(art); } @@ -71385,52 +75438,52 @@ void Node256::ReplaceChildPointer(idx_t pos, Node *node) { children[pos] = node; } -void Node256::InsertChild(Node *&node, uint8_t key_byte, Node *new_child) { +bool Node256::ChildIsInMemory(idx_t pos) { + return children[pos] && !children[pos].IsSwizzled(); +} + +void Node256::InsertChild(ART &, Node *&node, uint8_t key_byte, Node *new_child) { auto n = (Node256 *)(node); n->count++; n->children[key_byte] = new_child; } -void Node256::EraseChild(Node *&node, int pos, ART &art) { +void Node256::EraseChild(ART &art, Node *&node, idx_t pos) { auto n = (Node256 *)(node); + + // adjust the ART size + if (n->ChildIsInMemory(pos)) { + auto child = n->GetChild(art, pos); + D_ASSERT(art.memory_size >= child->MemorySize(art, true)); + art.memory_size -= child->MemorySize(art, true); + } + + // erase the child and decrease the count n->children[pos].Reset(); n->count--; - if (node->count <= 36) { + + // shrink node to Node48 + if (node->count <= NODE_256_SHRINK_THRESHOLD) { + auto new_node = Node48::New(); - new_node->prefix = move(n->prefix); - for (idx_t i = 0; i < 256; i++) { + art.memory_size += new_node->MemorySize(art, false); + new_node->prefix = std::move(n->prefix); + + for (idx_t i = 0; i < Node256::GetSize(); i++) { if (n->children[i]) { new_node->child_index[i] = new_node->count; - new_node->children[new_node->count] = n->children[i]; + new_node->children[new_node->count++] = n->children[i]; n->children[i] = nullptr; - new_node->count++; } } + + D_ASSERT(art.memory_size >= node->MemorySize(art, false)); + art.memory_size -= node->MemorySize(art, false); Node::Delete(node); node = new_node; } } - -bool Node256::Merge(MergeInfo &info, idx_t depth, Node *&l_parent, idx_t l_pos) { - - for (idx_t i = 0; i < 256; i++) { - if (info.r_node->GetChildPos(i) != DConstants::INVALID_INDEX) { - - auto l_child_pos = info.l_node->GetChildPos(i); - auto key_byte = (uint8_t)i; - if (!Node::MergeAtByte(info, depth, l_child_pos, i, key_byte, l_parent, l_pos)) { - return false; - } - } - } - return true; -} - -idx_t Node256::GetSize() { - return 256; -} - } // namespace duckdb @@ -71444,6 +75497,13 @@ Node4::Node4() : Node(NodeType::N4) { memset(key, 0, sizeof(key)); } +idx_t Node4::MemorySize(ART &art, const bool &recurse) { + if (recurse) { + return prefix.MemorySize() + sizeof(*this) + RecursiveMemorySize(art); + } + return prefix.MemorySize() + sizeof(*this); +} + idx_t Node4::GetChildPos(uint8_t k) { for (idx_t pos = 0; pos < count; pos++) { if (key[pos] == k) { @@ -71479,6 +75539,19 @@ idx_t Node4::GetNextPos(idx_t pos) { return pos < count ? pos : DConstants::INVALID_INDEX; } +idx_t Node4::GetNextPosAndByte(idx_t pos, uint8_t &byte) { + if (pos == DConstants::INVALID_INDEX) { + byte = key[0]; + return 0; + } + pos++; + if (pos < count) { + byte = key[pos]; + return pos; + } + return DConstants::INVALID_INDEX; +} + Node *Node4::GetChild(ART &art, idx_t pos) { D_ASSERT(pos < count); return children[pos].Unswizzle(art); @@ -71488,12 +75561,16 @@ void Node4::ReplaceChildPointer(idx_t pos, Node *node) { children[pos] = node; } -void Node4::InsertChild(Node *&node, uint8_t key_byte, Node *new_child) { +bool Node4::ChildIsInMemory(idx_t pos) { + return children[pos] && !children[pos].IsSwizzled(); +} + +void Node4::InsertChild(ART &art, Node *&node, uint8_t key_byte, Node *new_child) { Node4 *n = (Node4 *)node; - // Insert new child node into node - if (node->count < 4) { - // Insert element + // insert new child node into node + if (node->count < Node4::GetSize()) { + // still space, just insert the child idx_t pos = 0; while ((pos < node->count) && (n->key[pos] < key_byte)) { pos++; @@ -71507,74 +75584,80 @@ void Node4::InsertChild(Node *&node, uint8_t key_byte, Node *new_child) { n->key[pos] = key_byte; n->children[pos] = new_child; n->count++; + } else { - // Grow to Node16 + // node is full, grow to Node16 auto new_node = Node16::New(); - new_node->count = 4; - new_node->prefix = move(node->prefix); - for (idx_t i = 0; i < 4; i++) { + art.memory_size += new_node->MemorySize(art, false); + new_node->count = n->count; + new_node->prefix = std::move(node->prefix); + + for (idx_t i = 0; i < n->count; i++) { new_node->key[i] = n->key[i]; new_node->children[i] = n->children[i]; n->children[i] = nullptr; } - // Delete old node and replace it with new Node16 + n->count = 0; + + D_ASSERT(art.memory_size >= node->MemorySize(art, false)); + art.memory_size -= node->MemorySize(art, false); Node::Delete(node); node = new_node; - Node16::InsertChild(node, key_byte, new_child); + Node16::InsertChild(art, node, key_byte, new_child); } } -void Node4::EraseChild(Node *&node, int pos, ART &art) { +void Node4::EraseChild(ART &art, Node *&node, idx_t pos) { + Node4 *n = (Node4 *)node; D_ASSERT(pos < n->count); + D_ASSERT(n->count > 1); + + // adjust the ART size + if (n->ChildIsInMemory(pos)) { + auto child = n->GetChild(art, pos); + D_ASSERT(art.memory_size >= child->MemorySize(art, true)); + art.memory_size -= child->MemorySize(art, true); + } + // erase the child and decrease the count n->children[pos].Reset(); n->count--; + D_ASSERT(n->count >= 1); + // potentially move any children backwards for (; pos < n->count; pos++) { n->key[pos] = n->key[pos + 1]; n->children[pos] = n->children[pos + 1]; } // set any remaining nodes as nullptr - for (; pos < 4; pos++) { + for (; pos < Node4::GetSize(); pos++) { n->children[pos] = nullptr; } - // This is a one way node + // this is a one way node, compress if (n->count == 1) { + + // get only child and concatenate prefixes auto child_ref = n->GetChild(art, 0); // concatenate prefixes - child_ref->prefix.Concatenate(n->key[0], node->prefix); + child_ref->prefix.Concatenate(art, n->key[0], node->prefix); + // ensure that when deleting the node, we do not delete the child (because we move it) n->children[0] = nullptr; + + D_ASSERT(art.memory_size >= n->MemorySize(art, false)); + art.memory_size -= n->MemorySize(art, false); Node::Delete(node); node = child_ref; } } - -bool Node4::Merge(MergeInfo &info, idx_t depth, Node *&l_parent, idx_t l_pos) { - - Node4 *r_n = (Node4 *)info.r_node; - - for (idx_t i = 0; i < info.r_node->count; i++) { - - auto l_child_pos = info.l_node->GetChildPos(r_n->key[i]); - if (!Node::MergeAtByte(info, depth, l_child_pos, i, r_n->key[i], l_parent, l_pos)) { - return false; - } - } - return true; -} - -idx_t Node4::GetSize() { - return 4; -} - } // namespace duckdb + namespace duckdb { Node48::Node48() : Node(NodeType::N48) { @@ -71583,6 +75666,13 @@ Node48::Node48() : Node(NodeType::N48) { } } +idx_t Node48::MemorySize(ART &art, const bool &recurse) { + if (recurse) { + return prefix.MemorySize() + sizeof(*this) + RecursiveMemorySize(art); + } + return prefix.MemorySize() + sizeof(*this); +} + idx_t Node48::GetChildPos(uint8_t k) { if (child_index[k] == Node::EMPTY_MARKER) { return DConstants::INVALID_INDEX; @@ -71592,7 +75682,7 @@ idx_t Node48::GetChildPos(uint8_t k) { } idx_t Node48::GetChildGreaterEqual(uint8_t k, bool &equal) { - for (idx_t pos = k; pos < 256; pos++) { + for (idx_t pos = k; pos < Node256::GetSize(); pos++) { if (child_index[pos] != Node::EMPTY_MARKER) { if (pos == k) { equal = true; @@ -71606,7 +75696,7 @@ idx_t Node48::GetChildGreaterEqual(uint8_t k, bool &equal) { } idx_t Node48::GetMin() { - for (idx_t i = 0; i < 256; i++) { + for (idx_t i = 0; i < Node256::GetSize(); i++) { if (child_index[i] != Node::EMPTY_MARKER) { return i; } @@ -71615,7 +75705,8 @@ idx_t Node48::GetMin() { } idx_t Node48::GetNextPos(idx_t pos) { - for (pos == DConstants::INVALID_INDEX ? pos = 0 : pos++; pos < 256; pos++) { + pos == DConstants::INVALID_INDEX ? pos = 0 : pos++; + for (; pos < Node256::GetSize(); pos++) { if (child_index[pos] != Node::EMPTY_MARKER) { return pos; } @@ -71623,6 +75714,17 @@ idx_t Node48::GetNextPos(idx_t pos) { return Node::GetNextPos(pos); } +idx_t Node48::GetNextPosAndByte(idx_t pos, uint8_t &byte) { + pos == DConstants::INVALID_INDEX ? pos = 0 : pos++; + for (; pos < Node256::GetSize(); pos++) { + if (child_index[pos] != Node::EMPTY_MARKER) { + byte = uint8_t(pos); + return pos; + } + } + return Node::GetNextPos(pos); +} + Node *Node48::GetChild(ART &art, idx_t pos) { D_ASSERT(child_index[pos] != Node::EMPTY_MARKER); return children[child_index[pos]].Unswizzle(art); @@ -71632,12 +75734,16 @@ void Node48::ReplaceChildPointer(idx_t pos, Node *node) { children[child_index[pos]] = node; } -void Node48::InsertChild(Node *&node, uint8_t key_byte, Node *new_child) { +bool Node48::ChildIsInMemory(idx_t pos) { + return children[child_index[pos]] && !children[child_index[pos]].IsSwizzled(); +} + +void Node48::InsertChild(ART &art, Node *&node, uint8_t key_byte, Node *new_child) { auto n = (Node48 *)node; - // Insert new child node into node - if (node->count < 48) { - // Insert element + // insert new child node into node + if (node->count < Node48::GetSize()) { + // still space, just insert the child idx_t pos = n->count; if (n->children[pos]) { // find an empty position in the node list if the current position is occupied @@ -71649,73 +75755,72 @@ void Node48::InsertChild(Node *&node, uint8_t key_byte, Node *new_child) { n->children[pos] = new_child; n->child_index[key_byte] = pos; n->count++; + } else { - // Grow to Node256 + // node is full, grow to Node256 auto new_node = Node256::New(); - for (idx_t i = 0; i < 256; i++) { + art.memory_size += new_node->MemorySize(art, false); + new_node->count = n->count; + new_node->prefix = std::move(n->prefix); + + for (idx_t i = 0; i < Node256::GetSize(); i++) { if (n->child_index[i] != Node::EMPTY_MARKER) { new_node->children[i] = n->children[n->child_index[i]]; n->children[n->child_index[i]] = nullptr; } } - new_node->count = n->count; - new_node->prefix = move(n->prefix); + + D_ASSERT(art.memory_size >= node->MemorySize(art, false)); + art.memory_size -= node->MemorySize(art, false); Node::Delete(node); node = new_node; - Node256::InsertChild(node, key_byte, new_child); + Node256::InsertChild(art, node, key_byte, new_child); } } -void Node48::EraseChild(Node *&node, int pos, ART &art) { +void Node48::EraseChild(ART &art, Node *&node, idx_t pos) { auto n = (Node48 *)(node); + + // adjust the ART size + if (n->ChildIsInMemory(pos)) { + auto child = n->GetChild(art, pos); + D_ASSERT(art.memory_size >= child->MemorySize(art, true)); + art.memory_size -= child->MemorySize(art, true); + } + + // erase the child and decrease the count n->children[n->child_index[pos]].Reset(); n->child_index[pos] = Node::EMPTY_MARKER; n->count--; - if (node->count <= 12) { + + // shrink node to Node16 + if (node->count < NODE_48_SHRINK_THRESHOLD) { + auto new_node = Node16::New(); - new_node->prefix = move(n->prefix); - for (idx_t i = 0; i < 256; i++) { + art.memory_size += new_node->MemorySize(art, false); + new_node->prefix = std::move(n->prefix); + + for (idx_t i = 0; i < Node256::GetSize(); i++) { if (n->child_index[i] != Node::EMPTY_MARKER) { new_node->key[new_node->count] = i; new_node->children[new_node->count++] = n->children[n->child_index[i]]; n->children[n->child_index[i]] = nullptr; } } + + D_ASSERT(art.memory_size >= node->MemorySize(art, false)); + art.memory_size -= node->MemorySize(art, false); Node::Delete(node); node = new_node; } } +} // namespace duckdb -bool Node48::Merge(MergeInfo &info, idx_t depth, Node *&l_parent, idx_t l_pos) { - - Node48 *r_n = (Node48 *)info.r_node; - - for (idx_t i = 0; i < 256; i++) { - if (r_n->child_index[i] != Node::EMPTY_MARKER) { - - auto l_child_pos = info.l_node->GetChildPos(i); - auto key_byte = (uint8_t)i; - if (!Node::MergeAtByte(info, depth, l_child_pos, i, key_byte, l_parent, l_pos)) { - return false; - } - } - } - return true; -} - -idx_t Node48::GetSize() { - return 48; -} -} // namespace duckdb namespace duckdb { -uint32_t Prefix::Size() const { - return size; -} - bool Prefix::IsInlined() const { return size <= PREFIX_INLINE_BYTES; } @@ -71770,6 +75875,10 @@ Prefix::~Prefix() { Destroy(); } +idx_t Prefix::MemorySize() { + return sizeof(*this) + sizeof(uint8_t) * size; +} + void Prefix::Destroy() { if (!IsInlined()) { DeleteArray(value.ptr, size); @@ -71809,6 +75918,7 @@ void Prefix::Overwrite(uint32_t new_size, uint8_t *data) { prefix[i] = data[i]; } DeleteArray(data, new_size); + } else { // new entry would not be inlined // take over the data directly @@ -71818,40 +75928,47 @@ void Prefix::Overwrite(uint32_t new_size, uint8_t *data) { } } -void Prefix::Concatenate(uint8_t key, Prefix &other) { - auto new_length = size + 1 + other.size; +void Prefix::Concatenate(ART &art, uint8_t key, Prefix &other) { + auto new_size = size + 1 + other.size; + art.memory_size += (new_size - size) * sizeof(uint8_t); // have to allocate space in our prefix array - auto new_prefix = AllocateArray(new_length); + auto new_prefix = AllocateArray(new_size); idx_t new_prefix_idx = 0; + // 1) add the to-be deleted node's prefix for (uint32_t i = 0; i < other.size; i++) { new_prefix[new_prefix_idx++] = other[i]; } - // 2) now move the current key as part of the prefix + + // 2) now move the current partial key byte as part of the prefix new_prefix[new_prefix_idx++] = key; + // 3) move the existing prefix (if any) auto prefix = GetPrefixData(); for (uint32_t i = 0; i < size; i++) { new_prefix[new_prefix_idx++] = prefix[i]; } - Overwrite(new_length, new_prefix); + Overwrite(new_size, new_prefix); } -uint8_t Prefix::Reduce(uint32_t n) { +uint8_t Prefix::Reduce(ART &art, uint32_t n) { auto new_size = size - n - 1; + D_ASSERT(art.memory_size >= (size - new_size) * sizeof(uint8_t)); + art.memory_size -= (size - new_size) * sizeof(uint8_t); auto prefix = GetPrefixData(); - auto key = prefix[n]; + auto partial_key = prefix[n]; + if (new_size == 0) { Destroy(); size = 0; - return key; + return partial_key; } auto new_prefix = AllocateArray(new_size); for (idx_t i = 0; i < new_size; i++) { new_prefix[i] = prefix[i + n + 1]; } Overwrite(new_size, new_prefix); - return key; + return partial_key; } void Prefix::Serialize(duckdb::MetaBlockWriter &writer) { @@ -71867,7 +75984,7 @@ void Prefix::Deserialize(duckdb::MetaBlockReader &reader) { reader.ReadData(prefix, size); } -uint32_t Prefix::KeyMismatchPosition(Key &key, uint64_t depth) { +uint32_t Prefix::KeyMismatchPosition(Key &key, uint32_t depth) { uint64_t pos; auto prefix = GetPrefixData(); for (pos = 0; pos < size; pos++) { @@ -71892,6 +76009,8 @@ uint32_t Prefix::MismatchPosition(Prefix &other) { } // namespace duckdb + + namespace duckdb { SwizzleablePointer::~SwizzleablePointer() { if (pointer) { @@ -71903,8 +76022,8 @@ SwizzleablePointer::~SwizzleablePointer() { SwizzleablePointer::SwizzleablePointer(duckdb::MetaBlockReader &reader) { idx_t block_id = reader.Read(); - idx_t offset = reader.Read(); - if (block_id == DConstants::INVALID_INDEX || offset == DConstants::INVALID_INDEX) { + uint32_t offset = reader.Read(); + if (block_id == DConstants::INVALID_INDEX || offset == (uint32_t)DConstants::INVALID_INDEX) { pointer = 0; return; } @@ -71970,6 +76089,7 @@ Node *SwizzleablePointer::Unswizzle(ART &art) { // first we unset the bae auto block_info = GetSwizzledBlockInfo(); *this = Node::Deserialize(art, block_info.block_id, block_info.offset); + art.Verify(); } return (Node *)pointer; } @@ -72100,9 +76220,6 @@ class JoinHashTable { idx_t ScanInnerJoin(DataChunk &keys, SelectionVector &result_vector); - idx_t ResolvePredicates(DataChunk &keys, SelectionVector &match_sel); - idx_t ResolvePredicates(DataChunk &keys, SelectionVector &match_sel, SelectionVector &no_match_sel); - public: void InitializeSelectionVector(const SelectionVector *¤t_sel); void AdvancePointers(); @@ -72311,8 +76428,6 @@ class JoinHashTable { //! Swizzle the blocks in this HT (moves from block_collection and string_heap to swizzled_...) void SwizzleBlocks(); - //! Unswizzle the blocks in this HT (moves from swizzled_... to block_collection and string_heap) - void UnswizzleBlocks(); //! Computes partition sizes and number of radix bits (called before scheduling partition tasks) void ComputePartitionSizes(ClientConfig &config, vector> &local_hts, idx_t max_ht_size); @@ -72363,9 +76478,9 @@ using ProbeSpillLocalState = JoinHashTable::ProbeSpillLocalAppendState; JoinHashTable::JoinHashTable(BufferManager &buffer_manager, const vector &conditions, vector btypes, JoinType type) - : buffer_manager(buffer_manager), conditions(conditions), build_types(move(btypes)), entry_size(0), tuple_size(0), - vfound(Value::BOOLEAN(false)), join_type(type), finalized(false), has_null(false), external(false), radix_bits(4), - tuples_per_round(0), partition_start(0), partition_end(0) { + : buffer_manager(buffer_manager), conditions(conditions), build_types(std::move(btypes)), entry_size(0), + tuple_size(0), vfound(Value::BOOLEAN(false)), join_type(type), finalized(false), has_null(false), external(false), + radix_bits(4), tuples_per_round(0), partition_start(0), partition_end(0) { for (auto &condition : conditions) { D_ASSERT(condition.left->return_type == condition.right->return_type); auto type = condition.left->return_type; @@ -72438,9 +76553,9 @@ void JoinHashTable::Merge(JoinHashTable &other) { D_ASSERT(partition_string_heaps.empty()); // Move partitions to this HT for (idx_t p = 0; p < other.partition_block_collections.size(); p++) { - partition_block_collections.push_back(move(other.partition_block_collections[p])); + partition_block_collections.push_back(std::move(other.partition_block_collections[p])); if (!layout.AllConstant()) { - partition_string_heaps.push_back(move(other.partition_string_heaps[p])); + partition_string_heaps.push_back(std::move(other.partition_string_heaps[p])); } } return; @@ -72599,7 +76714,7 @@ void JoinHashTable::Build(DataChunk &keys, DataChunk &payload) { // serialize the keys to the key locations for (idx_t i = 0; i < keys.ColumnCount(); i++) { source_chunk.data[i].Reference(keys.data[i]); - source_data.emplace_back(move(key_data[i])); + source_data.emplace_back(std::move(key_data[i])); } // now serialize the payload D_ASSERT(build_types.size() == payload.ColumnCount()); @@ -72607,21 +76722,21 @@ void JoinHashTable::Build(DataChunk &keys, DataChunk &payload) { source_chunk.data[source_data.size()].Reference(payload.data[i]); UnifiedVectorFormat pdata; payload.data[i].ToUnifiedFormat(payload.size(), pdata); - source_data.emplace_back(move(pdata)); + source_data.emplace_back(std::move(pdata)); } if (IsRightOuterJoin(join_type)) { // for FULL/RIGHT OUTER joins initialize the "found" boolean to false source_chunk.data[source_data.size()].Reference(vfound); UnifiedVectorFormat fdata; vfound.ToUnifiedFormat(keys.size(), fdata); - source_data.emplace_back(move(fdata)); + source_data.emplace_back(std::move(fdata)); } // serialise the hashes at the end source_chunk.data[source_data.size()].Reference(hash_values); UnifiedVectorFormat hdata; hash_values.ToUnifiedFormat(keys.size(), hdata); - source_data.emplace_back(move(hdata)); + source_data.emplace_back(std::move(hdata)); source_chunk.SetCardinality(keys); @@ -72690,22 +76805,37 @@ void JoinHashTable::Finalize(idx_t block_idx_start, idx_t block_idx_end, bool pa // Pointer table should be allocated D_ASSERT(hash_map.get()); + const auto unswizzle = external && !layout.AllConstant(); vector local_pinned_handles; Vector hashes(LogicalType::HASH); auto hash_data = FlatVector::GetData(hashes); data_ptr_t key_locations[STANDARD_VECTOR_SIZE]; // now construct the actual hash table; scan the nodes - // as we can the nodes we pin all the blocks of the HT and keep them pinned until the HT is destroyed + // as we scan the nodes we pin all the blocks of the HT and keep them pinned until the HT is destroyed // this is so that we can keep pointers around to the blocks for (idx_t block_idx = block_idx_start; block_idx < block_idx_end; block_idx++) { auto &block = block_collection->blocks[block_idx]; auto handle = buffer_manager.Pin(block->block); data_ptr_t dataptr = handle.Ptr(); + + data_ptr_t heap_ptr = nullptr; + if (unswizzle) { + auto &heap_block = string_heap->blocks[block_idx]; + auto heap_handle = buffer_manager.Pin(heap_block->block); + heap_ptr = heap_handle.Ptr(); + local_pinned_handles.push_back(std::move(heap_handle)); + } + idx_t entry = 0; while (entry < block->count) { - // fetch the next vector of entries from the blocks idx_t next = MinValue(STANDARD_VECTOR_SIZE, block->count - entry); + + if (unswizzle) { + RowOperations::UnswizzlePointers(layout, dataptr, heap_ptr, next); + } + + // fetch the next vector of entries from the blocks for (idx_t i = 0; i < next; i++) { hash_data[i] = Load((data_ptr_t)(dataptr + pointer_offset)); key_locations[i] = dataptr; @@ -72716,12 +76846,12 @@ void JoinHashTable::Finalize(idx_t block_idx_start, idx_t block_idx_end, bool pa entry += next; } - local_pinned_handles.push_back(move(handle)); + local_pinned_handles.push_back(std::move(handle)); } lock_guard lock(pinned_handles_lock); for (auto &local_pinned_handle : local_pinned_handles) { - pinned_handles.push_back(move(local_pinned_handle)); + pinned_handles.push_back(std::move(local_pinned_handle)); } } @@ -72774,7 +76904,6 @@ void ScanStructure::Next(DataChunk &keys, DataChunk &left, DataChunk &result) { if (finished) { return; } - switch (ht.join_type) { case JoinType::INNER: case JoinType::RIGHT: @@ -73153,10 +77282,10 @@ void ScanStructure::NextSingleJoin(DataChunk &keys, DataChunk &input, DataChunk for (idx_t i = 0; i < ht.build_types.size(); i++) { auto &vector = result.data[input.ColumnCount() + i]; // set NULL entries for every entry that was not found - auto &mask = FlatVector::Validity(vector); - mask.SetAllInvalid(input.size()); - for (idx_t j = 0; j < result_count; j++) { - mask.SetValid(result_sel.get_index(j)); + for (idx_t j = 0; j < input.size(); j++) { + if (!found_match[j]) { + FlatVector::SetNull(vector, j, true); + } } // for the remaining values we fetch the values GatherResult(vector, result_sel, result_sel, result_count, i + ht.condition_types.size()); @@ -73331,45 +77460,6 @@ void JoinHashTable::SwizzleBlocks() { string_heap->Clear(); } -void JoinHashTable::UnswizzleBlocks() { - auto &blocks = swizzled_block_collection->blocks; - auto &heap_blocks = swizzled_string_heap->blocks; -#ifdef DEBUG - if (!layout.AllConstant()) { - D_ASSERT(blocks.size() == heap_blocks.size()); - D_ASSERT(swizzled_block_collection->count == swizzled_string_heap->count); - } -#endif - - for (idx_t block_idx = 0; block_idx < blocks.size(); block_idx++) { - auto &data_block = blocks[block_idx]; - - if (!layout.AllConstant()) { - auto block_handle = buffer_manager.Pin(data_block->block); - - auto &heap_block = heap_blocks[block_idx]; - D_ASSERT(data_block->count == heap_block->count); - auto heap_handle = buffer_manager.Pin(heap_block->block); - - // Unswizzle and move - RowOperations::UnswizzlePointers(layout, block_handle.Ptr(), heap_handle.Ptr(), data_block->count); - string_heap->blocks.push_back(move(heap_block)); - string_heap->pinned_blocks.push_back(move(heap_handle)); - } - - // Fixed size stuff can just be moved - block_collection->blocks.push_back(move(data_block)); - } - - // Update counts and clean up - block_collection->count = swizzled_block_collection->count; - string_heap->count = swizzled_string_heap->count; - swizzled_block_collection->Clear(); - swizzled_string_heap->Clear(); - - D_ASSERT(SwizzledCount() == 0); -} - void JoinHashTable::ComputePartitionSizes(ClientConfig &config, vector> &local_hts, idx_t max_ht_size) { external = true; @@ -73389,12 +77479,12 @@ void JoinHashTable::ComputePartitionSizes(ClientConfig &config, vector((total_count + 2) / 3, tuples_per_round); } // Set the number of radix bits (minimum 4, maximum 8) @@ -73479,7 +77569,9 @@ bool JoinHashTable::PrepareExternalFinalize() { // Unswizzle them D_ASSERT(Count() == 0); - UnswizzleBlocks(); + // Move swizzled data to regular data (will be unswizzled in 'Finalize()') + block_collection->Merge(*swizzled_block_collection); + string_heap->Merge(*swizzled_string_heap); D_ASSERT(count == Count()); return true; @@ -73605,7 +77697,7 @@ void ProbeSpill::Finalize() { global_spill_collection = make_unique(BufferManager::GetBufferManager(context), probe_types); } else { - global_spill_collection = move(local_spill_collections[0]); + global_spill_collection = std::move(local_spill_collections[0]); for (idx_t i = 1; i < local_spill_collections.size(); i++) { global_spill_collection->Combine(*local_spill_collections[i]); } @@ -73624,7 +77716,7 @@ void ProbeSpill::PrepareNextProbe() { make_unique(BufferManager::GetBufferManager(context), probe_types); } else { // Move specific partitions to the global spill collection - global_spill_collection = move(partitions[ht.partition_start]); + global_spill_collection = std::move(partitions[ht.partition_start]); for (idx_t i = ht.partition_start + 1; i < ht.partition_end; i++) { global_spill_collection->Combine(*partitions[i]); } @@ -74021,7 +78113,7 @@ namespace duckdb { AggregateObject::AggregateObject(AggregateFunction function, FunctionData *bind_data, idx_t child_count, idx_t payload_size, AggregateType aggr_type, PhysicalType return_type, Expression *filter) - : function(move(function)), bind_data(bind_data), child_count(child_count), payload_size(payload_size), + : function(std::move(function)), bind_data(bind_data), child_count(child_count), payload_size(payload_size), aggr_type(aggr_type), return_type(return_type), filter(filter) { } @@ -74093,12 +78185,13 @@ AggregateFilterData &AggregateFilterDataSet::GetFilterData(idx_t aggr_idx) { + namespace duckdb { //! Shared information about a collection of distinct aggregates DistinctAggregateCollectionInfo::DistinctAggregateCollectionInfo(const vector> &aggregates, vector indices) - : indices(move(indices)), aggregates(aggregates) { + : indices(std::move(indices)), aggregates(aggregates) { table_count = CreateTableIndexMap(); const idx_t aggregate_count = aggregates.size(); @@ -74282,7 +78375,7 @@ DistinctAggregateCollectionInfo::Create(vector> &aggregat if (indices.empty()) { return nullptr; } - return make_unique(aggregates, move(indices)); + return make_unique(aggregates, std::move(indices)); } bool DistinctAggregateData::IsDistinct(idx_t index) const { @@ -74318,7 +78411,7 @@ const vector> &GroupedAggregateData::GetGroupingFunctions() const void GroupedAggregateData::InitializeGroupby(vector> groups, vector> expressions, vector> grouping_functions) { - InitializeGroupbyGroups(move(groups)); + InitializeGroupbyGroups(std::move(groups)); vector payload_types_filters; SetGroupingFunctions(grouping_functions); @@ -74341,7 +78434,7 @@ void GroupedAggregateData::InitializeGroupby(vector> grou if (!aggr.function.combine) { throw InternalException("Aggregate function %s is missing a combine method", aggr.function.name); } - aggregates.push_back(move(expr)); + aggregates.push_back(std::move(expr)); } for (const auto &pay_filters : payload_types_filters) { payload_types.push_back(pay_filters); @@ -74388,13 +78481,13 @@ void GroupedAggregateData::InitializeGroupbyGroups(vector for (auto &expr : groups) { group_types.push_back(expr->return_type); } - this->groups = move(groups); + this->groups = std::move(groups); } void GroupedAggregateData::SetGroupingFunctions(vector> &functions) { grouping_functions.reserve(functions.size()); for (idx_t i = 0; i < functions.size(); i++) { - grouping_functions.push_back(move(functions[i])); + grouping_functions.push_back(std::move(functions[i])); } } @@ -74635,13 +78728,14 @@ bool PhysicalHashAggregate::CanSkipRegularSink() const { PhysicalHashAggregate::PhysicalHashAggregate(ClientContext &context, vector types, vector> expressions, idx_t estimated_cardinality) - : PhysicalHashAggregate(context, move(types), move(expressions), {}, estimated_cardinality) { + : PhysicalHashAggregate(context, std::move(types), std::move(expressions), {}, estimated_cardinality) { } PhysicalHashAggregate::PhysicalHashAggregate(ClientContext &context, vector types, vector> expressions, vector> groups_p, idx_t estimated_cardinality) - : PhysicalHashAggregate(context, move(types), move(expressions), move(groups_p), {}, {}, estimated_cardinality) { + : PhysicalHashAggregate(context, std::move(types), std::move(expressions), std::move(groups_p), {}, {}, + estimated_cardinality) { } PhysicalHashAggregate::PhysicalHashAggregate(ClientContext &context, vector types, @@ -74649,8 +78743,8 @@ PhysicalHashAggregate::PhysicalHashAggregate(ClientContext &context, vector> groups_p, vector grouping_sets_p, vector> grouping_functions_p, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::HASH_GROUP_BY, move(types), estimated_cardinality), - grouping_sets(move(grouping_sets_p)) { + : PhysicalOperator(PhysicalOperatorType::HASH_GROUP_BY, std::move(types), estimated_cardinality), + grouping_sets(std::move(grouping_sets_p)) { // get a list of all aggregates to be computed const idx_t group_count = groups_p.size(); if (grouping_sets.empty()) { @@ -74658,11 +78752,12 @@ PhysicalHashAggregate::PhysicalHashAggregate(ClientContext &context, vectorexecutor, shared_from_this(), *grouping_gstate.table_state, tasks); } D_ASSERT(!tasks.empty()); - SetTasks(move(tasks)); + SetTasks(std::move(tasks)); } }; @@ -75002,8 +79097,8 @@ class HashAggregateFinalizeTask : public ExecutorTask { public: HashAggregateFinalizeTask(Pipeline &pipeline, shared_ptr event_p, HashAggregateGlobalState &state_p, ClientContext &context, const PhysicalHashAggregate &op) - : ExecutorTask(pipeline.executor), pipeline(pipeline), event(move(event_p)), gstate(state_p), context(context), - op(op) { + : ExecutorTask(pipeline.executor), pipeline(pipeline), event(std::move(event_p)), gstate(state_p), + context(context), op(op) { } TaskExecutionResult ExecuteTask(TaskExecutionMode mode) override { @@ -75038,7 +79133,7 @@ class HashAggregateFinalizeEvent : public BasePipelineEvent { vector> tasks; tasks.push_back(make_unique(*pipeline, shared_from_this(), gstate, context, op)); D_ASSERT(!tasks.empty()); - SetTasks(move(tasks)); + SetTasks(std::move(tasks)); } }; @@ -75049,8 +79144,8 @@ class HashDistinctAggregateFinalizeTask : public ExecutorTask { HashDistinctAggregateFinalizeTask(Pipeline &pipeline, shared_ptr event_p, HashAggregateGlobalState &state_p, ClientContext &context, const PhysicalHashAggregate &op, vector>> &global_sources_p) - : ExecutorTask(pipeline.executor), pipeline(pipeline), event(move(event_p)), gstate(state_p), context(context), - op(op), global_sources(global_sources_p) { + : ExecutorTask(pipeline.executor), pipeline(pipeline), event(std::move(event_p)), gstate(state_p), + context(context), op(op), global_sources(global_sources_p) { } void AggregateDistinctGrouping(DistinctAggregateCollectionInfo &info, @@ -75190,13 +79285,13 @@ class HashDistinctAggregateFinalizeEvent : public BasePipelineEvent { context, op, global_sources)); } D_ASSERT(!tasks.empty()); - SetTasks(move(tasks)); + SetTasks(std::move(tasks)); } void FinishEvent() override { //! Now that everything is added to the main ht, we can actually finalize auto new_event = make_shared(op, gstate, pipeline.get(), context); - this->InsertEvent(move(new_event)); + this->InsertEvent(std::move(new_event)); } private: @@ -75224,7 +79319,7 @@ class HashDistinctAggregateFinalizeEvent : public BasePipelineEvent { auto &radix_table_p = data.radix_tables[table_idx]; aggregate_sources.push_back(radix_table_p->GetGlobalSourceState(context)); } - grouping_sources.push_back(move(aggregate_sources)); + grouping_sources.push_back(std::move(aggregate_sources)); } return grouping_sources; } @@ -75260,13 +79355,13 @@ class HashDistinctCombineFinalizeEvent : public BasePipelineEvent { } D_ASSERT(!tasks.empty()); - SetTasks(move(tasks)); + SetTasks(std::move(tasks)); } void FinishEvent() override { //! Now that all tables are combined, it's time to do the distinct aggregations auto new_event = make_shared(op, gstate, *pipeline, client); - this->InsertEvent(move(new_event)); + this->InsertEvent(std::move(new_event)); } }; @@ -75298,12 +79393,12 @@ SinkFinalizeType PhysicalHashAggregate::FinalizeDistinct(Pipeline &pipeline, Eve if (any_partitioned) { // If any of the groupings are partitioned then we first need to combine those, then aggregate auto new_event = make_shared(*this, gstate, pipeline, context); - event.InsertEvent(move(new_event)); + event.InsertEvent(std::move(new_event)); } else { // Hashtables aren't partitioned, they dont need to be joined first // so we can already compute the aggregate auto new_event = make_shared(*this, gstate, pipeline, context); - event.InsertEvent(move(new_event)); + event.InsertEvent(std::move(new_event)); } return SinkFinalizeType::READY; } @@ -75331,7 +79426,7 @@ SinkFinalizeType PhysicalHashAggregate::FinalizeInternal(Pipeline &pipeline, Eve } if (any_partitioned) { auto new_event = make_shared(*this, gstate, &pipeline); - event.InsertEvent(move(new_event)); + event.InsertEvent(std::move(new_event)); } return SinkFinalizeType::READY; } @@ -75683,15 +79778,15 @@ PhysicalPerfectHashAggregate::PhysicalPerfectHashAggregate(ClientContext &contex vector> groups_p, vector> group_stats, vector required_bits_p, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::PERFECT_HASH_GROUP_BY, move(types_p), estimated_cardinality), - groups(move(groups_p)), aggregates(move(aggregates_p)), required_bits(move(required_bits_p)) { + : PhysicalOperator(PhysicalOperatorType::PERFECT_HASH_GROUP_BY, std::move(types_p), estimated_cardinality), + groups(std::move(groups_p)), aggregates(std::move(aggregates_p)), required_bits(std::move(required_bits_p)) { D_ASSERT(groups.size() == group_stats.size()); group_minima.reserve(group_stats.size()); for (auto &stats : group_stats) { D_ASSERT(stats); auto &nstats = (NumericStatistics &)*stats; D_ASSERT(!nstats.min.IsNull()); - group_minima.push_back(move(nstats.min)); + group_minima.push_back(std::move(nstats.min)); } for (auto &expr : groups) { group_types.push_back(expr->return_type); @@ -75937,7 +80032,7 @@ namespace duckdb { PhysicalStreamingWindow::PhysicalStreamingWindow(vector types, vector> select_list, idx_t estimated_cardinality, PhysicalOperatorType type) - : PhysicalOperator(type, move(types), estimated_cardinality), select_list(move(select_list)) { + : PhysicalOperator(type, std::move(types), estimated_cardinality), select_list(std::move(select_list)) { } class StreamingWindowGlobalState : public GlobalOperatorState { @@ -76229,8 +80324,8 @@ namespace duckdb { PhysicalUngroupedAggregate::PhysicalUngroupedAggregate(vector types, vector> expressions, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::UNGROUPED_AGGREGATE, move(types), estimated_cardinality), - aggregates(move(expressions)) { + : PhysicalOperator(PhysicalOperatorType::UNGROUPED_AGGREGATE, std::move(types), estimated_cardinality), + aggregates(std::move(expressions)) { distinct_collection_info = DistinctAggregateCollectionInfo::Create(aggregates); if (!distinct_collection_info) { @@ -76249,7 +80344,7 @@ struct AggregateState { auto &aggr = (BoundAggregateExpression &)*aggregate; auto state = unique_ptr(new data_t[aggr.function.state_size()]); aggr.function.initialize(state.get()); - aggregates.push_back(move(state)); + aggregates.push_back(std::move(state)); destructors.push_back(aggr.function.destructor); #ifdef DEBUG counts.push_back(0); @@ -76270,8 +80365,8 @@ struct AggregateState { } void Move(AggregateState &other) { - other.aggregates = move(aggregates); - other.destructors = move(destructors); + other.aggregates = std::move(aggregates); + other.destructors = std::move(destructors); } //! The aggregate values @@ -76546,7 +80641,7 @@ class UngroupedDistinctAggregateFinalizeTask : public ExecutorTask { UngroupedDistinctAggregateFinalizeTask(Executor &executor, shared_ptr event_p, UngroupedAggregateGlobalState &state_p, ClientContext &context, const PhysicalUngroupedAggregate &op) - : ExecutorTask(executor), event(move(event_p)), gstate(state_p), context(context), op(op) { + : ExecutorTask(executor), event(std::move(event_p)), gstate(state_p), context(context), op(op) { } void AggregateDistinct() { @@ -76649,7 +80744,7 @@ class UngroupedDistinctAggregateFinalizeEvent : public BasePipelineEvent { tasks.push_back(make_unique(pipeline->executor, shared_from_this(), gstate, context, op)); D_ASSERT(!tasks.empty()); - SetTasks(move(tasks)); + SetTasks(std::move(tasks)); } }; @@ -76675,13 +80770,13 @@ class UngroupedDistinctCombineFinalizeEvent : public BasePipelineEvent { *distinct_state.radix_states[table_idx], tasks); } D_ASSERT(!tasks.empty()); - SetTasks(move(tasks)); + SetTasks(std::move(tasks)); } void FinishEvent() override { //! Now that all tables are combined, it's time to do the distinct aggregations auto new_event = make_shared(op, gstate, *pipeline, client); - this->InsertEvent(move(new_event)); + this->InsertEvent(std::move(new_event)); } }; @@ -76702,12 +80797,12 @@ SinkFinalizeType PhysicalUngroupedAggregate::FinalizeDistinct(Pipeline &pipeline } if (any_partitioned) { auto new_event = make_shared(*this, gstate, pipeline, context); - event.InsertEvent(move(new_event)); + event.InsertEvent(std::move(new_event)); } else { //! Hashtables aren't partitioned, they dont need to be joined first //! So we can compute the aggregate already auto new_event = make_shared(*this, gstate, pipeline, context); - event.InsertEvent(move(new_event)); + event.InsertEvent(std::move(new_event)); } return SinkFinalizeType::READY; } @@ -76879,6 +80974,7 @@ class PhysicalWindow : public PhysicalOperator { + //===----------------------------------------------------------------------===// // DuckDB // @@ -76972,14 +81068,13 @@ class WindowSegmentTree { + #include #include #include namespace duckdb { -using counts_t = std::vector; - class WindowGlobalHashGroup { public: using GlobalSortStatePtr = unique_ptr; @@ -76988,8 +81083,8 @@ class WindowGlobalHashGroup { using Types = vector; WindowGlobalHashGroup(BufferManager &buffer_manager, const Orders &partitions, const Orders &orders, - const Types &payload_types, idx_t max_mem, bool external) - : memory_per_thread(max_mem), count(0) { + const Types &payload_types, bool external) + : count(0) { RowLayout payload_layout; payload_layout.Initialize(payload_types); @@ -76999,17 +81094,8 @@ class WindowGlobalHashGroup { partition_layout = global_sort->sort_layout.GetPrefixComparisonLayout(partitions.size()); } - void Combine(LocalSortState &local_sort) { - global_sort->AddLocalState(local_sort); - } - - void PrepareMergePhase() { - global_sort->PrepareMergePhase(); - } - void ComputeMasks(ValidityMask &partition_mask, ValidityMask &order_mask); - const idx_t memory_per_thread; GlobalSortStatePtr global_sort; atomic count; @@ -77055,19 +81141,19 @@ class WindowGlobalSinkState : public GlobalSinkState { using Orders = vector; using Types = vector; + using GroupingPartition = unique_ptr; + using GroupingAppend = unique_ptr; + WindowGlobalSinkState(const PhysicalWindow &op_p, ClientContext &context) : op(op_p), context(context), buffer_manager(BufferManager::GetBufferManager(context)), - allocator(Allocator::Get(context)), - partition_info((idx_t)TaskScheduler::GetScheduler(context).NumberOfThreads()), next_sort(0), - memory_per_thread(0), count(0), mode(DBConfig::GetConfig(context).options.window_mode) { + allocator(Allocator::Get(context)), payload_types(op.children[0]->types), memory_per_thread(0), count(0), + mode(DBConfig::GetConfig(context).options.window_mode) { D_ASSERT(op.select_list[0]->GetExpressionClass() == ExpressionClass::BOUND_WINDOW); auto wexpr = reinterpret_cast(op.select_list[0].get()); // we sort by both 1) partition by expression list and 2) order by expressions - payload_types = op.children[0]->types; - - partition_cols = wexpr->partitions.size(); + const auto partition_cols = wexpr->partitions.size(); for (idx_t prt_idx = 0; prt_idx < partition_cols; prt_idx++) { auto &pexpr = wexpr->partitions[prt_idx]; @@ -77086,77 +81172,37 @@ class WindowGlobalSinkState : public GlobalSinkState { memory_per_thread = op.GetMaxThreadMemory(context); external = ClientConfig::GetConfig(context).force_external; - } - WindowGlobalHashGroup *GetUngrouped() { - lock_guard guard(lock); + if (!orders.empty()) { + grouping_types = payload_types; + grouping_types.push_back(LogicalType::HASH); - if (!ungrouped) { - ungrouped = make_unique(buffer_manager, partitions, orders, payload_types, - memory_per_thread, external); + ResizeGroupingData(op.estimated_cardinality); } - - return ungrouped.get(); } - //! Switch to hash grouping - size_t Group() { - lock_guard guard(lock); - if (hash_groups.size() < partition_info.n_partitions) { - hash_groups.resize(partition_info.n_partitions); - } + void UpdateLocalPartition(GroupingPartition &local_partition, GroupingAppend &local_append); + void CombineLocalPartition(GroupingPartition &local_partition, GroupingAppend &local_append); - return hash_groups.size(); - } - - idx_t GroupCount() const { - return std::accumulate( - hash_groups.begin(), hash_groups.end(), 0, - [&](const idx_t &n, const HashGroupPtr &group) { return n + (group ? idx_t(group->count) : 0); }); - } - - WindowGlobalHashGroup *GetHashGroup(idx_t group) { - lock_guard guard(lock); - D_ASSERT(group < hash_groups.size()); - auto &hash_group = hash_groups[group]; - if (!hash_group) { - const auto maxmem = memory_per_thread / partition_info.n_partitions; - hash_group = - make_unique(buffer_manager, partitions, orders, payload_types, maxmem, external); - } - - return hash_group.get(); - } - - void Finalize(); - - size_t GetNextSortGroup() { - for (auto group = next_sort++; group < hash_groups.size(); group = next_sort++) { - // Only non-empty groups exist. - if (hash_groups[group]) { - return group; - } - } - - return hash_groups.size(); - } + void BuildSortState(ColumnDataCollection &group_data, WindowGlobalHashGroup &global_sort); const PhysicalWindow &op; ClientContext &context; BufferManager &buffer_manager; Allocator &allocator; - size_t partition_cols; - const RadixPartitionInfo partition_info; mutex lock; - // Sorting + // OVER(PARTITION BY...) (hash grouping) + unique_ptr grouping_data; + //! Payload plus hash column + Types grouping_types; + + // OVER(...) (sorting) Orders partitions; Orders orders; - Types payload_types; - HashGroupPtr ungrouped; + const Types payload_types; vector hash_groups; bool external; - atomic next_sort; // OVER() (no sorting) unique_ptr rows; @@ -77166,253 +81212,250 @@ class WindowGlobalSinkState : public GlobalSinkState { idx_t memory_per_thread; atomic count; WindowAggregationMode mode; -}; -// Per-thread hash group -class WindowLocalHashGroup { -public: - using LocalSortStatePtr = unique_ptr; - using DataChunkPtr = unique_ptr; +private: + void ResizeGroupingData(idx_t cardinality); + void SyncLocalPartition(GroupingPartition &local_partition, GroupingAppend &local_append); +}; + +void WindowGlobalSinkState::ResizeGroupingData(idx_t cardinality) { + // Is the average partition size too large? + const idx_t partition_size = STANDARD_ROW_GROUPS_SIZE; + const auto bits = grouping_data ? grouping_data->GetRadixBits() : 0; + auto new_bits = bits ? bits : 4; + while (new_bits < 10 && (cardinality / RadixPartitioning::NumberOfPartitions(new_bits)) > partition_size) { + ++new_bits; + } + + // Repartition the grouping data + if (new_bits != bits) { + const auto hash_col_idx = payload_types.size(); + auto new_grouping_data = + make_unique(context, grouping_types, new_bits, hash_col_idx); + + // We have to append to a shared copy for some reason + if (grouping_data) { + auto new_shared = new_grouping_data->CreateShared(); + PartitionedColumnDataAppendState shared_append; + new_shared->InitializeAppendState(shared_append); + + auto &partitions = grouping_data->GetPartitions(); + for (auto &partition : partitions) { + ColumnDataScanState scanner; + partition->InitializeScan(scanner); + + DataChunk scan_chunk; + partition->InitializeScanChunk(scan_chunk); + for (scan_chunk.Reset(); partition->Scan(scanner, scan_chunk); scan_chunk.Reset()) { + new_shared->Append(shared_append, scan_chunk); + } + } + new_shared->FlushAppendState(shared_append); + new_grouping_data->Combine(*new_shared); + } + + grouping_data = std::move(new_grouping_data); + } +} - explicit WindowLocalHashGroup(WindowGlobalHashGroup &global_group_p) : global_group(global_group_p), count(0) { +void WindowGlobalSinkState::SyncLocalPartition(GroupingPartition &local_partition, GroupingAppend &local_append) { + // We are done if the local_partition is right sized. + auto local_radix = (RadixPartitionedColumnData *)local_partition.get(); + if (local_radix->GetRadixBits() == grouping_data->GetRadixBits()) { + return; } - bool SinkChunk(DataChunk &sort_chunk, DataChunk &payload_chunk); - void Combine(); + // If the local partition is now too small, flush it and reallocate + auto new_partition = grouping_data->CreateShared(); + auto new_append = make_unique(); + new_partition->InitializeAppendState(*new_append); - WindowGlobalHashGroup &global_group; - LocalSortStatePtr local_sort; - idx_t count; -}; + local_partition->FlushAppendState(*local_append); + auto &local_groups = local_partition->GetPartitions(); + for (auto &local_group : local_groups) { + ColumnDataScanState scanner; + local_group->InitializeScan(scanner); -bool WindowLocalHashGroup::SinkChunk(DataChunk &sort_buffer, DataChunk &input_chunk) { - D_ASSERT(sort_buffer.size() == input_chunk.size()); - count += input_chunk.size(); - auto &global_sort = *global_group.global_sort; - if (!local_sort) { - local_sort = make_unique(); - local_sort->Initialize(global_sort, global_sort.buffer_manager); + DataChunk scan_chunk; + local_group->InitializeScanChunk(scan_chunk); + for (scan_chunk.Reset(); local_group->Scan(scanner, scan_chunk); scan_chunk.Reset()) { + new_partition->Append(*new_append, scan_chunk); + } } - local_sort->SinkChunk(sort_buffer, input_chunk); + // The append state has stale pointers to the old local partition, so nuke it from orbit. + new_partition->FlushAppendState(*new_append); + + local_partition = std::move(new_partition); + local_append = make_unique(); + local_partition->InitializeAppendState(*local_append); +} + +void WindowGlobalSinkState::UpdateLocalPartition(GroupingPartition &local_partition, GroupingAppend &local_append) { + // Make sure grouping_data doesn't change under us. + lock_guard guard(lock); - if (local_sort->SizeInBytes() >= global_group.memory_per_thread) { - local_sort->Sort(global_sort, true); + if (!local_partition) { + local_partition = grouping_data->CreateShared(); + local_append = make_unique(); + local_partition->InitializeAppendState(*local_append); + return; + } + + // Grow the groups if they are too big + ResizeGroupingData(count); + + // Sync local partition to have the same bit count + SyncLocalPartition(local_partition, local_append); +} + +void WindowGlobalSinkState::CombineLocalPartition(GroupingPartition &local_partition, GroupingAppend &local_append) { + if (!local_partition) { + return; } + local_partition->FlushAppendState(*local_append); - return (local_sort->SizeInBytes() >= global_group.memory_per_thread); + // Make sure grouping_data doesn't change under us. + // Combine has an internal mutex, so this is single-threaded anyway. + lock_guard guard(lock); + SyncLocalPartition(local_partition, local_append); + grouping_data->Combine(*local_partition); } -void WindowLocalHashGroup::Combine() { - if (local_sort) { - global_group.Combine(*local_sort); - global_group.count += count; - local_sort.reset(); +void WindowGlobalSinkState::BuildSortState(ColumnDataCollection &group_data, WindowGlobalHashGroup &hash_group) { + auto &global_sort = *hash_group.global_sort; + + // Set up the sort expression computation. + vector sort_types; + ExpressionExecutor executor(context); + for (auto &order : orders) { + auto &oexpr = order.expression; + sort_types.emplace_back(oexpr->return_type); + executor.AddExpression(*oexpr); + } + DataChunk sort_chunk; + sort_chunk.Initialize(allocator, sort_types); + + // Copy the data from the group into the sort code. + LocalSortState local_sort; + local_sort.Initialize(global_sort, global_sort.buffer_manager); + + // Strip hash column + DataChunk payload_chunk; + payload_chunk.Initialize(allocator, payload_types); + + vector column_ids; + column_ids.reserve(payload_types.size()); + for (column_t i = 0; i < payload_types.size(); ++i) { + column_ids.emplace_back(i); + } + ColumnDataConsumer scanner(group_data, column_ids); + ColumnDataConsumerScanState chunk_state; + chunk_state.current_chunk_state.properties = ColumnDataScanProperties::ALLOW_ZERO_COPY; + scanner.InitializeScan(); + for (auto chunk_idx = scanner.ChunkCount(); chunk_idx-- > 0;) { + if (!scanner.AssignChunk(chunk_state)) { + break; + } + scanner.ScanChunk(chunk_state, payload_chunk); + + sort_chunk.Reset(); + executor.Execute(payload_chunk, sort_chunk); + + local_sort.SinkChunk(sort_chunk, payload_chunk); + if (local_sort.SizeInBytes() > memory_per_thread) { + local_sort.Sort(global_sort, true); + } + scanner.FinishChunk(chunk_state); } + + global_sort.AddLocalState(local_sort); + + hash_group.count += group_data.Count(); } // Per-thread sink state class WindowLocalSinkState : public LocalSinkState { public: - using LocalHashGroupPtr = unique_ptr; - WindowLocalSinkState(ClientContext &context, const PhysicalWindow &op_p) - : op(op_p), executor(context), count(0), hash_vector(LogicalTypeId::UBIGINT), sel(STANDARD_VECTOR_SIZE) { - + : op(op_p), allocator(Allocator::Get(context)), executor(context) { D_ASSERT(op.select_list[0]->GetExpressionClass() == ExpressionClass::BOUND_WINDOW); auto wexpr = reinterpret_cast(op.select_list[0].get()); - partition_cols = wexpr->partitions.size(); - // we sort by both 1) partition by expression list and 2) order by expressions - auto &payload_types = op.children[0]->types; - vector over_types; + vector group_types; for (idx_t prt_idx = 0; prt_idx < wexpr->partitions.size(); prt_idx++) { auto &pexpr = wexpr->partitions[prt_idx]; - over_types.push_back(pexpr->return_type); + group_types.push_back(pexpr->return_type); executor.AddExpression(*pexpr); } + sort_cols = wexpr->orders.size() + group_types.size(); - for (const auto &order : wexpr->orders) { - auto &oexpr = order.expression; - over_types.push_back(oexpr->return_type); - executor.AddExpression(*oexpr); - } - - auto &allocator = Allocator::Get(context); - if (!over_types.empty()) { - over_chunk.Initialize(allocator, over_types); - over_subset.Initialize(allocator, over_types); + if (sort_cols) { + if (!group_types.empty()) { + // OVER(PARTITION BY...) + group_chunk.Initialize(allocator, group_types); + } + // OVER(...) + auto payload_types = op.children[0]->types; + payload_types.emplace_back(LogicalType::HASH); + payload_chunk.Initialize(allocator, payload_types); + } else { + // OVER() + payload_layout.Initialize(op.children[0]->types); } - - payload_chunk.Initialize(allocator, payload_types); - payload_subset.Initialize(allocator, payload_types); - payload_layout.Initialize(payload_types); } // Global state const PhysicalWindow &op; + Allocator &allocator; - // Input + // OVER(PARTITION BY...) (hash grouping) ExpressionExecutor executor; - DataChunk over_chunk; + DataChunk group_chunk; DataChunk payload_chunk; - idx_t count; + unique_ptr local_partition; + unique_ptr local_append; - // Grouping - idx_t partition_cols; - counts_t counts; - counts_t offsets; - Vector hash_vector; - SelectionVector sel; - DataChunk over_subset; - DataChunk payload_subset; - LocalHashGroupPtr ungrouped; - vector hash_groups; + // OVER(...) (sorting) + size_t sort_cols; // OVER() (no sorting) RowLayout payload_layout; unique_ptr rows; unique_ptr strings; - //! Switch to grouping the data - void Group(WindowGlobalSinkState &gstate); - //! Compute the OVER values - void Over(DataChunk &input_chunk); - //! Hash the data and group it - void Hash(WindowGlobalSinkState &gstate, DataChunk &input_chunk); + //! Compute the hash values + void Hash(DataChunk &input_chunk, Vector &hash_vector); //! Sink an input chunk void Sink(DataChunk &input_chunk, WindowGlobalSinkState &gstate); //! Merge the state into the global state. void Combine(WindowGlobalSinkState &gstate); }; -void WindowLocalSinkState::Over(DataChunk &input_chunk) { - if (over_chunk.ColumnCount() > 0) { - over_chunk.Reset(); - executor.Execute(input_chunk, over_chunk); - over_chunk.Verify(); - } -} - -void WindowLocalSinkState::Hash(WindowGlobalSinkState &gstate, DataChunk &input_chunk) { - // There are three types of hash grouping: - // 1. No partitions (no sorting) - // 2. One group (sorting, but no hash grouping) - // 3. Multiple groups (sorting and hash grouping) - if (over_chunk.ColumnCount() == 0) { - return; - } - - const auto count = over_chunk.size(); - auto hashes = FlatVector::GetData(hash_vector); - if (hash_groups.empty()) { - // Ungrouped, so take them all - counts.resize(1, count); - } else { - // First pass: count bins sizes - counts.resize(0); - counts.resize(hash_groups.size(), 0); - - VectorOperations::Hash(over_chunk.data[0], hash_vector, count); - for (idx_t prt_idx = 1; prt_idx < partition_cols; ++prt_idx) { - VectorOperations::CombineHash(hash_vector, over_chunk.data[prt_idx], count); - } - - const auto &partition_info = gstate.partition_info; - if (hash_vector.GetVectorType() == VectorType::CONSTANT_VECTOR) { - const auto group = partition_info.GetHashPartition(hashes[0]); - counts[group] = count; - for (idx_t i = 0; i < count; ++i) { - sel.set_index(i, i); - } - } else { - for (idx_t i = 0; i < count; ++i) { - const auto group = partition_info.GetHashPartition(hashes[i]); - ++counts[group]; - } - - // Second pass: Initialise offsets - offsets.resize(counts.size()); - size_t offset = 0; - for (size_t c = 0; c < counts.size(); ++c) { - offsets[c] = offset; - offset += counts[c]; - } - - // Third pass: Build sequential selections - for (idx_t i = 0; i < count; ++i) { - const auto group = partition_info.GetHashPartition(hashes[i]); - auto &group_idx = offsets[group]; - sel.set_index(group_idx++, i); - } - } - } - - idx_t group_offset = 0; - for (size_t group = 0; group < counts.size(); ++group) { - const auto group_size = counts[group]; - if (group_size) { - auto &local_group = hash_groups[group]; - if (!local_group) { - auto global_group = gstate.GetHashGroup(group); - local_group = make_unique(*global_group); - } - - if (counts.size() == 1) { - local_group->SinkChunk(over_chunk, input_chunk); - } else { - SelectionVector psel(sel.data() + group_offset); - over_subset.Slice(over_chunk, psel, group_size); - payload_subset.Slice(input_chunk, psel, group_size); - local_group->SinkChunk(over_subset, payload_subset); - group_offset += group_size; - } +void WindowLocalSinkState::Hash(DataChunk &input_chunk, Vector &hash_vector) { + const auto count = input_chunk.size(); + if (group_chunk.ColumnCount() > 0) { + // OVER(PARTITION BY...) (hash grouping) + group_chunk.Reset(); + executor.Execute(input_chunk, group_chunk); + VectorOperations::Hash(group_chunk.data[0], hash_vector, count); + for (idx_t prt_idx = 1; prt_idx < group_chunk.ColumnCount(); ++prt_idx) { + VectorOperations::CombineHash(hash_vector, group_chunk.data[prt_idx], count); } + } else { + // OVER(...) (sorting) + // Single partition => single hash value + hash_vector.SetVectorType(VectorType::CONSTANT_VECTOR); + auto hashes = ConstantVector::GetData(hash_vector); + hashes[0] = 0; } } -void WindowLocalSinkState::Group(WindowGlobalSinkState &gstate) { - if (!gstate.partition_cols) { - return; - } - - if (!hash_groups.empty()) { - return; - } - - hash_groups.resize(gstate.Group()); - - if (!ungrouped) { - return; - } - - auto &payload_data = *ungrouped->local_sort->payload_data; - auto rows = payload_data.CloneEmpty(payload_data.keep_pinned); - - auto &payload_heap = *ungrouped->local_sort->payload_heap; - auto heap = payload_heap.CloneEmpty(payload_heap.keep_pinned); - - RowDataCollectionScanner::AlignHeapBlocks(*rows, *heap, payload_data, payload_heap, payload_layout); - RowDataCollectionScanner scanner(*rows, *heap, payload_layout, true); - while (scanner.Remaining()) { - payload_chunk.Reset(); - scanner.Scan(payload_chunk); - - Over(payload_chunk); - Hash(gstate, payload_chunk); - } - - ungrouped.reset(); -} - void WindowLocalSinkState::Sink(DataChunk &input_chunk, WindowGlobalSinkState &gstate) { gstate.count += input_chunk.size(); - count += input_chunk.size(); - - Over(input_chunk); // OVER() - if (over_chunk.ColumnCount() == 0) { + if (sort_cols == 0) { // No sorts, so build paged row chunks if (!rows) { const auto entry_size = payload_layout.GetRowWidth(); @@ -77438,27 +81481,23 @@ void WindowLocalSinkState::Sink(DataChunk &input_chunk, WindowGlobalSinkState &g return; } - // Ungrouped - if (hash_groups.empty()) { - auto global_ungrouped = gstate.GetUngrouped(); - if (!ungrouped) { - ungrouped = make_unique(*global_ungrouped); - } + // OVER(...) + gstate.UpdateLocalPartition(local_partition, local_append); - // If we pass our thread memory budget, then switch to hash grouping. - if (ungrouped->SinkChunk(over_chunk, input_chunk) || gstate.count > 100000) { - Group(gstate); - } - return; + payload_chunk.Reset(); + auto &hash_vector = payload_chunk.data.back(); + Hash(input_chunk, hash_vector); + for (idx_t col_idx = 0; col_idx < input_chunk.ColumnCount(); ++col_idx) { + payload_chunk.data[col_idx].Reference(input_chunk.data[col_idx]); } + payload_chunk.SetCardinality(input_chunk); - // Grouped, so hash - Hash(gstate, input_chunk); + local_partition->Append(*local_append, payload_chunk); } void WindowLocalSinkState::Combine(WindowGlobalSinkState &gstate) { // OVER() - if (over_chunk.ColumnCount() == 0) { + if (sort_cols == 0) { // Only one partition again, so need a global lock. lock_guard glock(gstate.lock); if (gstate.rows) { @@ -77469,95 +81508,20 @@ void WindowLocalSinkState::Combine(WindowGlobalSinkState &gstate) { strings.reset(); } } else { - gstate.rows = move(rows); - gstate.strings = move(strings); + gstate.rows = std::move(rows); + gstate.strings = std::move(strings); } return; } - // Ungrouped data - idx_t check = 0; - if (ungrouped) { - check += ungrouped->count; - ungrouped->Combine(); - ungrouped.reset(); - } - - // Grouped data - for (auto &local_group : hash_groups) { - if (local_group) { - check += local_group->count; - local_group->Combine(); - local_group.reset(); - } - } - - (void)check; - D_ASSERT(check == count); -} - -void WindowGlobalSinkState::Finalize() { - if (!ungrouped) { - return; - } - - if (hash_groups.empty()) { - hash_groups.emplace_back(move(ungrouped)); - return; - } - - // If we have grouped data, merge the remaining ungrouped data into it. - // This can happen if only SOME of the threads ended up regrouping. - // The simplest thing to do is to fake a local thread state, - // push the ungrouped data into it and then use that state to partition the data. - // This is probably OK because this situation will only happen - // with relatively small amounts of data. - - // Sort the data so we can scan it - auto &global_sort = *ungrouped->global_sort; - if (global_sort.sorted_blocks.empty()) { - return; - } - - global_sort.PrepareMergePhase(); - while (global_sort.sorted_blocks.size() > 1) { - global_sort.InitializeMergeRound(); - MergeSorter merge_sorter(global_sort, global_sort.buffer_manager); - merge_sorter.PerformInMergeRound(); - global_sort.CompleteMergeRound(true); - } - - // Sink it into a temporary local sink state - auto lstate = make_unique(context, op); - - // Match the grouping. - lstate->Group(*this); - - // Write into the state chunks directly to hash them - auto &payload_chunk = lstate->payload_chunk; - - // Now scan the sorted data - PayloadScanner scanner(global_sort); - while (scanner.Remaining()) { - lstate->payload_chunk.Reset(); - scanner.Scan(lstate->payload_chunk); - if (payload_chunk.size() == 0) { - break; - } - lstate->count += payload_chunk.size(); - - lstate->Over(payload_chunk); - lstate->Hash(*this, payload_chunk); - } - - // Merge the grouped data in. - lstate->Combine(*this); + // OVER(...) + gstate.CombineLocalPartition(local_partition, local_append); } // this implements a sorted window functions variant PhysicalWindow::PhysicalWindow(vector types, vector> select_list_p, idx_t estimated_cardinality, PhysicalOperatorType type) - : PhysicalOperator(type, move(types), estimated_cardinality), select_list(move(select_list_p)) { + : PhysicalOperator(type, std::move(types), estimated_cardinality), select_list(std::move(select_list_p)) { is_order_dependent = false; for (auto &expr : select_list) { D_ASSERT(expr->expression_class == ExpressionClass::BOUND_WINDOW); @@ -78170,6 +82134,7 @@ WindowExecutor::WindowExecutor(BoundWindowExpression *wexpr, ClientContext &cont // evaluate inner expressions of window functions, could be more complex vector exprs; + exprs.reserve(wexpr->children.size()); for (auto &child : wexpr->children) { exprs.push_back(child.get()); } @@ -78476,6 +82441,10 @@ class WindowLocalMergeState { bool TaskFinished() { return finished; } + + void Prepare(); + void Merge(); + void ExecuteTask(); WindowGlobalMergeState *merge_state; @@ -78485,8 +82454,19 @@ class WindowLocalMergeState { class WindowGlobalMergeState { public: - explicit WindowGlobalMergeState(GlobalSortState &sort_state) - : sort_state(sort_state), stage(WindowSortStage::INIT), total_tasks(0), tasks_assigned(0), tasks_completed(0) { + using GroupDataPtr = unique_ptr; + + explicit WindowGlobalMergeState(WindowGlobalSinkState &sink, GroupDataPtr group_data) + : sink(sink), group_data(std::move(group_data)), stage(WindowSortStage::INIT), total_tasks(0), + tasks_assigned(0), tasks_completed(0) { + + const auto group_idx = sink.hash_groups.size(); + auto new_group = make_unique(sink.buffer_manager, sink.partitions, sink.orders, + sink.payload_types, sink.external); + sink.hash_groups.emplace_back(std::move(new_group)); + + hash_group = sink.hash_groups[group_idx].get(); + global_sort = sink.hash_groups[group_idx]->global_sort.get(); } bool IsSorted() const { @@ -78498,7 +82478,10 @@ class WindowGlobalMergeState { bool TryPrepareNextStage(); void CompleteTask(); - GlobalSortState &sort_state; + WindowGlobalSinkState &sink; + GroupDataPtr group_data; + WindowGlobalHashGroup *hash_group; + GlobalSortState *global_sort; private: mutable mutex lock; @@ -78508,17 +82491,28 @@ class WindowGlobalMergeState { idx_t tasks_completed; }; +void WindowLocalMergeState::Prepare() { + auto &global_sort = *merge_state->global_sort; + merge_state->sink.BuildSortState(*merge_state->group_data, *merge_state->hash_group); + merge_state->group_data.reset(); + + global_sort.PrepareMergePhase(); +} + +void WindowLocalMergeState::Merge() { + auto &global_sort = *merge_state->global_sort; + MergeSorter merge_sorter(global_sort, global_sort.buffer_manager); + merge_sorter.PerformInMergeRound(); +} + void WindowLocalMergeState::ExecuteTask() { - auto &global_sort = merge_state->sort_state; switch (stage) { case WindowSortStage::PREPARE: - global_sort.PrepareMergePhase(); + Prepare(); break; - case WindowSortStage::MERGE: { - MergeSorter merge_sorter(global_sort, global_sort.buffer_manager); - merge_sorter.PerformInMergeRound(); + case WindowSortStage::MERGE: + Merge(); break; - } default: throw InternalException("Unexpected WindowGlobalMergeState in ExecuteTask!"); } @@ -78564,21 +82558,21 @@ bool WindowGlobalMergeState::TryPrepareNextStage() { return true; case WindowSortStage::PREPARE: - total_tasks = sort_state.sorted_blocks.size() / 2; + total_tasks = global_sort->sorted_blocks.size() / 2; if (!total_tasks) { break; } stage = WindowSortStage::MERGE; - sort_state.InitializeMergeRound(); + global_sort->InitializeMergeRound(); return true; case WindowSortStage::MERGE: - sort_state.CompleteMergeRound(true); - total_tasks = sort_state.sorted_blocks.size() / 2; + global_sort->CompleteMergeRound(true); + total_tasks = global_sort->sorted_blocks.size() / 2; if (!total_tasks) { break; } - sort_state.InitializeMergeRound(); + global_sort->InitializeMergeRound(); return true; case WindowSortStage::SORTED: @@ -78594,14 +82588,14 @@ class WindowGlobalMergeStates { public: using WindowGlobalMergeStatePtr = unique_ptr; - WindowGlobalMergeStates(WindowGlobalSinkState &sink, idx_t group) { + explicit WindowGlobalMergeStates(WindowGlobalSinkState &sink) { // Schedule all the sorts for maximum thread utilisation - for (; group < sink.hash_groups.size(); group = sink.GetNextSortGroup()) { - auto &hash_group = *sink.hash_groups[group]; - + for (auto &group_data : sink.grouping_data->GetPartitions()) { // Prepare for merge sort phase - auto state = make_unique(*hash_group.global_sort); - states.emplace_back(move(state)); + if (group_data->Count()) { + auto state = make_unique(sink, std::move(group_data)); + states.emplace_back(std::move(state)); + } } } @@ -78611,7 +82605,7 @@ class WindowGlobalMergeStates { class WindowMergeTask : public ExecutorTask { public: WindowMergeTask(shared_ptr event_p, ClientContext &context_p, WindowGlobalMergeStates &hash_groups_p) - : ExecutorTask(context_p), event(move(event_p)), hash_groups(hash_groups_p) { + : ExecutorTask(context_p), event(std::move(event_p)), hash_groups(hash_groups_p) { } TaskExecutionResult ExecuteTask(TaskExecutionMode mode) override; @@ -78681,8 +82675,8 @@ TaskExecutionResult WindowMergeTask::ExecuteTask(TaskExecutionMode mode) { class WindowMergeEvent : public BasePipelineEvent { public: - WindowMergeEvent(WindowGlobalSinkState &gstate_p, Pipeline &pipeline_p, idx_t group) - : BasePipelineEvent(pipeline_p), gstate(gstate_p), merge_states(gstate_p, group) { + WindowMergeEvent(WindowGlobalSinkState &gstate_p, Pipeline &pipeline_p) + : BasePipelineEvent(pipeline_p), gstate(gstate_p), merge_states(gstate_p) { } WindowGlobalSinkState &gstate; @@ -78700,7 +82694,7 @@ class WindowMergeEvent : public BasePipelineEvent { for (idx_t tnum = 0; tnum < num_threads; tnum++) { merge_tasks.push_back(make_unique(shared_from_this(), context, merge_states)); } - SetTasks(move(merge_tasks)); + SetTasks(std::move(merge_tasks)); } }; @@ -78708,24 +82702,27 @@ SinkFinalizeType PhysicalWindow::Finalize(Pipeline &pipeline, Event &event, Clie GlobalSinkState &gstate_p) const { auto &state = (WindowGlobalSinkState &)gstate_p; + // Did we get any data? + if (!state.count) { + return SinkFinalizeType::NO_OUTPUT_POSSIBLE; + } + // Do we have any sorting to schedule? if (state.rows) { - D_ASSERT(state.hash_groups.empty()); + D_ASSERT(!state.grouping_data); return state.rows->count ? SinkFinalizeType::READY : SinkFinalizeType::NO_OUTPUT_POSSIBLE; } // Find the first group to sort - state.Finalize(); - D_ASSERT(state.count == state.GroupCount()); - auto group = state.GetNextSortGroup(); - if (group >= state.hash_groups.size()) { + auto &groups = state.grouping_data->GetPartitions(); + if (groups.empty()) { // Empty input! return SinkFinalizeType::NO_OUTPUT_POSSIBLE; } // Schedule all the sorts for maximum thread utilisation - auto new_event = make_shared(state, pipeline, group); - event.InsertEvent(move(new_event)); + auto new_event = make_shared(state, pipeline); + event.InsertEvent(std::move(new_event)); return SinkFinalizeType::READY; } @@ -78747,18 +82744,16 @@ class WindowGlobalSourceState : public GlobalSourceState { auto &state = (WindowGlobalSinkState &)*op.sink_state; // If there is only one partition, we have to process it on one thread. - if (state.hash_groups.empty()) { + if (!state.grouping_data) { return 1; } - idx_t max_threads = 0; - for (const auto &hash_group : state.hash_groups) { - if (hash_group) { - max_threads++; - } + // If there is not a lot of data, process serially. + if (state.count < STANDARD_ROW_GROUPS_SIZE) { + return 1; } - return max_threads; + return state.hash_groups.size(); } }; @@ -78769,8 +82764,8 @@ class WindowLocalSourceState : public LocalSourceState { using WindowExecutorPtr = unique_ptr; using WindowExecutors = vector; - WindowLocalSourceState(Allocator &allocator_p, const PhysicalWindow &op, ExecutionContext &context) - : context(context.client), allocator(allocator_p) { + WindowLocalSourceState(const PhysicalWindow &op, ExecutionContext &context, WindowGlobalSourceState &gstate) + : context(context.client), allocator(Allocator::Get(context.client)) { vector output_types; for (idx_t expr_idx = 0; expr_idx < op.select_list.size(); ++expr_idx) { D_ASSERT(op.select_list[expr_idx]->GetExpressionClass() == ExpressionClass::BOUND_WINDOW); @@ -78837,7 +82832,7 @@ void WindowLocalSourceState::MaterializeSortedData() { D_ASSERT(!sd.data_blocks.empty()); auto &block = sd.data_blocks[0]; rows = make_unique(buffer_manager, block->capacity, block->entry_size); - rows->blocks = move(sd.data_blocks); + rows->blocks = std::move(sd.data_blocks); rows->count = std::accumulate(rows->blocks.begin(), rows->blocks.end(), idx_t(0), [&](idx_t c, const unique_ptr &b) { return c + b->count; }); @@ -78845,7 +82840,7 @@ void WindowLocalSourceState::MaterializeSortedData() { if (!sd.heap_blocks.empty()) { auto &block = sd.heap_blocks[0]; heap = make_unique(buffer_manager, block->capacity, block->entry_size); - heap->blocks = move(sd.heap_blocks); + heap->blocks = std::move(sd.heap_blocks); hash_group.reset(); } else { heap = make_unique(buffer_manager, (idx_t)Storage::BLOCK_SIZE, 1, true); @@ -78859,7 +82854,6 @@ void WindowLocalSourceState::GeneratePartition(WindowGlobalSinkState &gstate, co // Get rid of any stale data hash_bin = hash_bin_p; - hash_group.reset(); // There are three types of partitions: // 1. No partition (no sorting) @@ -78882,7 +82876,7 @@ void WindowLocalSourceState::GeneratePartition(WindowGlobalSinkState &gstate, co D_ASSERT(op.select_list[expr_idx]->GetExpressionClass() == ExpressionClass::BOUND_WINDOW); auto wexpr = reinterpret_cast(op.select_list[expr_idx].get()); auto wexec = make_unique(wexpr, context, count); - window_execs.emplace_back(move(wexec)); + window_execs.emplace_back(std::move(wexec)); } // Initialise masks to false @@ -78908,7 +82902,7 @@ void WindowLocalSourceState::GeneratePartition(WindowGlobalSinkState &gstate, co external = true; } else if (hash_bin < gstate.hash_groups.size() && gstate.hash_groups[hash_bin]) { // Overwrite the collections with the sorted data - hash_group = move(gstate.hash_groups[hash_bin]); + hash_group = std::move(gstate.hash_groups[hash_bin]); hash_group->ComputeMasks(partition_mask, order_mask); MaterializeSortedData(); } else { @@ -78942,13 +82936,12 @@ void WindowLocalSourceState::GeneratePartition(WindowGlobalSinkState &gstate, co scanner->ReSwizzle(); // Second pass can flush - scanner = make_unique(*rows, *heap, layout, external, true); + scanner->Reset(true); } void WindowLocalSourceState::Scan(DataChunk &result) { D_ASSERT(scanner); if (!scanner->Remaining()) { - scanner.reset(); return; } @@ -78976,8 +82969,9 @@ void WindowLocalSourceState::Scan(DataChunk &result) { } unique_ptr PhysicalWindow::GetLocalSourceState(ExecutionContext &context, - GlobalSourceState &gstate) const { - return make_unique(Allocator::Get(context.client), *this, context); + GlobalSourceState &gstate_p) const { + auto &gstate = (WindowGlobalSourceState &)gstate_p; + return make_unique(*this, context, gstate); } unique_ptr PhysicalWindow::GetGlobalSourceState(ClientContext &context) const { @@ -78992,25 +82986,28 @@ void PhysicalWindow::GetData(ExecutionContext &context, DataChunk &chunk, Global const auto bin_count = gstate.hash_groups.empty() ? 1 : gstate.hash_groups.size(); - // Move to the next bin if we are done. - while (!state.scanner || !state.scanner->Remaining()) { - state.scanner.reset(); - state.rows.reset(); - state.heap.reset(); - auto hash_bin = global_source.next_bin++; - if (hash_bin >= bin_count) { - return; - } + while (chunk.size() == 0) { + // Move to the next bin if we are done. + while (!state.scanner || !state.scanner->Remaining()) { + state.scanner.reset(); + state.rows.reset(); + state.heap.reset(); + state.hash_group.reset(); + auto hash_bin = global_source.next_bin++; + if (hash_bin >= bin_count) { + return; + } - for (; hash_bin < gstate.hash_groups.size(); hash_bin = global_source.next_bin++) { - if (gstate.hash_groups[hash_bin]) { - break; + for (; hash_bin < gstate.hash_groups.size(); hash_bin = global_source.next_bin++) { + if (gstate.hash_groups[hash_bin]) { + break; + } } + state.GeneratePartition(gstate, hash_bin); } - state.GeneratePartition(gstate, hash_bin); - } - state.Scan(chunk); + state.Scan(chunk); + } } string PhysicalWindow::ParamsToString() const { @@ -79072,17 +83069,17 @@ namespace duckdb { PhysicalFilter::PhysicalFilter(vector types, vector> select_list, idx_t estimated_cardinality) - : CachingPhysicalOperator(PhysicalOperatorType::FILTER, move(types), estimated_cardinality) { + : CachingPhysicalOperator(PhysicalOperatorType::FILTER, std::move(types), estimated_cardinality) { D_ASSERT(select_list.size() > 0); if (select_list.size() > 1) { // create a big AND out of the expressions auto conjunction = make_unique(ExpressionType::CONJUNCTION_AND); for (auto &expr : select_list) { - conjunction->children.push_back(move(expr)); + conjunction->children.push_back(std::move(expr)); } - expression = move(conjunction); + expression = std::move(conjunction); } else { - expression = move(select_list[0]); + expression = std::move(select_list[0]); } } @@ -79119,7 +83116,10 @@ OperatorResultType PhysicalFilter::ExecuteInternal(ExecutionContext &context, Da } string PhysicalFilter::ParamsToString() const { - return expression->GetName(); + auto result = expression->GetName(); + result += "\n[INFOSEPARATOR]\n"; + result += StringUtil::Format("EC: %llu", estimated_props->GetCardinality()); + return result; } } // namespace duckdb @@ -79265,9 +83265,9 @@ SinkFinalizeType PhysicalBatchCollector::Finalize(Pipeline &pipeline, Event &eve auto &gstate = (BatchCollectorGlobalState &)gstate_p; auto collection = gstate.data.FetchCollection(); D_ASSERT(collection); - auto result = make_unique(statement_type, properties, names, move(collection), + auto result = make_unique(statement_type, properties, names, std::move(collection), context.GetClientProperties()); - gstate.result = move(result); + gstate.result = std::move(result); return SinkFinalizeType::READY; } @@ -79282,7 +83282,7 @@ unique_ptr PhysicalBatchCollector::GetGlobalSinkState(ClientCon unique_ptr PhysicalBatchCollector::GetResult(GlobalSinkState &state) { auto &gstate = (BatchCollectorGlobalState &)state; D_ASSERT(gstate.result); - return move(gstate.result); + return std::move(gstate.result); } } // namespace duckdb @@ -79523,7 +83523,7 @@ namespace duckdb { class PhysicalExplainAnalyze : public PhysicalOperator { public: PhysicalExplainAnalyze(vector types) - : PhysicalOperator(PhysicalOperatorType::EXPLAIN_ANALYZE, move(types), 1) { + : PhysicalOperator(PhysicalOperatorType::EXPLAIN_ANALYZE, std::move(types), 1) { } public: @@ -79731,8 +83731,9 @@ namespace duckdb { PhysicalLimit::PhysicalLimit(vector types, idx_t limit, idx_t offset, unique_ptr limit_expression, unique_ptr offset_expression, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::LIMIT, move(types), estimated_cardinality), limit_value(limit), - offset_value(offset), limit_expression(move(limit_expression)), offset_expression(move(offset_expression)) { + : PhysicalOperator(PhysicalOperatorType::LIMIT, std::move(types), estimated_cardinality), limit_value(limit), + offset_value(offset), limit_expression(std::move(limit_expression)), + offset_expression(std::move(offset_expression)) { } //===--------------------------------------------------------------------===// @@ -79958,9 +83959,9 @@ class PhysicalLimitPercent : public PhysicalOperator { PhysicalLimitPercent(vector types, double limit_percent, idx_t offset, unique_ptr limit_expression, unique_ptr offset_expression, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::LIMIT_PERCENT, move(types), estimated_cardinality), - limit_percent(limit_percent), offset_value(offset), limit_expression(move(limit_expression)), - offset_expression(move(offset_expression)) { + : PhysicalOperator(PhysicalOperatorType::LIMIT_PERCENT, std::move(types), estimated_cardinality), + limit_percent(limit_percent), offset_value(offset), limit_expression(std::move(limit_expression)), + offset_expression(std::move(offset_expression)) { } double limit_percent; @@ -80156,6 +84157,7 @@ void PhysicalLimitPercent::GetData(ExecutionContext &context, DataChunk &chunk, + namespace duckdb { enum class LoadType { LOAD, INSTALL, FORCE_INSTALL }; @@ -80171,6 +84173,22 @@ struct LoadInfo : public ParseInfo { result->load_type = load_type; return result; } + + void Serialize(Serializer &serializer) const { + FieldWriter writer(serializer); + writer.WriteString(filename); + writer.WriteField(load_type); + writer.Finalize(); + } + + static unique_ptr Deserialize(Deserializer &deserializer) { + FieldReader reader(deserializer); + auto load_info = make_unique(); + load_info->filename = reader.ReadRequired(); + load_info->load_type = reader.ReadRequired(); + reader.Finalize(); + return std::move(load_info); + } }; } // namespace duckdb @@ -80183,7 +84201,7 @@ class PhysicalLoad : public PhysicalOperator { public: explicit PhysicalLoad(unique_ptr info, idx_t estimated_cardinality) : PhysicalOperator(PhysicalOperatorType::LOAD, {LogicalType::BOOLEAN}, estimated_cardinality), - info(move(info)) { + info(std::move(info)) { } unique_ptr info; @@ -80240,6 +84258,7 @@ class ExtensionHelper { static void InstallExtension(ClientContext &context, const string &extension, bool force_install); static void LoadExternalExtension(ClientContext &context, const string &extension); + static void LoadExternalExtension(DatabaseInstance &db, FileOpener *opener, const string &extension); static string ExtensionDirectory(ClientContext &context); @@ -80251,9 +84270,13 @@ class ExtensionHelper { static const vector GetPublicKeys(); - static unique_ptr ReplacementOpenPre(const string &extension, DBConfig &config); - static void ReplacementOpenPost(ClientContext &context, const string &extension, DatabaseInstance &instance, - ReplacementOpenData *open_data); + static void StorageInit(string &extension, DBConfig &config); + + // Returns extension name, or empty string if not a replacement open path + static string ExtractExtensionPrefixFromPath(const string &path); + + //! Apply any known extension aliases + static string ApplyExtensionAlias(string extension_name); private: static const vector PathComponents(); @@ -80263,8 +84286,7 @@ class ExtensionHelper { //! Version tags occur with and without 'v', tag in extension path is always with 'v' static const string NormalizeVersionTag(const string &version_tag); static bool IsRelease(const string &version_tag); - //! Apply any known extension aliases - static string ApplyExtensionAlias(string extension_name); + static bool CreateSuggestions(const string &extension_name, string &message); private: static ExtensionLoadResult LoadExtensionInternal(DuckDB &db, const std::string &extension, bool initial_load); @@ -80365,7 +84387,7 @@ void PhysicalMaterializedCollector::Combine(ExecutionContext &context, GlobalSin lock_guard l(gstate.glock); if (!gstate.collection) { - gstate.collection = move(lstate.collection); + gstate.collection = std::move(lstate.collection); } else { gstate.collection->Combine(*lstate.collection); } @@ -80374,14 +84396,14 @@ void PhysicalMaterializedCollector::Combine(ExecutionContext &context, GlobalSin unique_ptr PhysicalMaterializedCollector::GetGlobalSinkState(ClientContext &context) const { auto state = make_unique(); state->context = context.shared_from_this(); - return move(state); + return std::move(state); } unique_ptr PhysicalMaterializedCollector::GetLocalSinkState(ExecutionContext &context) const { auto state = make_unique(); state->collection = make_unique(Allocator::DefaultAllocator(), types); state->collection->InitializeAppend(state->append_state); - return move(state); + return std::move(state); } unique_ptr PhysicalMaterializedCollector::GetResult(GlobalSinkState &state) { @@ -80389,9 +84411,9 @@ unique_ptr PhysicalMaterializedCollector::GetResult(GlobalSinkState if (!gstate.collection) { gstate.collection = make_unique(Allocator::DefaultAllocator(), types); } - auto result = make_unique(statement_type, properties, names, move(gstate.collection), + auto result = make_unique(statement_type, properties, names, std::move(gstate.collection), gstate.context->GetClientProperties()); - return move(result); + return std::move(result); } bool PhysicalMaterializedCollector::ParallelSink() const { @@ -80420,7 +84442,7 @@ class PhysicalPragma : public PhysicalOperator { public: PhysicalPragma(PragmaFunction function_p, PragmaInfo info_p, idx_t estimated_cardinality) : PhysicalOperator(PhysicalOperatorType::PRAGMA, {LogicalType::BOOLEAN}, estimated_cardinality), - function(move(function_p)), info(move(info_p)) { + function(std::move(function_p)), info(std::move(info_p)) { } //! The pragma function to call @@ -80467,7 +84489,7 @@ class PhysicalPrepare : public PhysicalOperator { public: PhysicalPrepare(string name, shared_ptr prepared, idx_t estimated_cardinality) : PhysicalOperator(PhysicalOperatorType::PREPARE, {LogicalType::BOOLEAN}, estimated_cardinality), name(name), - prepared(move(prepared)) { + prepared(std::move(prepared)) { } string name; @@ -80513,8 +84535,8 @@ namespace duckdb { class PhysicalReservoirSample : public PhysicalOperator { public: PhysicalReservoirSample(vector types, unique_ptr options, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::RESERVOIR_SAMPLE, move(types), estimated_cardinality), - options(move(options)) { + : PhysicalOperator(PhysicalOperatorType::RESERVOIR_SAMPLE, std::move(types), estimated_cardinality), + options(std::move(options)) { } unique_ptr options; @@ -80735,6 +84757,225 @@ string PhysicalReservoirSample::ParamsToString() const { } } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/execution/operator/helper/physical_reset.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/parsed_data/vacuum_info.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/tableref/bound_basetableref.hpp +// +// +//===----------------------------------------------------------------------===// + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/bound_tableref.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + +namespace duckdb { + +class BoundTableRef { +public: + explicit BoundTableRef(TableReferenceType type) : type(type) { + } + virtual ~BoundTableRef() { + } + + //! The type of table reference + TableReferenceType type; + //! The sample options (if any) + unique_ptr sample; +}; +} // namespace duckdb + + + +namespace duckdb { +class TableCatalogEntry; + +//! Represents a TableReference to a base table in the schema +class BoundBaseTableRef : public BoundTableRef { +public: + BoundBaseTableRef(TableCatalogEntry *table, unique_ptr get) + : BoundTableRef(TableReferenceType::BASE_TABLE), table(table), get(std::move(get)) { + } + + TableCatalogEntry *table; + unique_ptr get; +}; +} // namespace duckdb + + + +namespace duckdb { + +struct VacuumOptions { + bool vacuum; + bool analyze; +}; + +struct VacuumInfo : public ParseInfo { +public: + explicit VacuumInfo(VacuumOptions options) : options(options), has_table(false), table(nullptr) {}; + + unique_ptr Copy() { + auto result = make_unique(options); + result->has_table = has_table; + if (has_table) { + result->ref = ref->Copy(); + } + return result; + } + + const VacuumOptions options; + +public: + bool has_table; + unique_ptr ref; + TableCatalogEntry *table; + unordered_map column_id_map; + vector columns; +}; + +} // namespace duckdb + + +namespace duckdb { + +struct DBConfig; +struct ExtensionOption; + +//! PhysicalReset represents a RESET operation (e.g. RESET a = 42) +class PhysicalReset : public PhysicalOperator { +public: + PhysicalReset(const std::string &name_p, SetScope scope_p, idx_t estimated_cardinality) + : PhysicalOperator(PhysicalOperatorType::RESET, {LogicalType::BOOLEAN}, estimated_cardinality), name(name_p), + scope(scope_p) { + } + +public: + // Source interface + void GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, + LocalSourceState &lstate) const override; + +public: + const std::string name; + const SetScope scope; + +private: + void ResetExtensionVariable(ExecutionContext &context, DBConfig &config, ExtensionOption &extension_option) const; +}; + +} // namespace duckdb + + + + + + +namespace duckdb { + +void PhysicalReset::ResetExtensionVariable(ExecutionContext &context, DBConfig &config, + ExtensionOption &extension_option) const { + if (extension_option.set_function) { + extension_option.set_function(context.client, scope, extension_option.default_value); + } + if (scope == SetScope::GLOBAL) { + config.ResetOption(name); + } else { + auto &client_config = ClientConfig::GetConfig(context.client); + client_config.set_variables[name] = extension_option.default_value; + } +} + +void PhysicalReset::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, + LocalSourceState &lstate) const { + auto option = DBConfig::GetOptionByName(name); + if (!option) { + // check if this is an extra extension variable + auto &config = DBConfig::GetConfig(context.client); + auto entry = config.extension_parameters.find(name); + if (entry == config.extension_parameters.end()) { + // it is not! + // get a list of all options + vector potential_names = DBConfig::GetOptionNames(); + for (auto &entry : config.extension_parameters) { + potential_names.push_back(entry.first); + } + + throw CatalogException("unrecognized configuration parameter \"%s\"\n%s", name, + StringUtil::CandidatesErrorMessage(potential_names, name, "Did you mean")); + } + ResetExtensionVariable(context, config, entry->second); + return; + } + + // Transform scope + SetScope variable_scope = scope; + if (variable_scope == SetScope::AUTOMATIC) { + if (option->set_local) { + variable_scope = SetScope::SESSION; + } else { + D_ASSERT(option->set_global); + variable_scope = SetScope::GLOBAL; + } + } + + switch (variable_scope) { + case SetScope::GLOBAL: { + if (!option->set_global) { + throw CatalogException("option \"%s\" cannot be reset globally", name); + } + auto &db = DatabaseInstance::GetDatabase(context.client); + auto &config = DBConfig::GetConfig(context.client); + config.ResetOption(&db, *option); + break; + } + case SetScope::SESSION: + if (!option->reset_local) { + throw CatalogException("option \"%s\" cannot be reset locally", name); + } + option->reset_local(context.client); + break; + default: + throw InternalException("Unsupported SetScope for variable"); + } +} + +} // namespace duckdb @@ -80806,111 +85047,12 @@ void PhysicalResultCollector::BuildPipelines(Pipeline ¤t, MetaPipeline &me -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/parsed_data/vacuum_info.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/tableref/bound_basetableref.hpp -// -// -//===----------------------------------------------------------------------===// - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/bound_tableref.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - namespace duckdb { -class BoundTableRef { -public: - explicit BoundTableRef(TableReferenceType type) : type(type) { - } - virtual ~BoundTableRef() { - } - - //! The type of table reference - TableReferenceType type; - //! The sample options (if any) - unique_ptr sample; -}; -} // namespace duckdb - - - -namespace duckdb { -class TableCatalogEntry; - -//! Represents a TableReference to a base table in the schema -class BoundBaseTableRef : public BoundTableRef { -public: - BoundBaseTableRef(TableCatalogEntry *table, unique_ptr get) - : BoundTableRef(TableReferenceType::BASE_TABLE), table(table), get(move(get)) { - } - - TableCatalogEntry *table; - unique_ptr get; -}; -} // namespace duckdb - - - -namespace duckdb { - -struct VacuumOptions { - bool vacuum; - bool analyze; -}; - -struct VacuumInfo : public ParseInfo { -public: - explicit VacuumInfo(VacuumOptions options) : options(options), has_table(false), table(nullptr) {}; - - unique_ptr Copy() { - auto result = make_unique(options); - result->has_table = has_table; - if (has_table) { - result->ref = ref->Copy(); - } - return result; - } - - const VacuumOptions options; - -public: - bool has_table; - unique_ptr ref; - TableCatalogEntry *table; - unordered_map column_id_map; - vector columns; -}; - -} // namespace duckdb - - -namespace duckdb { +struct DBConfig; +struct ExtensionOption; //! PhysicalSet represents a SET operation (e.g. SET a = 42) class PhysicalSet : public PhysicalOperator { @@ -80925,6 +85067,9 @@ class PhysicalSet : public PhysicalOperator { void GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, LocalSourceState &lstate) const override; + static void SetExtensionVariable(ClientContext &context, ExtensionOption &extension_option, const string &name, + SetScope scope, const Value &value); + public: const std::string name; const Value value; @@ -80940,6 +85085,22 @@ class PhysicalSet : public PhysicalOperator { namespace duckdb { +void PhysicalSet::SetExtensionVariable(ClientContext &context, ExtensionOption &extension_option, const string &name, + SetScope scope, const Value &value) { + auto &config = DBConfig::GetConfig(context); + auto &target_type = extension_option.type; + Value target_value = value.CastAs(context, target_type); + if (extension_option.set_function) { + extension_option.set_function(context, scope, target_value); + } + if (scope == SetScope::GLOBAL) { + config.SetOption(name, std::move(target_value)); + } else { + auto &client_config = ClientConfig::GetConfig(context); + client_config.set_variables[name] = std::move(target_value); + } +} + void PhysicalSet::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, LocalSourceState &lstate) const { auto option = DBConfig::GetOptionByName(name); @@ -80958,19 +85119,7 @@ void PhysicalSet::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSou throw CatalogException("unrecognized configuration parameter \"%s\"\n%s", name, StringUtil::CandidatesErrorMessage(potential_names, name, "Did you mean")); } - //! it is! - auto &extension_option = entry->second; - auto &target_type = extension_option.type; - Value target_value = value.CastAs(context.client, target_type); - if (extension_option.set_function) { - extension_option.set_function(context.client, scope, target_value); - } - if (scope == SetScope::GLOBAL) { - config.SetOption(name, move(target_value)); - } else { - auto &client_config = ClientConfig::GetConfig(context.client); - client_config.set_variables[name] = move(target_value); - } + SetExtensionVariable(context.client, entry->second, name, scope, value); return; } SetScope variable_scope = scope; @@ -81015,9 +85164,9 @@ PhysicalStreamingLimit::PhysicalStreamingLimit(vector types, idx_t unique_ptr limit_expression, unique_ptr offset_expression, idx_t estimated_cardinality, bool parallel) - : PhysicalOperator(PhysicalOperatorType::STREAMING_LIMIT, move(types), estimated_cardinality), limit_value(limit), - offset_value(offset), limit_expression(move(limit_expression)), offset_expression(move(offset_expression)), - parallel(parallel) { + : PhysicalOperator(PhysicalOperatorType::STREAMING_LIMIT, std::move(types), estimated_cardinality), + limit_value(limit), offset_value(offset), limit_expression(std::move(limit_expression)), + offset_expression(std::move(offset_expression)), parallel(parallel) { } //===--------------------------------------------------------------------===// @@ -81128,7 +85277,7 @@ namespace duckdb { PhysicalStreamingSample::PhysicalStreamingSample(vector types, SampleMethod method, double percentage, int64_t seed, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::STREAMING_SAMPLE, move(types), estimated_cardinality), method(method), + : PhysicalOperator(PhysicalOperatorType::STREAMING_SAMPLE, std::move(types), estimated_cardinality), method(method), percentage(percentage / 100), seed(seed) { } @@ -81239,7 +85388,7 @@ class PhysicalTransaction : public PhysicalOperator { public: explicit PhysicalTransaction(unique_ptr info, idx_t estimated_cardinality) : PhysicalOperator(PhysicalOperatorType::TRANSACTION, {LogicalType::BOOLEAN}, estimated_cardinality), - info(move(info)) { + info(std::move(info)) { } unique_ptr info; @@ -81253,6 +85402,7 @@ class PhysicalTransaction : public PhysicalOperator { + namespace duckdb { void PhysicalTransaction::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, @@ -81399,6 +85549,8 @@ class LogicalGet : public LogicalOperator { vector input_table_types; //! The set of named input table names for the table-in table-out function vector input_table_names; + //! For a table-in-out function, the set of projected input columns + vector projected_input; string GetName() const override; string ParamsToString() const override; @@ -81421,11 +85573,12 @@ class LogicalGet : public LogicalOperator { + namespace duckdb { PhysicalVacuum::PhysicalVacuum(unique_ptr info_p, idx_t estimated_cardinality) : PhysicalOperator(PhysicalOperatorType::VACUUM, {LogicalType::BOOLEAN}, estimated_cardinality), - info(move(info_p)) { + info(std::move(info_p)) { } class VacuumLocalSinkState : public LocalSinkState { @@ -81488,8 +85641,8 @@ SinkFinalizeType PhysicalVacuum::Finalize(Pipeline &pipeline, Event &event, Clie auto table = info->table; for (idx_t col_idx = 0; col_idx < sink.column_distinct_stats.size(); col_idx++) { - table->storage->SetStatistics(info->column_id_map.at(col_idx), [&](BaseStatistics &stats) { - stats.distinct_stats = move(sink.column_distinct_stats[col_idx]); + table->GetStorage().SetStatistics(info->column_id_map.at(col_idx), [&](BaseStatistics &stats) { + stats.distinct_stats = std::move(sink.column_distinct_stats[col_idx]); }); } @@ -81937,7 +86090,7 @@ namespace duckdb { PerfectHashJoinExecutor::PerfectHashJoinExecutor(const PhysicalHashJoin &join_p, JoinHashTable &ht_p, PerfectHashJoinStats perfect_join_stats) - : join(join_p), ht(ht_p), perfect_join_statistics(move(perfect_join_stats)) { + : join(join_p), ht(ht_p), perfect_join_statistics(std::move(perfect_join_stats)) { } bool PerfectHashJoinExecutor::CanDoPerfectHashJoin() { @@ -82078,7 +86231,7 @@ class PerfectHashJoinState : public OperatorState { unique_ptr PerfectHashJoinExecutor::GetOperatorState(ExecutionContext &context) { auto state = make_unique(context.client, join); - return move(state); + return std::move(state); } OperatorResultType PerfectHashJoinExecutor::ProbePerfectHashTable(ExecutionContext &context, DataChunk &input, @@ -82337,7 +86490,7 @@ class PhysicalCrossProduct : public CachingPhysicalOperator { class CrossProductExecutor { public: - CrossProductExecutor(ColumnDataCollection &rhs); + explicit CrossProductExecutor(ColumnDataCollection &rhs); OperatorResultType Execute(DataChunk &input, DataChunk &output); @@ -82376,9 +86529,9 @@ PhysicalBlockwiseNLJoin::PhysicalBlockwiseNLJoin(LogicalOperator &op, unique_ptr unique_ptr right, unique_ptr condition, JoinType join_type, idx_t estimated_cardinality) : PhysicalJoin(op, PhysicalOperatorType::BLOCKWISE_NL_JOIN, join_type, estimated_cardinality), - condition(move(condition)) { - children.push_back(move(left)); - children.push_back(move(right)); + condition(std::move(condition)) { + children.push_back(std::move(left)); + children.push_back(std::move(right)); // MARK and SINGLE joins not handled D_ASSERT(join_type != JoinType::MARK); D_ASSERT(join_type != JoinType::SINGLE); @@ -82606,8 +86759,9 @@ string PhysicalComparisonJoin::ParamsToString() const { string op = ExpressionTypeToOperator(it.comparison); extra_info += it.left->GetName() + " " + op + " " + it.right->GetName() + "\n"; } - extra_info += "\nEC = " + std::to_string(estimated_props->GetCardinality()) + "\n"; - extra_info += "COST = " + std::to_string(estimated_props->GetCost()) + "\n"; + extra_info += "\n[INFOSEPARATOR]\n"; + extra_info += StringUtil::Format("EC: %llu\n", estimated_props->GetCardinality()); + extra_info += StringUtil::Format("Cost: %llu", (idx_t)estimated_props->GetCost()); return extra_info; } @@ -82667,9 +86821,9 @@ namespace duckdb { PhysicalCrossProduct::PhysicalCrossProduct(vector types, unique_ptr left, unique_ptr right, idx_t estimated_cardinality) - : CachingPhysicalOperator(PhysicalOperatorType::CROSS_PRODUCT, move(types), estimated_cardinality) { - children.push_back(move(left)); - children.push_back(move(right)); + : CachingPhysicalOperator(PhysicalOperatorType::CROSS_PRODUCT, std::move(types), estimated_cardinality) { + children.push_back(std::move(left)); + children.push_back(std::move(right)); } //===--------------------------------------------------------------------===// @@ -82828,7 +86982,7 @@ namespace duckdb { class PhysicalColumnDataScan : public PhysicalOperator { public: PhysicalColumnDataScan(vector types, PhysicalOperatorType op_type, idx_t estimated_cardinality) - : PhysicalOperator(op_type, move(types), estimated_cardinality), collection(nullptr) { + : PhysicalOperator(op_type, std::move(types), estimated_cardinality), collection(nullptr) { } // the column data collection to scan @@ -82912,18 +87066,18 @@ namespace duckdb { PhysicalDelimJoin::PhysicalDelimJoin(vector types, unique_ptr original_join, vector delim_scans, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::DELIM_JOIN, move(types), estimated_cardinality), join(move(original_join)), - delim_scans(move(delim_scans)) { + : PhysicalOperator(PhysicalOperatorType::DELIM_JOIN, std::move(types), estimated_cardinality), + join(std::move(original_join)), delim_scans(std::move(delim_scans)) { D_ASSERT(join->children.size() == 2); // now for the original join // we take its left child, this is the side that we will duplicate eliminate - children.push_back(move(join->children[0])); + children.push_back(std::move(join->children[0])); // we replace it with a PhysicalColumnDataScan, that scans the ColumnDataCollection that we keep cached // the actual chunk collection to scan will be created in the DelimJoinGlobalState auto cached_chunk_scan = make_unique( children[0]->GetTypes(), PhysicalOperatorType::COLUMN_DATA_SCAN, estimated_cardinality); - join->children[0] = move(cached_chunk_scan); + join->children[0] = std::move(cached_chunk_scan); } vector PhysicalDelimJoin::GetChildren() const { @@ -82980,13 +87134,13 @@ unique_ptr PhysicalDelimJoin::GetGlobalSinkState(ClientContext if (delim_scans.size() > 1) { PhysicalHashAggregate::SetMultiScan(*distinct->sink_state); } - return move(state); + return std::move(state); } unique_ptr PhysicalDelimJoin::GetLocalSinkState(ExecutionContext &context) const { auto state = make_unique(context.client, *this); state->distinct_state = distinct->GetLocalSinkState(context); - return move(state); + return std::move(state); } SinkResultType PhysicalDelimJoin::Sink(ExecutionContext &context, GlobalSinkState &state_p, LocalSinkState &lstate_p, @@ -83059,6 +87213,7 @@ void PhysicalDelimJoin::BuildPipelines(Pipeline ¤t, MetaPipeline &meta_pip + namespace duckdb { struct BitAndFun { @@ -83268,12 +87423,12 @@ PhysicalHashJoin::PhysicalHashJoin(LogicalOperator &op, unique_ptr &left_projection_map, const vector &right_projection_map_p, vector delim_types, idx_t estimated_cardinality, PerfectHashJoinStats perfect_join_stats) - : PhysicalComparisonJoin(op, PhysicalOperatorType::HASH_JOIN, move(cond), join_type, estimated_cardinality), - right_projection_map(right_projection_map_p), delim_types(move(delim_types)), - perfect_join_statistics(move(perfect_join_stats)) { + : PhysicalComparisonJoin(op, PhysicalOperatorType::HASH_JOIN, std::move(cond), join_type, estimated_cardinality), + right_projection_map(right_projection_map_p), delim_types(std::move(delim_types)), + perfect_join_statistics(std::move(perfect_join_stats)) { - children.push_back(move(left)); - children.push_back(move(right)); + children.push_back(std::move(left)); + children.push_back(std::move(right)); D_ASSERT(left_projection_map.empty()); for (auto &condition : conditions) { @@ -83289,8 +87444,8 @@ PhysicalHashJoin::PhysicalHashJoin(LogicalOperator &op, unique_ptr left, unique_ptr right, vector cond, JoinType join_type, idx_t estimated_cardinality, PerfectHashJoinStats perfect_join_state) - : PhysicalHashJoin(op, move(left), move(right), move(cond), join_type, {}, {}, {}, estimated_cardinality, - std::move(perfect_join_state)) { + : PhysicalHashJoin(op, std::move(left), std::move(right), std::move(cond), join_type, {}, {}, {}, + estimated_cardinality, std::move(perfect_join_state)) { } //===--------------------------------------------------------------------===// @@ -83400,17 +87555,17 @@ unique_ptr PhysicalHashJoin::InitializeHashTable(ClientContext &c AggregateType::NON_DISTINCT); correlated_aggregates.push_back(&*aggr); payload_types.push_back(aggr->return_type); - info.correlated_aggregates.push_back(move(aggr)); + info.correlated_aggregates.push_back(std::move(aggr)); auto count_fun = CountFun::GetFunction(); vector> children; // this is a dummy but we need it to make the hash table understand whats going on children.push_back(make_unique_base(count_fun.return_type, 0)); - aggr = - function_binder.BindAggregateFunction(count_fun, move(children), nullptr, AggregateType::NON_DISTINCT); + aggr = function_binder.BindAggregateFunction(count_fun, std::move(children), nullptr, + AggregateType::NON_DISTINCT); correlated_aggregates.push_back(&*aggr); payload_types.push_back(aggr->return_type); - info.correlated_aggregates.push_back(move(aggr)); + info.correlated_aggregates.push_back(std::move(aggr)); auto &allocator = Allocator::Get(context); info.correlated_counts = make_unique(context, allocator, delim_types, @@ -83473,7 +87628,7 @@ void PhysicalHashJoin::Combine(ExecutionContext &context, GlobalSinkState &gstat auto &lstate = (HashJoinLocalSinkState &)lstate_p; if (lstate.hash_table) { lock_guard local_ht_lock(gstate.lock); - gstate.local_hash_tables.push_back(move(lstate.hash_table)); + gstate.local_hash_tables.push_back(std::move(lstate.hash_table)); } auto &client_profiler = QueryProfiler::Get(context.client); context.thread.profiler.Flush(this, &lstate.build_executor, "build_executor", 1); @@ -83487,7 +87642,7 @@ class HashJoinFinalizeTask : public ExecutorTask { public: HashJoinFinalizeTask(shared_ptr event_p, ClientContext &context, HashJoinGlobalSinkState &sink, idx_t block_idx_start, idx_t block_idx_end, bool parallel) - : ExecutorTask(context), event(move(event_p)), sink(sink), block_idx_start(block_idx_start), + : ExecutorTask(context), event(std::move(event_p)), sink(sink), block_idx_start(block_idx_start), block_idx_end(block_idx_end), parallel(parallel) { } @@ -83543,7 +87698,7 @@ class HashJoinFinalizeEvent : public BasePipelineEvent { } } } - SetTasks(move(finalize_tasks)); + SetTasks(std::move(finalize_tasks)); } void FinishEvent() override { @@ -83560,7 +87715,7 @@ void HashJoinGlobalSinkState::ScheduleFinalize(Pipeline &pipeline, Event &event) } hash_table->InitializePointerTable(); auto new_event = make_shared(pipeline, *this); - event.InsertEvent(move(new_event)); + event.InsertEvent(std::move(new_event)); } void HashJoinGlobalSinkState::InitializeProbeSpill(ClientContext &context) { @@ -83574,7 +87729,7 @@ class HashJoinPartitionTask : public ExecutorTask { public: HashJoinPartitionTask(shared_ptr event_p, ClientContext &context, JoinHashTable &global_ht, JoinHashTable &local_ht) - : ExecutorTask(context), event(move(event_p)), global_ht(global_ht), local_ht(local_ht) { + : ExecutorTask(context), event(std::move(event_p)), global_ht(global_ht), local_ht(local_ht) { } TaskExecutionResult ExecuteTask(TaskExecutionMode mode) override { @@ -83609,7 +87764,7 @@ class HashJoinPartitionEvent : public BasePipelineEvent { partition_tasks.push_back( make_unique(shared_from_this(), context, *sink.hash_table, *local_ht)); } - SetTasks(move(partition_tasks)); + SetTasks(std::move(partition_tasks)); } void FinishEvent() override { @@ -83629,7 +87784,7 @@ SinkFinalizeType PhysicalHashJoin::Finalize(Pipeline &pipeline, Event &event, Cl sink.perfect_join_executor.reset(); sink.hash_table->ComputePartitionSizes(context.config, sink.local_hash_tables, sink.max_ht_size); auto new_event = make_shared(pipeline, sink, sink.local_hash_tables); - event.InsertEvent(move(new_event)); + event.InsertEvent(std::move(new_event)); sink.finalized = true; return SinkFinalizeType::READY; } else { @@ -83699,7 +87854,7 @@ unique_ptr PhysicalHashJoin::GetOperatorState(ExecutionContext &c sink.InitializeProbeSpill(context.client); } - return move(state); + return std::move(state); } OperatorResultType PhysicalHashJoin::ExecuteInternal(ExecutionContext &context, DataChunk &input, DataChunk &chunk, @@ -83728,7 +87883,7 @@ OperatorResultType PhysicalHashJoin::ExecuteInternal(ExecutionContext &context, } if (state.scan_structure) { - // still have elements remaining from the previous probe (i.e. we got >1024 elements in the previous probe) + // still have elements remaining (i.e. we got >STANDARD_VECTOR_SIZE elements in the previous probe) state.scan_structure->Next(state.join_keys, input, chunk); if (chunk.size() > 0) { return OperatorResultType::HAVE_MORE_OUTPUT; @@ -84048,7 +88203,7 @@ void HashJoinLocalSourceState::ExternalProbe(HashJoinGlobalSinkState &sink, Hash D_ASSERT(local_stage == HashJoinSourceStage::PROBE && sink.hash_table->finalized); if (scan_structure) { - // Still have elements remaining from the previous probe (i.e. we got >1024 elements in the previous probe) + // still have elements remaining (i.e. we got >STANDARD_VECTOR_SIZE elements in the previous probe) scan_structure->Next(join_keys, payload, chunk); if (chunk.size() == 0) { scan_structure = nullptr; @@ -84332,8 +88487,8 @@ namespace duckdb { PhysicalIEJoin::PhysicalIEJoin(LogicalOperator &op, unique_ptr left, unique_ptr right, vector cond, JoinType join_type, idx_t estimated_cardinality) - : PhysicalRangeJoin(op, PhysicalOperatorType::IE_JOIN, move(left), move(right), move(cond), join_type, - estimated_cardinality) { + : PhysicalRangeJoin(op, PhysicalOperatorType::IE_JOIN, std::move(left), std::move(right), std::move(cond), + join_type, estimated_cardinality) { // 1. let L1 (resp. L2) be the array of column X (resp. Y) D_ASSERT(conditions.size() >= 2); @@ -84365,8 +88520,8 @@ PhysicalIEJoin::PhysicalIEJoin(LogicalOperator &op, unique_ptr default: throw NotImplementedException("Unimplemented join type for IEJoin"); } - lhs_orders[i].emplace_back(BoundOrderByNode(sense, OrderByNullType::NULLS_LAST, move(left))); - rhs_orders[i].emplace_back(BoundOrderByNode(sense, OrderByNullType::NULLS_LAST, move(right))); + lhs_orders[i].emplace_back(BoundOrderByNode(sense, OrderByNullType::NULLS_LAST, std::move(left))); + rhs_orders[i].emplace_back(BoundOrderByNode(sense, OrderByNullType::NULLS_LAST, std::move(right))); } for (idx_t i = 2; i < conditions.size(); ++i) { @@ -84412,7 +88567,7 @@ class IEJoinGlobalState : public GlobalSinkState { } IEJoinGlobalState(IEJoinGlobalState &prev) - : GlobalSinkState(prev), tables(move(prev.tables)), child(prev.child + 1) { + : GlobalSinkState(prev), tables(std::move(prev.tables)), child(prev.child + 1) { } void Sink(DataChunk &input, IEJoinLocalState &lstate) { @@ -84699,7 +88854,7 @@ IEJoinUnion::IEJoinUnion(ClientContext &context, const PhysicalIEJoin &op, Sorte // Sort on the first expression auto ref = make_unique(order1.expression->return_type, 0); vector orders; - orders.emplace_back(BoundOrderByNode(order1.type, order1.null_order, move(ref))); + orders.emplace_back(BoundOrderByNode(order1.type, order1.null_order, std::move(ref))); l1 = make_unique(context, orders, payload_layout); @@ -84735,7 +88890,7 @@ IEJoinUnion::IEJoinUnion(ClientContext &context, const PhysicalIEJoin &op, Sorte // Sort on the first expression orders.clear(); ref = make_unique(order2.expression->return_type, 0); - orders.emplace_back(BoundOrderByNode(order2.type, order2.null_order, move(ref))); + orders.emplace_back(BoundOrderByNode(order2.type, order2.null_order, std::move(ref))); ExpressionExecutor executor(context); executor.AddExpression(*orders[0].expression); @@ -85497,52 +89652,7 @@ class PhysicalTableScan : public PhysicalOperator { } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/function/table/table_scan.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -namespace duckdb { -class TableCatalogEntry; - -struct TableScanBindData : public TableFunctionData { - explicit TableScanBindData(TableCatalogEntry *table) : table(table), is_index_scan(false), is_create_index(false) { - } - - //! The table to scan - TableCatalogEntry *table; - - //! Whether or not the table scan is an index scan - bool is_index_scan; - //! Whether or not the table scan is for index creation - bool is_create_index; - //! The row ids to fetch (in case of an index scan) - vector result_ids; - -public: - bool Equals(const FunctionData &other_p) const override { - auto &other = (const TableScanBindData &)other_p; - return other.table == table && result_ids == other.result_ids; - } -}; - -//! The table scan function represents a sequential scan over one of DuckDB's base tables. -struct TableScanFunction { - static void RegisterFunction(BuiltinFunctions &set); - static TableFunction GetFunction(); - static TableFunction GetIndexScanFunction(); - static TableCatalogEntry *GetTableEntry(const TableFunction &function, const FunctionData *bind_data); -}; -} // namespace duckdb @@ -85599,12 +89709,12 @@ PhysicalIndexJoin::PhysicalIndexJoin(LogicalOperator &op, unique_ptr &left_projection_map_p, vector right_projection_map_p, vector column_ids_p, Index *index_p, bool lhs_first, idx_t estimated_cardinality) - : CachingPhysicalOperator(PhysicalOperatorType::INDEX_JOIN, move(op.types), estimated_cardinality), - left_projection_map(left_projection_map_p), right_projection_map(move(right_projection_map_p)), index(index_p), - conditions(move(cond)), join_type(join_type), lhs_first(lhs_first) { - column_ids = move(column_ids_p); - children.push_back(move(left)); - children.push_back(move(right)); + : CachingPhysicalOperator(PhysicalOperatorType::INDEX_JOIN, std::move(op.types), estimated_cardinality), + left_projection_map(left_projection_map_p), right_projection_map(std::move(right_projection_map_p)), + index(index_p), conditions(std::move(cond)), join_type(join_type), lhs_first(lhs_first) { + column_ids = std::move(column_ids_p); + children.push_back(std::move(left)); + children.push_back(std::move(right)); for (auto &condition : conditions) { condition_types.push_back(condition.left->return_type); } @@ -85637,12 +89747,12 @@ unique_ptr PhysicalIndexJoin::GetOperatorState(ExecutionContext & void PhysicalIndexJoin::Output(ExecutionContext &context, DataChunk &input, DataChunk &chunk, OperatorState &state_p) const { - auto &transaction = Transaction::GetTransaction(context.client); auto &phy_tbl_scan = (PhysicalTableScan &)*children[1]; auto &bind_tbl = (TableScanBindData &)*phy_tbl_scan.bind_data; + auto &transaction = DuckTransaction::Get(context.client, *bind_tbl.table->catalog); auto &state = (IndexJoinOperatorState &)state_p; - auto tbl = bind_tbl.table->storage.get(); + auto &tbl = bind_tbl.table->GetStorage(); idx_t output_sel_idx = 0; vector fetch_rows; @@ -85668,7 +89778,7 @@ void PhysicalIndexJoin::Output(ExecutionContext &context, DataChunk &input, Data state.rhs_chunk.Reset(); state.fetch_state = make_unique(); Vector row_ids(LogicalType::ROW_TYPE, (data_ptr_t)&fetch_rows[0]); - tbl->Fetch(transaction, state.rhs_chunk, fetch_ids, row_ids, output_sel_idx, *state.fetch_state); + tbl.Fetch(transaction, state.rhs_chunk, fetch_ids, row_ids, output_sel_idx, *state.fetch_state); } //! Now we actually produce our result chunk @@ -85814,8 +89924,15 @@ void PhysicalJoin::BuildJoinPipelines(Pipeline ¤t, MetaPipeline &meta_pipe // continue building the current pipeline on the LHS (probe side) op.children[0]->BuildPipelines(current, meta_pipeline); - if (op.type == PhysicalOperatorType::CROSS_PRODUCT) { + switch (op.type) { + case PhysicalOperatorType::POSITIONAL_JOIN: + // Positional joins are always outer + meta_pipeline.CreateChildPipeline(current, &op, last_pipeline); + return; + case PhysicalOperatorType::CROSS_PRODUCT: return; + default: + break; } // Join can become a source operator if it's RIGHT/OUTER, or if the hash join goes out-of-core @@ -85953,9 +90070,10 @@ namespace duckdb { PhysicalNestedLoopJoin::PhysicalNestedLoopJoin(LogicalOperator &op, unique_ptr left, unique_ptr right, vector cond, JoinType join_type, idx_t estimated_cardinality) - : PhysicalComparisonJoin(op, PhysicalOperatorType::NESTED_LOOP_JOIN, move(cond), join_type, estimated_cardinality) { - children.push_back(move(left)); - children.push_back(move(right)); + : PhysicalComparisonJoin(op, PhysicalOperatorType::NESTED_LOOP_JOIN, std::move(cond), join_type, + estimated_cardinality) { + children.push_back(std::move(left)); + children.push_back(std::move(right)); } bool PhysicalJoin::HasNullValues(DataChunk &chunk) { @@ -86499,8 +90617,8 @@ namespace duckdb { PhysicalPiecewiseMergeJoin::PhysicalPiecewiseMergeJoin(LogicalOperator &op, unique_ptr left, unique_ptr right, vector cond, JoinType join_type, idx_t estimated_cardinality) - : PhysicalRangeJoin(op, PhysicalOperatorType::PIECEWISE_MERGE_JOIN, move(left), move(right), move(cond), join_type, - estimated_cardinality) { + : PhysicalRangeJoin(op, PhysicalOperatorType::PIECEWISE_MERGE_JOIN, std::move(left), std::move(right), + std::move(cond), join_type, estimated_cardinality) { for (auto &cond : conditions) { D_ASSERT(cond.left->return_type == cond.right->return_type); @@ -86512,20 +90630,25 @@ PhysicalPiecewiseMergeJoin::PhysicalPiecewiseMergeJoin(LogicalOperator &op, uniq switch (cond.comparison) { case ExpressionType::COMPARE_LESSTHAN: case ExpressionType::COMPARE_LESSTHANOREQUALTO: - lhs_orders.emplace_back(BoundOrderByNode(OrderType::ASCENDING, OrderByNullType::NULLS_LAST, move(left))); - rhs_orders.emplace_back(BoundOrderByNode(OrderType::ASCENDING, OrderByNullType::NULLS_LAST, move(right))); + lhs_orders.emplace_back( + BoundOrderByNode(OrderType::ASCENDING, OrderByNullType::NULLS_LAST, std::move(left))); + rhs_orders.emplace_back( + BoundOrderByNode(OrderType::ASCENDING, OrderByNullType::NULLS_LAST, std::move(right))); break; case ExpressionType::COMPARE_GREATERTHAN: case ExpressionType::COMPARE_GREATERTHANOREQUALTO: - lhs_orders.emplace_back(BoundOrderByNode(OrderType::DESCENDING, OrderByNullType::NULLS_LAST, move(left))); - rhs_orders.emplace_back(BoundOrderByNode(OrderType::DESCENDING, OrderByNullType::NULLS_LAST, move(right))); + lhs_orders.emplace_back( + BoundOrderByNode(OrderType::DESCENDING, OrderByNullType::NULLS_LAST, std::move(left))); + rhs_orders.emplace_back( + BoundOrderByNode(OrderType::DESCENDING, OrderByNullType::NULLS_LAST, std::move(right))); break; case ExpressionType::COMPARE_NOTEQUAL: case ExpressionType::COMPARE_DISTINCT_FROM: // Allowed in multi-predicate joins, but can't be first/sort. D_ASSERT(!lhs_orders.empty()); - lhs_orders.emplace_back(BoundOrderByNode(OrderType::INVALID, OrderByNullType::NULLS_LAST, move(left))); - rhs_orders.emplace_back(BoundOrderByNode(OrderType::INVALID, OrderByNullType::NULLS_LAST, move(right))); + lhs_orders.emplace_back(BoundOrderByNode(OrderType::INVALID, OrderByNullType::NULLS_LAST, std::move(left))); + rhs_orders.emplace_back( + BoundOrderByNode(OrderType::INVALID, OrderByNullType::NULLS_LAST, std::move(right))); break; default: @@ -87220,6 +91343,251 @@ void PhysicalPiecewiseMergeJoin::GetData(ExecutionContext &context, DataChunk &r } } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/execution/operator/join/physical_positional_join.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +//! PhysicalPositionalJoin represents a cross product between two tables +class PhysicalPositionalJoin : public PhysicalOperator { +public: + PhysicalPositionalJoin(vector types, unique_ptr left, + unique_ptr right, idx_t estimated_cardinality); + +public: + // Operator Interface + OperatorResultType Execute(ExecutionContext &context, DataChunk &input, DataChunk &chunk, + GlobalOperatorState &gstate, OperatorState &state) const override; + +public: + // Source interface + void GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, + LocalSourceState &lstate) const override; + + bool IsSource() const override { + return true; + } + +public: + // Sink Interface + unique_ptr GetGlobalSinkState(ClientContext &context) const override; + SinkResultType Sink(ExecutionContext &context, GlobalSinkState &state, LocalSinkState &lstate, + DataChunk &input) const override; + + bool IsSink() const override { + return true; + } + +public: + void BuildPipelines(Pipeline ¤t, MetaPipeline &meta_pipeline) override; + vector GetSources() const override; +}; +} // namespace duckdb + + + + + + +namespace duckdb { + +PhysicalPositionalJoin::PhysicalPositionalJoin(vector types, unique_ptr left, + unique_ptr right, idx_t estimated_cardinality) + : PhysicalOperator(PhysicalOperatorType::POSITIONAL_JOIN, std::move(types), estimated_cardinality) { + children.push_back(std::move(left)); + children.push_back(std::move(right)); +} + +//===--------------------------------------------------------------------===// +// Sink +//===--------------------------------------------------------------------===// +class PositionalJoinGlobalState : public GlobalSinkState { +public: + explicit PositionalJoinGlobalState(ClientContext &context, const PhysicalPositionalJoin &op) + : rhs(context, op.children[1]->GetTypes()), initialized(false), source_offset(0), exhausted(false) { + rhs.InitializeAppend(append_state); + } + + ColumnDataCollection rhs; + ColumnDataAppendState append_state; + mutex rhs_lock; + + bool initialized; + ColumnDataScanState scan_state; + DataChunk source; + idx_t source_offset; + bool exhausted; + + void InitializeScan(); + idx_t Refill(); + idx_t CopyData(DataChunk &output, const idx_t count, const idx_t col_offset); + void Execute(DataChunk &input, DataChunk &output); + void GetData(DataChunk &output); +}; + +unique_ptr PhysicalPositionalJoin::GetGlobalSinkState(ClientContext &context) const { + return make_unique(context, *this); +} + +SinkResultType PhysicalPositionalJoin::Sink(ExecutionContext &context, GlobalSinkState &state, LocalSinkState &lstate_p, + DataChunk &input) const { + auto &sink = (PositionalJoinGlobalState &)state; + lock_guard client_guard(sink.rhs_lock); + sink.rhs.Append(sink.append_state, input); + return SinkResultType::NEED_MORE_INPUT; +} + +//===--------------------------------------------------------------------===// +// Operator +//===--------------------------------------------------------------------===// +void PositionalJoinGlobalState::InitializeScan() { + if (!initialized) { + // not initialized yet: initialize the scan + initialized = true; + rhs.InitializeScanChunk(source); + rhs.InitializeScan(scan_state); + } +} + +idx_t PositionalJoinGlobalState::Refill() { + if (source_offset >= source.size()) { + if (!exhausted) { + source.Reset(); + rhs.Scan(scan_state, source); + } + source_offset = 0; + } + + const auto available = source.size() - source_offset; + if (!available) { + if (!exhausted) { + source.Reset(); + for (idx_t i = 0; i < source.ColumnCount(); ++i) { + auto &vec = source.data[i]; + vec.SetVectorType(VectorType::CONSTANT_VECTOR); + ConstantVector::SetNull(vec, true); + } + exhausted = true; + } + } + + return available; +} + +idx_t PositionalJoinGlobalState::CopyData(DataChunk &output, const idx_t count, const idx_t col_offset) { + if (!source_offset && (source.size() >= count || exhausted)) { + // Fast track: aligned and has enough data + for (idx_t i = 0; i < source.ColumnCount(); ++i) { + output.data[col_offset + i].Reference(source.data[i]); + } + source_offset += count; + } else { + // Copy data + for (idx_t target_offset = 0; target_offset < count;) { + const auto needed = count - target_offset; + const auto available = exhausted ? needed : (source.size() - source_offset); + const auto copy_size = MinValue(needed, available); + const auto source_count = source_offset + copy_size; + for (idx_t i = 0; i < source.ColumnCount(); ++i) { + VectorOperations::Copy(source.data[i], output.data[col_offset + i], source_count, source_offset, + target_offset); + } + target_offset += copy_size; + source_offset += copy_size; + Refill(); + } + } + + return source.ColumnCount(); +} + +void PositionalJoinGlobalState::Execute(DataChunk &input, DataChunk &output) { + lock_guard client_guard(rhs_lock); + + // Reference the input and assume it will be full + const auto col_offset = input.ColumnCount(); + for (idx_t i = 0; i < col_offset; ++i) { + output.data[i].Reference(input.data[i]); + } + + // Copy or reference the RHS columns + const auto count = input.size(); + InitializeScan(); + Refill(); + CopyData(output, count, col_offset); + + output.SetCardinality(count); +} + +OperatorResultType PhysicalPositionalJoin::Execute(ExecutionContext &context, DataChunk &input, DataChunk &chunk, + GlobalOperatorState &gstate, OperatorState &state_p) const { + auto &sink = (PositionalJoinGlobalState &)*sink_state; + sink.Execute(input, chunk); + return OperatorResultType::NEED_MORE_INPUT; +} + +//===--------------------------------------------------------------------===// +// Source +//===--------------------------------------------------------------------===// +void PositionalJoinGlobalState::GetData(DataChunk &output) { + lock_guard client_guard(rhs_lock); + + InitializeScan(); + Refill(); + + // LHS exhausted + if (exhausted) { + // RHS exhausted too, so we are done + output.SetCardinality(0); + return; + } + + // LHS is all NULL + const auto col_offset = output.ColumnCount() - source.ColumnCount(); + for (idx_t i = 0; i < col_offset; ++i) { + auto &vec = output.data[i]; + vec.SetVectorType(VectorType::CONSTANT_VECTOR); + ConstantVector::SetNull(vec, true); + } + + // RHS still has data, so copy it + const auto count = MinValue(STANDARD_VECTOR_SIZE, source.size() - source_offset); + CopyData(output, count, col_offset); + output.SetCardinality(count); +} + +void PhysicalPositionalJoin::GetData(ExecutionContext &context, DataChunk &result, GlobalSourceState &gstate, + LocalSourceState &lstate) const { + auto &sink = (PositionalJoinGlobalState &)*sink_state; + sink.GetData(result); +} + +//===--------------------------------------------------------------------===// +// Pipeline Construction +//===--------------------------------------------------------------------===// +void PhysicalPositionalJoin::BuildPipelines(Pipeline ¤t, MetaPipeline &meta_pipeline) { + PhysicalJoin::BuildJoinPipelines(current, meta_pipeline, *this); +} + +vector PhysicalPositionalJoin::GetSources() const { + auto result = children[0]->GetSources(); + if (IsSource()) { + result.push_back(this); + } + return result; +} + +} // namespace duckdb @@ -87308,7 +91676,7 @@ class RangeJoinMergeTask : public ExecutorTask { public: RangeJoinMergeTask(shared_ptr event_p, ClientContext &context, GlobalSortedTable &table) - : ExecutorTask(context), event(move(event_p)), context(context), table(table) { + : ExecutorTask(context), event(std::move(event_p)), context(context), table(table) { } TaskExecutionResult ExecuteTask(TaskExecutionMode mode) override { @@ -87350,7 +91718,7 @@ class RangeJoinMergeEvent : public BasePipelineEvent { for (idx_t tnum = 0; tnum < num_threads; tnum++) { iejoin_tasks.push_back(make_unique(shared_from_this(), context, table)); } - SetTasks(move(iejoin_tasks)); + SetTasks(std::move(iejoin_tasks)); } void FinishEvent() override { @@ -87368,7 +91736,7 @@ void PhysicalRangeJoin::GlobalSortedTable::ScheduleMergeTasks(Pipeline &pipeline // Initialize global sort state for a round of merging global_sort_state.InitializeMergeRound(); auto new_event = make_shared(*this, pipeline); - event.InsertEvent(move(new_event)); + event.InsertEvent(std::move(new_event)); } void PhysicalRangeJoin::GlobalSortedTable::Finalize(Pipeline &pipeline, Event &event) { @@ -87384,7 +91752,7 @@ void PhysicalRangeJoin::GlobalSortedTable::Finalize(Pipeline &pipeline, Event &e PhysicalRangeJoin::PhysicalRangeJoin(LogicalOperator &op, PhysicalOperatorType type, unique_ptr left, unique_ptr right, vector cond, JoinType join_type, idx_t estimated_cardinality) - : PhysicalComparisonJoin(op, type, move(cond), join_type, estimated_cardinality) { + : PhysicalComparisonJoin(op, type, std::move(cond), join_type, estimated_cardinality) { // Reorder the conditions so that ranges are at the front. // TODO: use stats to improve the choice? // TODO: Prefer fixed length types? @@ -87408,8 +91776,8 @@ PhysicalRangeJoin::PhysicalRangeJoin(LogicalOperator &op, PhysicalOperatorType t } } - children.push_back(move(left)); - children.push_back(move(right)); + children.push_back(std::move(left)); + children.push_back(std::move(right)); } idx_t PhysicalRangeJoin::LocalSortedTable::MergeNulls(const vector &conditions) { @@ -87537,7 +91905,7 @@ BufferHandle PhysicalRangeJoin::SliceSortedPayload(DataChunk &payload, GlobalSor col.Slice(gsel, result_count); } - return move(read_state.payload_heap_handle); + return std::move(read_state.payload_heap_handle); } idx_t PhysicalRangeJoin::SelectJoinTail(const ExpressionType &condition, Vector &left, Vector &right, @@ -87582,7 +91950,7 @@ idx_t PhysicalRangeJoin::SelectJoinTail(const ExpressionType &condition, Vector namespace duckdb { -class OrderGlobalState; +class OrderGlobalSinkState; //! Physically re-orders the input data class PhysicalOrder : public PhysicalOperator { @@ -87596,18 +91964,30 @@ class PhysicalOrder : public PhysicalOperator { public: // Source interface + unique_ptr GetLocalSourceState(ExecutionContext &context, + GlobalSourceState &gstate) const override; unique_ptr GetGlobalSourceState(ClientContext &context) const override; void GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, LocalSourceState &lstate) const override; + idx_t GetBatchIndex(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, + LocalSourceState &lstate) const override; - bool IsOrderPreserving() const override { + bool IsSource() const override { return false; } + bool ParallelSource() const override { + return true; + } + + bool SupportsBatchIndex() const override { + return true; + } + public: + // Sink interface unique_ptr GetLocalSinkState(ExecutionContext &context) const override; unique_ptr GetGlobalSinkState(ClientContext &context) const override; - SinkResultType Sink(ExecutionContext &context, GlobalSinkState &gstate_p, LocalSinkState &lstate_p, DataChunk &input) const override; void Combine(ExecutionContext &context, GlobalSinkState &gstate_p, LocalSinkState &lstate_p) const override; @@ -87621,10 +92001,11 @@ class PhysicalOrder : public PhysicalOperator { return true; } +public: string ParamsToString() const override; //! Schedules tasks to merge the data during the Finalize phase - static void ScheduleMergeTasks(Pipeline &pipeline, Event &event, OrderGlobalState &state); + static void ScheduleMergeTasks(Pipeline &pipeline, Event &event, OrderGlobalSinkState &state); }; } // namespace duckdb @@ -87641,16 +92022,16 @@ namespace duckdb { PhysicalOrder::PhysicalOrder(vector types, vector orders, vector projections, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::ORDER_BY, move(types), estimated_cardinality), orders(move(orders)), - projections(move(projections)) { + : PhysicalOperator(PhysicalOperatorType::ORDER_BY, std::move(types), estimated_cardinality), + orders(std::move(orders)), projections(std::move(projections)) { } //===--------------------------------------------------------------------===// // Sink //===--------------------------------------------------------------------===// -class OrderGlobalState : public GlobalSinkState { +class OrderGlobalSinkState : public GlobalSinkState { public: - OrderGlobalState(BufferManager &buffer_manager, const PhysicalOrder &order, RowLayout &payload_layout) + OrderGlobalSinkState(BufferManager &buffer_manager, const PhysicalOrder &order, RowLayout &payload_layout) : global_sort_state(buffer_manager, order.orders, payload_layout) { } @@ -87660,9 +92041,9 @@ class OrderGlobalState : public GlobalSinkState { idx_t memory_per_thread; }; -class OrderLocalState : public LocalSinkState { +class OrderLocalSinkState : public LocalSinkState { public: - OrderLocalState(ClientContext &context, const PhysicalOrder &op) : key_executor(context) { + OrderLocalSinkState(ClientContext &context, const PhysicalOrder &op) : key_executor(context) { // Initialize order clause expression executor and DataChunk vector key_types; for (auto &order : op.orders) { @@ -87688,21 +92069,21 @@ unique_ptr PhysicalOrder::GetGlobalSinkState(ClientContext &con // Get the payload layout from the return types RowLayout payload_layout; payload_layout.Initialize(types); - auto state = make_unique(BufferManager::GetBufferManager(context), *this, payload_layout); + auto state = make_unique(BufferManager::GetBufferManager(context), *this, payload_layout); // Set external (can be force with the PRAGMA) state->global_sort_state.external = ClientConfig::GetConfig(context).force_external; state->memory_per_thread = GetMaxThreadMemory(context); - return move(state); + return std::move(state); } unique_ptr PhysicalOrder::GetLocalSinkState(ExecutionContext &context) const { - return make_unique(context.client, *this); + return make_unique(context.client, *this); } SinkResultType PhysicalOrder::Sink(ExecutionContext &context, GlobalSinkState &gstate_p, LocalSinkState &lstate_p, DataChunk &input) const { - auto &gstate = (OrderGlobalState &)gstate_p; - auto &lstate = (OrderLocalState &)lstate_p; + auto &gstate = (OrderGlobalSinkState &)gstate_p; + auto &lstate = (OrderLocalSinkState &)lstate_p; auto &global_sort_state = gstate.global_sort_state; auto &local_sort_state = lstate.local_sort_state; @@ -87733,15 +92114,15 @@ SinkResultType PhysicalOrder::Sink(ExecutionContext &context, GlobalSinkState &g } void PhysicalOrder::Combine(ExecutionContext &context, GlobalSinkState &gstate_p, LocalSinkState &lstate_p) const { - auto &gstate = (OrderGlobalState &)gstate_p; - auto &lstate = (OrderLocalState &)lstate_p; + auto &gstate = (OrderGlobalSinkState &)gstate_p; + auto &lstate = (OrderLocalSinkState &)lstate_p; gstate.global_sort_state.AddLocalState(lstate.local_sort_state); } class PhysicalOrderMergeTask : public ExecutorTask { public: - PhysicalOrderMergeTask(shared_ptr event_p, ClientContext &context, OrderGlobalState &state) - : ExecutorTask(context), event(move(event_p)), context(context), state(state) { + PhysicalOrderMergeTask(shared_ptr event_p, ClientContext &context, OrderGlobalSinkState &state) + : ExecutorTask(context), event(std::move(event_p)), context(context), state(state) { } TaskExecutionResult ExecuteTask(TaskExecutionMode mode) override { @@ -87756,16 +92137,16 @@ class PhysicalOrderMergeTask : public ExecutorTask { private: shared_ptr event; ClientContext &context; - OrderGlobalState &state; + OrderGlobalSinkState &state; }; class OrderMergeEvent : public BasePipelineEvent { public: - OrderMergeEvent(OrderGlobalState &gstate_p, Pipeline &pipeline_p) + OrderMergeEvent(OrderGlobalSinkState &gstate_p, Pipeline &pipeline_p) : BasePipelineEvent(pipeline_p), gstate(gstate_p) { } - OrderGlobalState &gstate; + OrderGlobalSinkState &gstate; public: void Schedule() override { @@ -87779,7 +92160,7 @@ class OrderMergeEvent : public BasePipelineEvent { for (idx_t tnum = 0; tnum < num_threads; tnum++) { merge_tasks.push_back(make_unique(shared_from_this(), context, gstate)); } - SetTasks(move(merge_tasks)); + SetTasks(std::move(merge_tasks)); } void FinishEvent() override { @@ -87795,7 +92176,7 @@ class OrderMergeEvent : public BasePipelineEvent { SinkFinalizeType PhysicalOrder::Finalize(Pipeline &pipeline, Event &event, ClientContext &context, GlobalSinkState &gstate_p) const { - auto &state = (OrderGlobalState &)gstate_p; + auto &state = (OrderGlobalSinkState &)gstate_p; auto &global_sort_state = state.global_sort_state; if (global_sort_state.sorted_blocks.empty()) { @@ -87813,43 +92194,86 @@ SinkFinalizeType PhysicalOrder::Finalize(Pipeline &pipeline, Event &event, Clien return SinkFinalizeType::READY; } -void PhysicalOrder::ScheduleMergeTasks(Pipeline &pipeline, Event &event, OrderGlobalState &state) { +void PhysicalOrder::ScheduleMergeTasks(Pipeline &pipeline, Event &event, OrderGlobalSinkState &state) { // Initialize global sort state for a round of merging state.global_sort_state.InitializeMergeRound(); auto new_event = make_shared(state, pipeline); - event.InsertEvent(move(new_event)); + event.InsertEvent(std::move(new_event)); } //===--------------------------------------------------------------------===// // Source //===--------------------------------------------------------------------===// -class PhysicalOrderOperatorState : public GlobalSourceState { +class PhysicalOrderGlobalSourceState : public GlobalSourceState { public: - //! Payload scanner - unique_ptr scanner; + explicit PhysicalOrderGlobalSourceState(OrderGlobalSinkState &sink) : next_batch_index(0) { + auto &global_sort_state = sink.global_sort_state; + if (global_sort_state.sorted_blocks.empty()) { + total_batches = 0; + } else { + D_ASSERT(global_sort_state.sorted_blocks.size() == 1); + total_batches = global_sort_state.sorted_blocks[0]->payload_data->data_blocks.size(); + } + } + + idx_t MaxThreads() override { + return total_batches; + } + +public: + atomic next_batch_index; + idx_t total_batches; }; unique_ptr PhysicalOrder::GetGlobalSourceState(ClientContext &context) const { - return make_unique(); + auto &sink = (OrderGlobalSinkState &)*this->sink_state; + return make_unique(sink); } -void PhysicalOrder::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, - LocalSourceState &lstate) const { - auto &state = (PhysicalOrderOperatorState &)gstate; +class PhysicalOrderLocalSourceState : public LocalSourceState { +public: + explicit PhysicalOrderLocalSourceState(PhysicalOrderGlobalSourceState &gstate) + : batch_index(gstate.next_batch_index++) { + } - if (!state.scanner) { - // Initialize scanner (if not yet initialized) - auto &gstate = (OrderGlobalState &)*this->sink_state; - auto &global_sort_state = gstate.global_sort_state; - if (global_sort_state.sorted_blocks.empty()) { - return; - } - state.scanner = - make_unique(*global_sort_state.sorted_blocks[0]->payload_data, global_sort_state); +public: + idx_t batch_index; + unique_ptr scanner; +}; + +unique_ptr PhysicalOrder::GetLocalSourceState(ExecutionContext &context, + GlobalSourceState &gstate_p) const { + auto &gstate = (PhysicalOrderGlobalSourceState &)gstate_p; + return make_unique(gstate); +} + +void PhysicalOrder::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate_p, + LocalSourceState &lstate_p) const { + auto &gstate = (PhysicalOrderGlobalSourceState &)gstate_p; + auto &lstate = (PhysicalOrderLocalSourceState &)lstate_p; + + if (lstate.scanner && lstate.scanner->Remaining() == 0) { + lstate.batch_index = gstate.next_batch_index++; + lstate.scanner = nullptr; + } + + if (lstate.batch_index >= gstate.total_batches) { + return; + } + + if (!lstate.scanner) { + auto &sink = (OrderGlobalSinkState &)*this->sink_state; + auto &global_sort_state = sink.global_sort_state; + lstate.scanner = make_unique(global_sort_state, lstate.batch_index, true); } - // Scan the next data chunk - state.scanner->Scan(chunk); + lstate.scanner->Scan(chunk); +} + +idx_t PhysicalOrder::GetBatchIndex(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate_p, + LocalSourceState &lstate_p) const { + auto &lstate = (PhysicalOrderLocalSourceState &)lstate_p; + return lstate.batch_index; } string PhysicalOrder::ParamsToString() const { @@ -87932,7 +92356,7 @@ namespace duckdb { PhysicalTopN::PhysicalTopN(vector types, vector orders, idx_t limit, idx_t offset, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::TOP_N, move(types), estimated_cardinality), orders(move(orders)), + : PhysicalOperator(PhysicalOperatorType::TOP_N, std::move(types), estimated_cardinality), orders(std::move(orders)), limit(limit), offset(offset) { } @@ -88052,8 +92476,8 @@ void TopNSortState::Sink(DataChunk &input) { } void TopNSortState::Move(TopNSortState &other) { - local_state = move(other.local_state); - global_state = move(other.global_state); + local_state = std::move(other.local_state); + global_state = std::move(other.global_state); count = other.count; is_sorted = other.is_sorted; } @@ -88558,7 +92982,8 @@ struct StrfTimeFormat : public StrTimeFormat { char *WritePadded(char *target, uint32_t value, size_t padding); bool IsDateSpecifier(StrTimeSpecifier specifier); char *WriteDateSpecifier(StrTimeSpecifier specifier, date_t date, char *target); - char *WriteStandardSpecifier(StrTimeSpecifier specifier, int32_t data[], const char *tz_name, char *target); + char *WriteStandardSpecifier(StrTimeSpecifier specifier, int32_t data[], const char *tz_name, size_t tz_len, + char *target); }; struct StrpTimeFormat : public StrTimeFormat { @@ -88584,8 +93009,8 @@ struct StrpTimeFormat : public StrTimeFormat { DUCKDB_API bool Parse(string_t str, ParseResult &result); - bool TryParseDate(string_t str, date_t &result, string &error_message); - bool TryParseTimestamp(string_t str, timestamp_t &result, string &error_message); + DUCKDB_API bool TryParseDate(string_t str, date_t &result, string &error_message); + DUCKDB_API bool TryParseTimestamp(string_t str, timestamp_t &result, string &error_message); date_t ParseDate(string_t str); timestamp_t ParseTimestamp(string_t str); @@ -88642,7 +93067,7 @@ namespace duckdb { struct CSVFileHandle { public: - explicit CSVFileHandle(unique_ptr file_handle_p) : file_handle(move(file_handle_p)) { + explicit CSVFileHandle(unique_ptr file_handle_p) : file_handle(std::move(file_handle_p)) { can_seek = file_handle->CanSeek(); plain_file_source = file_handle->OnDiskFile() && can_seek; file_size = file_handle->GetFileSize(); @@ -88725,7 +93150,7 @@ struct CSVFileHandle { if (buffer_size > 0) { memcpy(new_buffer.get(), cached_buffer.get(), buffer_size); } - cached_buffer = move(new_buffer); + cached_buffer = std::move(new_buffer); } memcpy(cached_buffer.get() + buffer_size, (char *)buffer + result_offset, bytes_read); buffer_size += bytes_read; @@ -88799,13 +93224,15 @@ class CSVBuffer { static constexpr idx_t INITIAL_BUFFER_SIZE_COLOSSAL = 32000000; // 32MB //! Constructor for Initial Buffer - CSVBuffer(ClientContext &context, idx_t buffer_size_p, CSVFileHandle &file_handle); + CSVBuffer(ClientContext &context, idx_t buffer_size_p, CSVFileHandle &file_handle, + idx_t &global_csv_current_position); //! Constructor for `Next()` Buffers - CSVBuffer(ClientContext &context, BufferHandle handle, idx_t buffer_size_p, idx_t actual_size_p, bool final_buffer); + CSVBuffer(ClientContext &context, BufferHandle handle, idx_t buffer_size_p, idx_t actual_size_p, bool final_buffer, + idx_t global_csv_current_position); //! Creates a new buffer with the next part of the CSV File - unique_ptr Next(CSVFileHandle &file_handle, idx_t set_buffer_size); + unique_ptr Next(CSVFileHandle &file_handle, idx_t buffer_size, idx_t &global_csv_current_position); //! Gets the buffer actual size idx_t GetBufferSize(); @@ -88819,6 +93246,8 @@ class CSVBuffer { //! If this buffer is the first buffer of the CSV File bool IsCSVFileFirstBuffer(); + idx_t GetCSVGlobalStart(); + BufferHandle AllocateBuffer(idx_t buffer_size); char *Ptr() { @@ -88838,6 +93267,8 @@ class CSVBuffer { bool last_buffer = false; //! If this is the first buffer of the CSV File bool first_buffer = false; + //! Global position from the CSV File where this buffer starts + idx_t global_csv_start = 0; }; } // namespace duckdb @@ -88846,8 +93277,16 @@ class CSVBuffer { + namespace duckdb { +enum NewLineIdentifier { + SINGLE = 1, // Either \r or \n + CARRY_ON = 2, // \r\n + MIX = 3, // Hippie-Land, can't run it multithreaded + NOT_SET = 4 +}; + struct BufferedCSVReaderOptions { //===--------------------------------------------------------------------===// // CommonCSVOptions @@ -88857,7 +93296,16 @@ struct BufferedCSVReaderOptions { bool has_delimiter = false; //! Delimiter to separate columns within each line string delimiter = ","; - //! Whether or not a quote sign was defined by the user + //! Whether or not a new_line was defined by the user + bool has_newline = false; + //! New Line separator + NewLineIdentifier new_line = NewLineIdentifier::NOT_SET; + + //! Whether or not an option was provided for parallel + bool has_parallel = false; + //! Whether or not the read will use the ParallelCSVReader + bool use_parallel = false; + //! Whether or not a quote was defined by the user bool has_quote = false; //! Quote used for columns that contain reserved characters, e.g., delimiter string quote = "\""; @@ -88883,6 +93331,13 @@ struct BufferedCSVReaderOptions { //! The column names of the columns to read/write vector names; + //===--------------------------------------------------------------------===// + // CSVAutoOptions + //===--------------------------------------------------------------------===// + //! SQL Type list mapping of name to SQL type index in sql_type_list + case_insensitive_map_t sql_types_per_column; + //! User-defined SQL type list + vector sql_type_list; //===--------------------------------------------------------------------===// // ReadCSVOptions //===--------------------------------------------------------------------===// @@ -88914,6 +93369,8 @@ struct BufferedCSVReaderOptions { bool union_by_name = false; //! Buffer Size (Parallel Scan) idx_t buffer_size = CSVBuffer::INITIAL_BUFFER_SIZE_COLOSSAL; + //! Decimal separator when reading as numeric + string decimal_separator = "."; //===--------------------------------------------------------------------===// // WriteCSVOptions @@ -88933,7 +93390,14 @@ struct BufferedCSVReaderOptions { void Serialize(FieldWriter &writer) const; void Deserialize(FieldReader &reader); + void SetCompression(const string &compression); + void SetHeader(bool has_header); + void SetEscape(const string &escape); + void SetQuote(const string "e); void SetDelimiter(const string &delimiter); + void SetParallel(bool use_parallel); + + void SetNewline(const string &input); //! Set an option that is supported by both reading and writing functions, called by //! the SetReadOption and SetWriteOption methods bool SetBaseOption(const string &loption, const Value &value); @@ -88978,13 +93442,15 @@ class BaseCSVReader { Allocator &allocator; FileOpener *opener; BufferedCSVReaderOptions options; - vector sql_types; - vector col_names; + vector return_types; + vector names; //! remap parse_chunk col to insert_chunk col, because when //! union_by_name option on insert_chunk may have more cols vector insert_cols_idx; - vector insert_nulls_idx; + vector union_idx_map; + vector union_null_cols; + vector union_col_types; idx_t linenr = 0; bool linenr_estimated = false; @@ -89004,10 +93470,6 @@ class BaseCSVReader { ParserMode mode; -public: - //! Fill nulls into the cols that mismtach union names - void SetNullUnionCols(DataChunk &insert_chunk); - protected: //! Initializes the parse_chunk with varchar columns and aligns info with new number of cols void InitParseChunk(idx_t num_cols); @@ -89023,7 +93485,7 @@ class BaseCSVReader { //! Adds a value to the current row void AddValue(string_t str_val, idx_t &column, vector &escape_positions, bool has_quotes); //! Adds a row to the insert_chunk, returns true if the chunk is filled as a result of this row being added - bool AddRow(DataChunk &insert_chunk, idx_t &column); + bool AddRow(DataChunk &insert_chunk, idx_t &column, string &error_message); //! Finalizes a chunk, parsing all values that have been added so far and adding them to the insert_chunk bool Flush(DataChunk &insert_chunk, bool try_add_line = false); @@ -89033,8 +93495,11 @@ class BaseCSVReader { void VerifyUTF8(idx_t col_idx, idx_t row_idx, DataChunk &chunk, int64_t offset = 0); static string GetLineNumberStr(idx_t linenr, bool linenr_estimated); + //! Sets the newline delimiter + void SetNewLineDelimiter(bool carry = false, bool carry_followed_by_nl = false); + protected: - //! Whether or not the current row's columns have overflown sql_types.size() + //! Whether or not the current row's columns have overflown return_types.size() bool error_column_overflow = false; //! Number of sniffed columns - only used when auto-detecting vector sniffed_column_counts; @@ -89059,6 +93524,8 @@ class BaseCSVReader { + + #include #include #include @@ -89073,13 +93540,13 @@ string BaseCSVReader::GetLineNumberStr(idx_t linenr, bool linenr_estimated) { BaseCSVReader::BaseCSVReader(FileSystem &fs_p, Allocator &allocator, FileOpener *opener_p, BufferedCSVReaderOptions options_p, const vector &requested_types) - : fs(fs_p), allocator(allocator), opener(opener_p), options(move(options_p)) { + : fs(fs_p), allocator(allocator), opener(opener_p), options(std::move(options_p)) { } BaseCSVReader::BaseCSVReader(ClientContext &context, BufferedCSVReaderOptions options_p, const vector &requested_types) : BaseCSVReader(FileSystem::GetFileSystem(context), Allocator::Get(context), FileSystem::GetFileOpener(context), - move(options_p), requested_types) { + std::move(options_p), requested_types) { } BaseCSVReader::~BaseCSVReader() { @@ -89088,7 +93555,7 @@ BaseCSVReader::~BaseCSVReader() { unique_ptr BaseCSVReader::OpenCSV(const BufferedCSVReaderOptions &options_p) { auto file_handle = fs.OpenFile(options_p.file_path.c_str(), FileFlags::FILE_FLAGS_READ, FileLockType::NO_LOCK, options_p.compression, this->opener); - return make_unique(move(file_handle)); + return make_unique(std::move(file_handle)); } void BaseCSVReader::InitParseChunk(idx_t num_cols) { @@ -89120,6 +93587,52 @@ void BaseCSVReader::SetDateFormat(const string &format_specifier, const LogicalT StrTimeFormat::ParseFormatSpecifier(date_format.format_specifier, date_format); } +struct TryCastDecimalOperator { + template + static bool Operation(string_t input, uint8_t width, uint8_t scale) { + T result; + string error_message; + return OP::Operation(input, result, &error_message, width, scale); + } +}; + +struct TryCastFloatingOperator { + template + static bool Operation(string_t input) { + T result; + string error_message; + return OP::Operation(input, result, &error_message); + } +}; + +bool TryCastDecimalValueCommaSeparated(const string_t &value_str, const LogicalType &sql_type) { + auto width = DecimalType::GetWidth(sql_type); + auto scale = DecimalType::GetScale(sql_type); + switch (sql_type.InternalType()) { + case PhysicalType::INT16: + return TryCastDecimalOperator::Operation(value_str, width, scale); + case PhysicalType::INT32: + return TryCastDecimalOperator::Operation(value_str, width, scale); + case PhysicalType::INT64: + return TryCastDecimalOperator::Operation(value_str, width, scale); + case PhysicalType::INT128: + return TryCastDecimalOperator::Operation(value_str, width, scale); + default: + throw InternalException("Unimplemented physical type for decimal"); + } +} + +bool TryCastFloatingValueCommaSeparated(const string_t &value_str, const LogicalType &sql_type) { + switch (sql_type.InternalType()) { + case PhysicalType::DOUBLE: + return TryCastFloatingOperator::Operation(value_str); + case PhysicalType::FLOAT: + return TryCastFloatingOperator::Operation(value_str); + default: + throw InternalException("Unimplemented physical type for floating"); + } +} + bool BaseCSVReader::TryCastValue(const Value &value, const LogicalType &sql_type) { if (options.has_format[LogicalTypeId::DATE] && sql_type.id() == LogicalTypeId::DATE) { date_t result; @@ -89131,6 +93644,11 @@ bool BaseCSVReader::TryCastValue(const Value &value, const LogicalType &sql_type string error_message; return options.date_format[LogicalTypeId::TIMESTAMP].TryParseTimestamp(string_t(StringValue::Get(value)), result, error_message); + } else if (options.decimal_separator != "." && sql_type.id() == LogicalTypeId::DECIMAL) { + return TryCastDecimalValueCommaSeparated(string_t(StringValue::Get(value)), sql_type); + } else if (options.decimal_separator != "." && + ((sql_type.id() == LogicalTypeId::FLOAT) || (sql_type.id() == LogicalTypeId::DOUBLE))) { + return TryCastFloatingValueCommaSeparated(string_t(StringValue::Get(value)), sql_type); } else { Value new_value; string error_message; @@ -89178,6 +93696,36 @@ bool TryCastTimestampVector(BufferedCSVReaderOptions &options, Vector &input_vec count, error_message); } +template +bool TemplatedTryCastFloatingVector(BufferedCSVReaderOptions &options, Vector &input_vector, Vector &result_vector, + idx_t count, string &error_message) { + D_ASSERT(input_vector.GetType().id() == LogicalTypeId::VARCHAR); + bool all_converted = true; + UnaryExecutor::Execute(input_vector, result_vector, count, [&](string_t input) { + T result; + if (!OP::Operation(input, result, &error_message)) { + all_converted = false; + } + return result; + }); + return all_converted; +} + +template +bool TemplatedTryCastDecimalVector(BufferedCSVReaderOptions &options, Vector &input_vector, Vector &result_vector, + idx_t count, string &error_message, uint8_t width, uint8_t scale) { + D_ASSERT(input_vector.GetType().id() == LogicalTypeId::VARCHAR); + bool all_converted = true; + UnaryExecutor::Execute(input_vector, result_vector, count, [&](string_t input) { + T result; + if (!OP::Operation(input, result, &error_message, width, scale)) { + all_converted = false; + } + return result; + }); + return all_converted; +} + bool BaseCSVReader::TryCastVector(Vector &parse_chunk_col, idx_t size, const LogicalType &sql_type) { // try vector-cast from string to sql_type Vector dummy_result(sql_type); @@ -89203,8 +93751,7 @@ void BaseCSVReader::AddValue(string_t str_val, idx_t &column, vector &esc } else { row_empty = false; } - - if (!sql_types.empty() && column == sql_types.size() && length == 0) { + if (!return_types.empty() && column == return_types.size() && length == 0) { // skip a single trailing delimiter in last column return; } @@ -89212,14 +93759,14 @@ void BaseCSVReader::AddValue(string_t str_val, idx_t &column, vector &esc column++; return; } - if (column >= sql_types.size()) { + if (column >= return_types.size()) { if (options.ignore_errors) { error_column_overflow = true; return; } else { throw InvalidInputException( "Error in file \"%s\", on line %s: expected %lld values per row, but got more. (%s)", options.file_path, - GetLineNumberStr(linenr, linenr_estimated).c_str(), sql_types.size(), options.ToString()); + GetLineNumberStr(linenr, linenr_estimated).c_str(), return_types.size(), options.ToString()); } } @@ -89227,7 +93774,7 @@ void BaseCSVReader::AddValue(string_t str_val, idx_t &column, vector &esc idx_t row_entry = parse_chunk.size(); // test against null string, but only if the value was not quoted - if ((!has_quotes || sql_types[column].id() != LogicalTypeId::VARCHAR) && !options.force_not_null[column] && + if ((!has_quotes || return_types[column].id() != LogicalTypeId::VARCHAR) && !options.force_not_null[column] && Equals::Operation(str_val, string_t(options.null_str))) { FlatVector::SetNull(parse_chunk.data[column], row_entry, true); } else { @@ -89260,12 +93807,12 @@ void BaseCSVReader::AddValue(string_t str_val, idx_t &column, vector &esc column++; } -bool BaseCSVReader::AddRow(DataChunk &insert_chunk, idx_t &column) { +bool BaseCSVReader::AddRow(DataChunk &insert_chunk, idx_t &column, string &error_message) { linenr++; if (row_empty) { row_empty = false; - if (sql_types.size() != 1) { + if (return_types.size() != 1) { if (mode == ParserMode::PARSING) { FlatVector::SetNull(parse_chunk.data[0], parse_chunk.size(), false); } @@ -89282,14 +93829,20 @@ bool BaseCSVReader::AddRow(DataChunk &insert_chunk, idx_t &column) { return false; } - if (column < sql_types.size() && mode != ParserMode::SNIFFING_DIALECT) { + if (column < return_types.size() && mode != ParserMode::SNIFFING_DIALECT) { if (options.ignore_errors) { column = 0; return false; } else { - throw InvalidInputException( - "Error in file \"%s\" on line %s: expected %lld values per row, but got %d. (%s)", options.file_path, - GetLineNumberStr(linenr, linenr_estimated).c_str(), sql_types.size(), column, options.ToString()); + if (mode == ParserMode::SNIFFING_DATATYPES) { + error_message = "Error when adding line"; + return false; + } else { + throw InvalidInputException( + "Error in file \"%s\" on line %s: expected %lld values per row, but got %d.\nParser options:\n%s", + options.file_path, GetLineNumberStr(linenr, linenr_estimated).c_str(), return_types.size(), column, + options.ToString()); + } } } @@ -89320,13 +93873,6 @@ bool BaseCSVReader::AddRow(DataChunk &insert_chunk, idx_t &column) { return false; } -void BaseCSVReader::SetNullUnionCols(DataChunk &insert_chunk) { - for (idx_t col = 0; col < insert_nulls_idx.size(); ++col) { - insert_chunk.data[insert_nulls_idx[col]].SetVectorType(VectorType::CONSTANT_VECTOR); - ConstantVector::SetNull(insert_chunk.data[insert_nulls_idx[col]], true); - } -} - void BaseCSVReader::VerifyUTF8(idx_t col_idx, idx_t row_idx, DataChunk &chunk, int64_t offset) { D_ASSERT(col_idx < chunk.data.size()); D_ASSERT(row_idx < chunk.size()); @@ -89340,13 +93886,13 @@ void BaseCSVReader::VerifyUTF8(idx_t col_idx, idx_t row_idx, DataChunk &chunk, i auto utf_type = Utf8Proc::Analyze(s.GetDataUnsafe(), s.GetSize()); if (utf_type == UnicodeType::INVALID) { string col_name = to_string(col_idx); - if (col_idx < col_names.size()) { - col_name = "\"" + col_names[col_idx] + "\""; + if (col_idx < names.size()) { + col_name = "\"" + names[col_idx] + "\""; } int64_t error_line = linenr - (chunk.size() - row_idx) + 1 + offset; D_ASSERT(error_line >= 0); throw InvalidInputException("Error in file \"%s\" at line %llu in column \"%s\": " - "%s. Parser options: %s", + "%s. Parser options:\n%s", options.file_path, error_line, col_name, ErrorManager::InvalidUnicodeError(s.GetString(), "CSV file"), options.ToString()); } @@ -89359,6 +93905,48 @@ void BaseCSVReader::VerifyUTF8(idx_t col_idx) { } } +bool TryCastDecimalVectorCommaSeparated(BufferedCSVReaderOptions &options, Vector &input_vector, Vector &result_vector, + idx_t count, string &error_message, LogicalType &result_type) { + auto width = DecimalType::GetWidth(result_type); + auto scale = DecimalType::GetScale(result_type); + switch (result_type.InternalType()) { + case PhysicalType::INT16: + return TemplatedTryCastDecimalVector( + options, input_vector, result_vector, count, error_message, width, scale); + break; + case PhysicalType::INT32: + return TemplatedTryCastDecimalVector( + options, input_vector, result_vector, count, error_message, width, scale); + break; + case PhysicalType::INT64: + return TemplatedTryCastDecimalVector( + options, input_vector, result_vector, count, error_message, width, scale); + break; + case PhysicalType::INT128: + return TemplatedTryCastDecimalVector( + options, input_vector, result_vector, count, error_message, width, scale); + break; + default: + throw InternalException("Unimplemented physical type for decimal"); + } +} + +bool TryCastFloatingVectorCommaSeparated(BufferedCSVReaderOptions &options, Vector &input_vector, Vector &result_vector, + idx_t count, string &error_message, LogicalType &result_type) { + switch (result_type.InternalType()) { + case PhysicalType::DOUBLE: + return TemplatedTryCastFloatingVector( + options, input_vector, result_vector, count, error_message); + break; + case PhysicalType::FLOAT: + return TemplatedTryCastFloatingVector( + options, input_vector, result_vector, count, error_message); + break; + default: + throw InternalException("Unimplemented physical type for floating"); + } +} + bool BaseCSVReader::Flush(DataChunk &insert_chunk, bool try_add_line) { if (parse_chunk.size() == 0) { return true; @@ -89368,30 +93956,40 @@ bool BaseCSVReader::Flush(DataChunk &insert_chunk, bool try_add_line) { // convert the columns in the parsed chunk to the types of the table insert_chunk.SetCardinality(parse_chunk); - for (idx_t col_idx = 0; col_idx < sql_types.size(); col_idx++) { - if (sql_types[col_idx].id() == LogicalTypeId::VARCHAR) { + for (idx_t col_idx = 0; col_idx < return_types.size(); col_idx++) { + auto insert_idx = insert_cols_idx[col_idx]; + auto &type = return_types[col_idx]; + if (type.id() == LogicalTypeId::VARCHAR) { // target type is varchar: no need to convert // just test that all strings are valid utf-8 strings VerifyUTF8(col_idx); - insert_chunk.data[insert_cols_idx[col_idx]].Reference(parse_chunk.data[col_idx]); + // reinterpret rather than reference so we can deal with user-defined types + insert_chunk.data[insert_idx].Reinterpret(parse_chunk.data[col_idx]); + } else { string error_message; bool success; - if (options.has_format[LogicalTypeId::DATE] && sql_types[col_idx].id() == LogicalTypeId::DATE) { + if (options.has_format[LogicalTypeId::DATE] && type.id() == LogicalTypeId::DATE) { // use the date format to cast the chunk - success = - TryCastDateVector(options, parse_chunk.data[col_idx], insert_chunk.data[insert_cols_idx[col_idx]], - parse_chunk.size(), error_message); + success = TryCastDateVector(options, parse_chunk.data[col_idx], insert_chunk.data[insert_idx], + parse_chunk.size(), error_message); } else if (options.has_format[LogicalTypeId::TIMESTAMP] && - sql_types[col_idx].id() == LogicalTypeId::TIMESTAMP) { + return_types[col_idx].id() == LogicalTypeId::TIMESTAMP) { // use the date format to cast the chunk - success = TryCastTimestampVector(options, parse_chunk.data[col_idx], - insert_chunk.data[insert_cols_idx[col_idx]], parse_chunk.size(), - error_message); + success = TryCastTimestampVector(options, parse_chunk.data[col_idx], insert_chunk.data[insert_idx], + parse_chunk.size(), error_message); + } else if (options.decimal_separator != "." && (return_types[col_idx].id() == LogicalTypeId::FLOAT || + return_types[col_idx].id() == LogicalTypeId::DOUBLE)) { + success = TryCastFloatingVectorCommaSeparated(options, parse_chunk.data[col_idx], + insert_chunk.data[insert_idx], parse_chunk.size(), + error_message, return_types[col_idx]); + } else if (options.decimal_separator != "." && return_types[col_idx].id() == LogicalTypeId::DECIMAL) { + success = TryCastDecimalVectorCommaSeparated(options, parse_chunk.data[col_idx], + insert_chunk.data[insert_idx], parse_chunk.size(), + error_message, return_types[col_idx]); } else { // target type is not varchar: perform a cast - success = VectorOperations::DefaultTryCast(parse_chunk.data[col_idx], - insert_chunk.data[insert_cols_idx[col_idx]], + success = VectorOperations::DefaultTryCast(parse_chunk.data[col_idx], insert_chunk.data[insert_idx], parse_chunk.size(), &error_message); } if (success) { @@ -89405,8 +94003,8 @@ bool BaseCSVReader::Flush(DataChunk &insert_chunk, bool try_add_line) { continue; } string col_name = to_string(col_idx); - if (col_idx < col_names.size()) { - col_name = "\"" + col_names[col_idx] + "\""; + if (col_idx < names.size()) { + col_name = "\"" + names[col_idx] + "\""; } // figure out the exact line number @@ -89422,13 +94020,13 @@ bool BaseCSVReader::Flush(DataChunk &insert_chunk, bool try_add_line) { auto error_line = linenr - (parse_chunk.size() - row_idx) + 1; if (options.auto_detect) { - throw InvalidInputException("%s in column %s, at line %llu. Parser " - "options: %s. Consider either increasing the sample size " + throw InvalidInputException("%s in column %s, at line %llu.\n\nParser " + "options:\n%s.\n\nConsider either increasing the sample size " "(SAMPLE_SIZE=X [X rows] or SAMPLE_SIZE=-1 [all rows]), " "or skipping column conversion (ALL_VARCHAR=1)", error_message, col_name, error_line, options.ToString()); } else { - throw InvalidInputException("%s at line %llu in column %s. Parser options: %s ", error_message, + throw InvalidInputException("%s at line %llu in column %s. Parser options:\n%s ", error_message, error_line, col_name, options.ToString()); } } @@ -89441,7 +94039,7 @@ bool BaseCSVReader::Flush(DataChunk &insert_chunk, bool try_add_line) { for (idx_t row_idx = 0; row_idx < parse_chunk.size(); row_idx++) { bool failed = false; - for (idx_t column_idx = 0; column_idx < sql_types.size(); column_idx++) { + for (idx_t column_idx = 0; column_idx < return_types.size(); column_idx++) { auto &inserted_column = insert_chunk.data[column_idx]; auto &parsed_column = parse_chunk.data[column_idx]; @@ -89461,6 +94059,34 @@ bool BaseCSVReader::Flush(DataChunk &insert_chunk, bool try_add_line) { parse_chunk.Reset(); return true; } + +void BaseCSVReader::SetNewLineDelimiter(bool carry, bool carry_followed_by_nl) { + if ((mode == ParserMode::SNIFFING_DIALECT && !options.has_newline) || + options.new_line == NewLineIdentifier::NOT_SET) { + if (options.new_line == NewLineIdentifier::MIX) { + return; + } + NewLineIdentifier this_line_identifier; + if (carry) { + if (carry_followed_by_nl) { + this_line_identifier = NewLineIdentifier::CARRY_ON; + } else { + this_line_identifier = NewLineIdentifier::SINGLE; + } + } else { + this_line_identifier = NewLineIdentifier::SINGLE; + } + if (options.new_line == NewLineIdentifier::NOT_SET) { + options.new_line = this_line_identifier; + return; + } + if (options.new_line != this_line_identifier) { + options.new_line = NewLineIdentifier::MIX; + return; + } + options.new_line = this_line_identifier; + } +} } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB @@ -89521,6 +94147,8 @@ class BufferedCSVReader : public BaseCSVReader { const vector &requested_types = vector()); BufferedCSVReader(FileSystem &fs, Allocator &allocator, FileOpener *opener, BufferedCSVReaderOptions options, const vector &requested_types = vector()); + BufferedCSVReader(ClientContext &context, string filename, BufferedCSVReaderOptions options, + const vector &requested_types = vector()); ~BufferedCSVReader(); unique_ptr buffer; @@ -89537,6 +94165,7 @@ class BufferedCSVReader : public BaseCSVReader { public: //! Extract a single DataChunk from the CSV file and stores it in insert_chunk void ParseCSV(DataChunk &insert_chunk); + static string ColumnTypesError(case_insensitive_map_t sql_types_per_column, const vector &names); private: //! Initialize Parser @@ -89617,7 +94246,7 @@ namespace duckdb { BufferedCSVReader::BufferedCSVReader(FileSystem &fs_p, Allocator &allocator, FileOpener *opener_p, BufferedCSVReaderOptions options_p, const vector &requested_types) - : BaseCSVReader(fs_p, allocator, opener_p, move(options_p), requested_types), buffer_size(0), position(0), + : BaseCSVReader(fs_p, allocator, opener_p, std::move(options_p), requested_types), buffer_size(0), position(0), start(0) { file_handle = OpenCSV(options); Initialize(requested_types); @@ -89626,7 +94255,17 @@ BufferedCSVReader::BufferedCSVReader(FileSystem &fs_p, Allocator &allocator, Fil BufferedCSVReader::BufferedCSVReader(ClientContext &context, BufferedCSVReaderOptions options_p, const vector &requested_types) : BufferedCSVReader(FileSystem::GetFileSystem(context), Allocator::Get(context), FileSystem::GetFileOpener(context), - move(options_p), requested_types) { + std::move(options_p), requested_types) { +} + +BufferedCSVReader::BufferedCSVReader(ClientContext &context, string filename, BufferedCSVReaderOptions options_p, + const vector &requested_types) + : BaseCSVReader(FileSystem::GetFileSystem(context), Allocator::Get(context), FileSystem::GetFileOpener(context), + std::move(options_p), requested_types), + buffer_size(0), position(0), start(0) { + options.file_path = std::move(filename); + file_handle = OpenCSV(options); + Initialize(requested_types); } BufferedCSVReader::~BufferedCSVReader() { @@ -89710,7 +94349,7 @@ TextSearchShiftArray::TextSearchShiftArray() { TextSearchShiftArray::TextSearchShiftArray(string search_term) : length(search_term.size()) { if (length > 255) { - throw Exception("Size of delimiter/quote/escape in CSV reader is limited to 255 bytes"); + throw InvalidInputException("Size of delimiter/quote/escape in CSV reader is limited to 255 bytes"); } // initialize the shifts array shifts = unique_ptr(new uint8_t[length * 255]); @@ -89828,20 +94467,20 @@ static string NormalizeColumnName(const string &col_name) { void BufferedCSVReader::Initialize(const vector &requested_types) { PrepareComplexParser(); if (options.auto_detect) { - sql_types = SniffCSV(requested_types); - if (sql_types.empty()) { - throw Exception("Failed to detect column types from CSV: is the file a valid CSV file?"); + return_types = SniffCSV(requested_types); + if (return_types.empty()) { + throw InvalidInputException("Failed to detect column types from CSV: is the file a valid CSV file?"); } if (cached_chunks.empty()) { JumpToBeginning(options.skip_rows, options.header); } } else { - sql_types = requested_types; + return_types = requested_types; ResetBuffer(); SkipRowsAndReadHeader(options.skip_rows, options.header); } - InitParseChunk(sql_types.size()); - InitInsertChunkIdx(sql_types.size()); + InitParseChunk(return_types.size()); + InitInsertChunkIdx(return_types.size()); // we only need reset support during the automatic CSV type detection // since reset support might require caching (in the case of streams), we disable it for the remainder file_handle->DisableReset(); @@ -89889,7 +94528,7 @@ void BufferedCSVReader::SkipRowsAndReadHeader(idx_t skip_rows, bool skip_header) if (skip_header) { // ignore the first line as a header line - InitParseChunk(sql_types.size()); + InitParseChunk(return_types.size()); ParseCSV(ParserMode::PARSING_HEADER); } } @@ -90026,7 +94665,6 @@ void BufferedCSVReader::DetectDialect(const vector &requested_types JumpToBeginning(original_options.skip_rows); sniffed_column_counts.clear(); - if (!TryParseCSV(ParserMode::SNIFFING_DIALECT)) { continue; } @@ -90059,6 +94697,7 @@ void BufferedCSVReader::DetectDialect(const vector &requested_types } else if ((more_values || single_column_before) && rows_consistent) { sniff_info.skip_rows = start_row; sniff_info.num_cols = num_cols; + sniff_info.new_line = options.new_line; best_consistent_rows = consistent_rows; best_num_cols = num_cols; @@ -90074,6 +94713,7 @@ void BufferedCSVReader::DetectDialect(const vector &requested_types if (!same_quote_is_candidate) { sniff_info.skip_rows = start_row; sniff_info.num_cols = num_cols; + sniff_info.new_line = options.new_line; info_candidates.push_back(sniff_info); } } @@ -90107,14 +94747,14 @@ void BufferedCSVReader::DetectCandidateTypes(const vector &type_can format_candidates[t.first].clear(); } - // set all sql_types to VARCHAR so we can do datatype detection based on VARCHAR values - sql_types.clear(); - sql_types.assign(options.num_cols, LogicalType::VARCHAR); + // set all return_types to VARCHAR so we can do datatype detection based on VARCHAR values + return_types.clear(); + return_types.assign(options.num_cols, LogicalType::VARCHAR); // jump to beginning and skip potential header JumpToBeginning(options.skip_rows, true); DataChunk header_row; - header_row.Initialize(allocator, sql_types); + header_row.Initialize(allocator, return_types); parse_chunk.Copy(header_row); if (header_row.size() == 0) { @@ -90122,8 +94762,10 @@ void BufferedCSVReader::DetectCandidateTypes(const vector &type_can } // init parse chunk and read csv with info candidate - InitParseChunk(sql_types.size()); - ParseCSV(ParserMode::SNIFFING_DATATYPES); + InitParseChunk(return_types.size()); + if (!TryParseCSV(ParserMode::SNIFFING_DATATYPES)) { + continue; + } for (idx_t row_idx = 0; row_idx <= parse_chunk.size(); row_idx++) { bool is_header_row = row_idx == 0; idx_t row = row_idx - 1; @@ -90298,7 +94940,7 @@ void BufferedCSVReader::DetectHeader(const vector> &best_sql col_name = col_name + "_" + to_string(name_collision_count[col_name]); } - col_names.push_back(col_name); + names.push_back(col_name); name_collision_count[col_name] = 0; } @@ -90306,7 +94948,7 @@ void BufferedCSVReader::DetectHeader(const vector> &best_sql options.header = false; for (idx_t col = 0; col < options.num_cols; col++) { string column_name = GenerateColumnName(options.num_cols, col); - col_names.push_back(column_name); + names.push_back(column_name); } } } @@ -90316,8 +94958,8 @@ vector BufferedCSVReader::RefineTypeDetection(const vector> &best_sql_types_candidates, map> &best_format_candidates) { // for the type refine we set the SQL types to VARCHAR for all columns - sql_types.clear(); - sql_types.assign(options.num_cols, LogicalType::VARCHAR); + return_types.clear(); + return_types.assign(options.num_cols, LogicalType::VARCHAR); vector detected_types; @@ -90332,11 +94974,11 @@ vector BufferedCSVReader::RefineTypeDetection(const vector BufferedCSVReader::RefineTypeDetection(const vector(); auto parse_chunk_types = parse_chunk.GetTypes(); chunk->Move(parse_chunk); - cached_chunks.push(move(chunk)); + cached_chunks.push(std::move(chunk)); } else { while (!cached_chunks.empty()) { cached_chunks.pop(); @@ -90407,6 +95049,27 @@ vector BufferedCSVReader::RefineTypeDetection(const vector sql_types_per_column, + const vector &names) { + for (idx_t i = 0; i < names.size(); i++) { + auto it = sql_types_per_column.find(names[i]); + if (it != sql_types_per_column.end()) { + sql_types_per_column.erase(names[i]); + continue; + } + } + if (sql_types_per_column.empty()) { + return string(); + } + string exception = "COLUMN_TYPES error: Columns with names: "; + for (auto &col : sql_types_per_column) { + exception += "\"" + col.first + "\","; + } + exception.pop_back(); + exception += " do not exist in the CSV File"; + return exception; +} + vector BufferedCSVReader::SniffCSV(const vector &requested_types) { for (auto &type : requested_types) { // auto detect for blobs not supported: there may be invalid UTF-8 in the file @@ -90436,10 +95099,13 @@ vector BufferedCSVReader::SniffCSV(const vector &reque // ####### // type candidates, ordered by descending specificity (~ from high to low) vector type_candidates = { - LogicalType::VARCHAR, LogicalType::TIMESTAMP, - LogicalType::DATE, LogicalType::TIME, - LogicalType::DOUBLE, /* LogicalType::FLOAT,*/ LogicalType::BIGINT, - LogicalType::INTEGER, /*LogicalType::SMALLINT, LogicalType::TINYINT,*/ LogicalType::BOOLEAN, + LogicalType::VARCHAR, + LogicalType::TIMESTAMP, + LogicalType::DATE, + LogicalType::TIME, + LogicalType::DOUBLE, + /* LogicalType::FLOAT,*/ LogicalType::BIGINT, + /*LogicalType::INTEGER,*/ /*LogicalType::SMALLINT, LogicalType::TINYINT,*/ LogicalType::BOOLEAN, LogicalType::SQLNULL}; // format template candidates, ordered by descending specificity (~ from high to low) std::map> format_template_candidates = { @@ -90459,6 +95125,37 @@ vector BufferedCSVReader::SniffCSV(const vector &reque // ####### options.num_cols = best_num_cols; DetectHeader(best_sql_types_candidates, best_header_row); + if (!options.sql_type_list.empty()) { + // user-defined types were supplied for certain columns + // override the types + if (!options.sql_types_per_column.empty()) { + // types supplied as name -> value map + idx_t found = 0; + for (idx_t i = 0; i < names.size(); i++) { + auto it = options.sql_types_per_column.find(names[i]); + if (it != options.sql_types_per_column.end()) { + best_sql_types_candidates[i] = {options.sql_type_list[it->second]}; + found++; + continue; + } + } + if (!options.union_by_name && found < options.sql_types_per_column.size()) { + string exception = ColumnTypesError(options.sql_types_per_column, names); + if (!exception.empty()) { + throw BinderException(exception); + } + } + } else { + // types supplied as list + if (names.size() < options.sql_type_list.size()) { + throw BinderException("read_csv: %d types were provided, but CSV file only has %d columns", + options.sql_type_list.size(), names.size()); + } + for (idx_t i = 0; i < options.sql_type_list.size(); i++) { + best_sql_types_candidates[i] = {options.sql_type_list[i]}; + } + } + } // ####### // ### type detection (refining) @@ -90548,7 +95245,10 @@ add_row : { // check type of newline (\r or \n) bool carriage_return = buffer[position] == '\r'; AddValue(string_t(buffer.get() + start, position - start - offset), column, escape_positions, has_quotes); - finished_chunk = AddRow(insert_chunk, column); + finished_chunk = AddRow(insert_chunk, column, error_message); + if (!error_message.empty()) { + return false; + } // increase position by 1 and move start to the new position offset = 0; has_quotes = false; @@ -90686,7 +95386,10 @@ add_row : { if (column > 0 || position > start) { // remaining values to be added to the chunk AddValue(string_t(buffer.get() + start, position - start - offset), column, escape_positions, has_quotes); - finished_chunk = AddRow(insert_chunk, column); + finished_chunk = AddRow(insert_chunk, column, error_message); + if (!error_message.empty()) { + return false; + } } // final stage, only reached after parsing the file is finished // flush the parsed chunk and finalize parsing @@ -90759,7 +95462,13 @@ add_row : { // check type of newline (\r or \n) bool carriage_return = buffer[position] == '\r'; AddValue(string_t(buffer.get() + start, position - start - offset), column, escape_positions, has_quotes); - finished_chunk = AddRow(insert_chunk, column); + if (!error_message.empty()) { + return false; + } + finished_chunk = AddRow(insert_chunk, column, error_message); + if (!error_message.empty()) { + return false; + } // increase position by 1 and move start to the new position offset = 0; has_quotes = false; @@ -90772,6 +95481,7 @@ add_row : { // \r newline, go to special state that parses an optional \n afterwards goto carriage_return; } else { + SetNewLineDelimiter(); // \n newline, move to value start if (finished_chunk) { return true; @@ -90850,6 +95560,7 @@ add_row : { /* state: carriage_return */ // this stage optionally skips a newline (\n) character, which allows \r\n to be interpreted as a single line if (buffer[position] == '\n') { + SetNewLineDelimiter(true, true); // newline after carriage return: skip // increase position by 1 and move start to the new position start = ++position; @@ -90857,6 +95568,8 @@ add_row : { // file ends right after delimiter, go to final state goto final_state; } + } else { + SetNewLineDelimiter(true, false); } if (finished_chunk) { return true; @@ -90870,7 +95583,10 @@ add_row : { if (column > 0 || position > start) { // remaining values to be added to the chunk AddValue(string_t(buffer.get() + start, position - start - offset), column, escape_positions, has_quotes); - finished_chunk = AddRow(insert_chunk, column); + finished_chunk = AddRow(insert_chunk, column, error_message); + if (!error_message.empty()) { + return false; + } } // final stage, only reached after parsing the file is finished @@ -90884,7 +95600,7 @@ add_row : { } bool BufferedCSVReader::ReadBuffer(idx_t &start) { - auto old_buffer = move(buffer); + auto old_buffer = std::move(buffer); // the remaining part of the last buffer idx_t remaining = buffer_size - start; @@ -90914,7 +95630,7 @@ bool BufferedCSVReader::ReadBuffer(idx_t &start) { buffer_size = remaining + read_count; buffer[buffer_size] = '\0'; if (old_buffer) { - cached_buffers.push_back(move(old_buffer)); + cached_buffers.push_back(std::move(old_buffer)); } start = 0; position = remaining; @@ -90976,12 +95692,15 @@ bool BufferedCSVReader::TryParseCSV(ParserMode parser_mode, DataChunk &insert_ch namespace duckdb { -CSVBuffer::CSVBuffer(ClientContext &context, idx_t buffer_size_p, CSVFileHandle &file_handle) +CSVBuffer::CSVBuffer(ClientContext &context, idx_t buffer_size_p, CSVFileHandle &file_handle, + idx_t &global_csv_current_position) : context(context), first_buffer(true) { this->handle = AllocateBuffer(buffer_size_p); auto buffer = Ptr(); actual_size = file_handle.Read(buffer, buffer_size_p); + global_csv_start = global_csv_current_position; + global_csv_current_position += actual_size; if (actual_size >= 3 && buffer[0] == '\xEF' && buffer[1] == '\xBB' && buffer[2] == '\xBF') { start_position += 3; } @@ -90989,21 +95708,25 @@ CSVBuffer::CSVBuffer(ClientContext &context, idx_t buffer_size_p, CSVFileHandle } CSVBuffer::CSVBuffer(ClientContext &context, BufferHandle buffer_p, idx_t buffer_size_p, idx_t actual_size_p, - bool final_buffer) - : context(context), handle(move(buffer_p)), actual_size(actual_size_p), last_buffer(final_buffer) { + bool final_buffer, idx_t global_csv_current_position) + : context(context), handle(std::move(buffer_p)), actual_size(actual_size_p), last_buffer(final_buffer), + global_csv_start(global_csv_current_position) { } -unique_ptr CSVBuffer::Next(CSVFileHandle &file_handle, idx_t set_buffer_size) { +unique_ptr CSVBuffer::Next(CSVFileHandle &file_handle, idx_t buffer_size, + idx_t &global_csv_current_position) { if (file_handle.FinishedReading()) { // this was the last buffer return nullptr; } - auto next_buffer = AllocateBuffer(set_buffer_size); - idx_t next_buffer_actual_size = file_handle.Read(next_buffer.Ptr(), set_buffer_size); + auto next_buffer = AllocateBuffer(buffer_size); + idx_t next_buffer_actual_size = file_handle.Read(next_buffer.Ptr(), buffer_size); - return make_unique(context, move(next_buffer), set_buffer_size, next_buffer_actual_size, - file_handle.FinishedReading()); + auto next_csv_buffer = make_unique(context, std::move(next_buffer), buffer_size, next_buffer_actual_size, + file_handle.FinishedReading(), global_csv_current_position); + global_csv_current_position += next_buffer_actual_size; + return next_csv_buffer; } BufferHandle CSVBuffer::AllocateBuffer(idx_t buffer_size) { @@ -91027,11 +95750,16 @@ bool CSVBuffer::IsCSVFileFirstBuffer() { return first_buffer; } +idx_t CSVBuffer::GetCSVGlobalStart() { + return global_csv_start; +} + } // namespace duckdb + namespace duckdb { static bool ParseBoolean(const Value &value, const string &loption); @@ -91089,54 +95817,23 @@ static int64_t ParseInteger(const Value &value, const string &loption) { return value.GetValue(); } -static vector ParseColumnList(const vector &set, vector &names, const string &loption) { - vector result; +void BufferedCSVReaderOptions::SetHeader(bool input) { + this->header = input; + this->has_header = true; +} - if (set.empty()) { - throw BinderException("\"%s\" expects a column list or * as parameter", loption); - } - // list of options: parse the list - unordered_map option_map; - for (idx_t i = 0; i < set.size(); i++) { - option_map[set[i].ToString()] = false; - } - result.resize(names.size(), false); - for (idx_t i = 0; i < names.size(); i++) { - auto entry = option_map.find(names[i]); - if (entry != option_map.end()) { - result[i] = true; - entry->second = true; - } - } - for (auto &entry : option_map) { - if (!entry.second) { - throw BinderException("\"%s\" expected to find %s, but it was not found in the table", loption, - entry.first.c_str()); - } - } - return result; +void BufferedCSVReaderOptions::SetCompression(const string &compression) { + this->compression = FileCompressionTypeFromString(compression); } -static vector ParseColumnList(const Value &value, vector &names, const string &loption) { - vector result; +void BufferedCSVReaderOptions::SetEscape(const string &input) { + this->escape = input; + this->has_escape = true; +} - // Only accept a list of arguments - if (value.type().id() != LogicalTypeId::LIST) { - // Support a single argument if it's '*' - if (value.type().id() == LogicalTypeId::VARCHAR && value.GetValue() == "*") { - result.resize(names.size(), true); - return result; - } - throw BinderException("\"%s\" expects a column list or * as parameter", loption); - } - auto &children = ListValue::GetChildren(value); - // accept '*' as single argument - if (children.size() == 1 && children[0].type().id() == LogicalTypeId::VARCHAR && - children[0].GetValue() == "*") { - result.resize(names.size(), true); - return result; - } - return ParseColumnList(children, names, loption); +void BufferedCSVReaderOptions::SetParallel(bool use_parallel) { + this->has_parallel = true; + this->use_parallel = use_parallel; } void BufferedCSVReaderOptions::SetDelimiter(const string &input) { @@ -91147,6 +95844,22 @@ void BufferedCSVReaderOptions::SetDelimiter(const string &input) { } } +void BufferedCSVReaderOptions::SetQuote(const string "e) { + this->quote = quote; + this->has_quote = true; +} + +void BufferedCSVReaderOptions::SetNewline(const string &input) { + if (input == "\\n" || input == "\\r") { + new_line = NewLineIdentifier::SINGLE; + } else if (input == "\\r\\n") { + new_line = NewLineIdentifier::CARRY_ON; + } else { + throw InvalidInputException("This is not accepted as a newline: " + input); + } + has_newline = true; +} + void BufferedCSVReaderOptions::SetDateFormat(LogicalTypeId type, const string &format, bool read_format) { string error; if (read_format) { @@ -91170,6 +95883,8 @@ void BufferedCSVReaderOptions::SetReadOption(const string &loption, const Value } if (loption == "auto_detect") { auto_detect = ParseBoolean(value, loption); + } else if (loption == "parallel") { + SetParallel(ParseBoolean(value, loption)); } else if (loption == "sample_size") { int64_t sample_size = ParseInteger(value, loption); if (sample_size < 1 && sample_size != -1) { @@ -91183,7 +95898,7 @@ void BufferedCSVReaderOptions::SetReadOption(const string &loption, const Value sample_chunks = 1; } else { sample_chunk_size = STANDARD_VECTOR_SIZE; - sample_chunks = sample_size / STANDARD_VECTOR_SIZE; + sample_chunks = sample_size / STANDARD_VECTOR_SIZE + 1; } } else if (loption == "skip") { skip_rows = ParseInteger(value, loption); @@ -91211,9 +95926,6 @@ void BufferedCSVReaderOptions::SetReadOption(const string &loption, const Value } else if (loption == "timestamp_format" || loption == "timestampformat") { string format = ParseString(value, loption); SetDateFormat(LogicalTypeId::TIMESTAMP, format, true); - } else if (loption == "escape") { - escape = ParseString(value, loption); - has_escape = true; } else if (loption == "ignore_errors") { ignore_errors = ParseBoolean(value, loption); } else if (loption == "union_by_name") { @@ -91223,6 +95935,11 @@ void BufferedCSVReaderOptions::SetReadOption(const string &loption, const Value if (buffer_size == 0) { throw InvalidInputException("Buffer Size option must be higher than 0"); } + } else if (loption == "decimal_separator") { + decimal_separator = ParseString(value, loption); + if (decimal_separator != "." && decimal_separator != ",") { + throw BinderException("Unsupported parameter for DECIMAL_SEPARATOR: should be '.' or ','"); + } } else { throw BinderException("Unrecognized option for CSV reader \"%s\"", loption); } @@ -91256,14 +95973,13 @@ bool BufferedCSVReaderOptions::SetBaseOption(const string &loption, const Value if (StringUtil::StartsWith(loption, "delim") || StringUtil::StartsWith(loption, "sep")) { SetDelimiter(ParseString(value, loption)); } else if (loption == "quote") { - quote = ParseString(value, loption); - has_quote = true; + SetQuote(ParseString(value, loption)); + } else if (loption == "new_line") { + SetNewline(ParseString(value, loption)); } else if (loption == "escape") { - escape = ParseString(value, loption); - has_escape = true; + SetEscape(ParseString(value, loption)); } else if (loption == "header") { - header = ParseBoolean(value, loption); - has_header = true; + SetHeader(ParseBoolean(value, loption)); } else if (loption == "null" || loption == "nullstr") { null_str = ParseString(value, loption); } else if (loption == "encoding") { @@ -91272,7 +95988,7 @@ bool BufferedCSVReaderOptions::SetBaseOption(const string &loption, const Value throw BinderException("Copy is only supported for UTF-8 encoded files, ENCODING 'UTF-8'"); } } else if (loption == "compression") { - compression = FileCompressionTypeFromString(ParseString(value, loption)); + SetCompression(ParseString(value, loption)); } else { // unrecognized option in base CSV return false; @@ -91281,13 +95997,14 @@ bool BufferedCSVReaderOptions::SetBaseOption(const string &loption, const Value } std::string BufferedCSVReaderOptions::ToString() const { - return "DELIMITER='" + delimiter + (has_delimiter ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) + - ", QUOTE='" + quote + (has_quote ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) + - ", ESCAPE='" + escape + (has_escape ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) + - ", HEADER=" + std::to_string(header) + + return " file=" + file_path + "\n delimiter='" + delimiter + + (has_delimiter ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) + "\n quote='" + quote + + (has_quote ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) + "\n escape='" + escape + + (has_escape ? "'" : (auto_detect ? "' (auto detected)" : "' (default)")) + + "\n header=" + std::to_string(header) + (has_header ? "" : (auto_detect ? " (auto detected)" : "' (default)")) + - ", SAMPLE_SIZE=" + std::to_string(sample_chunk_size * sample_chunks) + - ", IGNORE_ERRORS=" + std::to_string(ignore_errors) + ", ALL_VARCHAR=" + std::to_string(all_varchar); + "\n sample_size=" + std::to_string(sample_chunk_size * sample_chunks) + + "\n ignore_errors=" + std::to_string(ignore_errors) + "\n all_varchar=" + std::to_string(all_varchar); } } // namespace duckdb @@ -91314,7 +96031,7 @@ namespace duckdb { struct CSVBufferRead { CSVBufferRead(shared_ptr buffer_p, idx_t buffer_start_p, idx_t buffer_end_p, idx_t batch_index, idx_t estimated_linenr) - : buffer(move(buffer_p)), buffer_start(buffer_start_p), buffer_end(buffer_end_p), batch_index(batch_index), + : buffer(std::move(buffer_p)), buffer_start(buffer_start_p), buffer_end(buffer_end_p), batch_index(batch_index), estimated_linenr(estimated_linenr) { if (buffer) { if (buffer_end > buffer->GetBufferSize()) { @@ -91369,7 +96086,7 @@ struct CSVBufferRead { for (; cur_pos < length; cur_pos++) { intersection[cur_pos] = next_buffer_ptr[nxt_buffer_pos++]; } - intersections.emplace_back(move(intersection)); + intersections.emplace_back(std::move(intersection)); return string_t(intersections.back().get(), length); } } @@ -91384,6 +96101,10 @@ struct CSVBufferRead { idx_t estimated_linenr; }; +struct VerificationPositions { + idx_t beginning_of_first_line = 0; + idx_t end_of_last_line = 0; +}; //! Buffered CSV reader is a class that reads values from a stream and parses them as a CSV file class ParallelCSVReader : public BaseCSVReader { public: @@ -91404,7 +96125,10 @@ class ParallelCSVReader : public BaseCSVReader { //! If this flag is set, it means we are about to try to read our last row. bool reached_remainder_state = false; + bool finished = false; + unique_ptr buffer; + VerificationPositions GetVerificationPositions(); public: void SetBufferRead(unique_ptr buffer); @@ -91427,8 +96151,13 @@ class ParallelCSVReader : public BaseCSVReader { //! when changing the buffer end the first time. //! It returns FALSE if the parser should jump to the final state of parsing or not bool BufferRemainder(); + + bool NewLineDelimiter(bool carry, bool carry_followed_by_nl, bool first_char); + //! Parses a CSV file with a one-byte delimiter, escape and quote character bool TryParseSimpleCSV(DataChunk &insert_chunk, string &error_message, bool try_add_line = false); + //! Position of the first read line and last read line for verification purposes + VerificationPositions verification_positions; }; } // namespace duckdb @@ -91466,11 +96195,13 @@ class ParallelCSVReader : public BaseCSVReader { + namespace duckdb { class ReadCSV { public: - static unique_ptr OpenCSV(const BufferedCSVReaderOptions &options, ClientContext &context); + static unique_ptr OpenCSV(const string &file_path, FileCompressionType compression, + ClientContext &context); }; struct BaseCSVData : public TableFunctionData { @@ -91488,9 +96219,10 @@ struct BaseCSVData : public TableFunctionData { }; struct WriteCSVData : public BaseCSVData { - WriteCSVData(string file_path, vector sql_types, vector names) : sql_types(move(sql_types)) { - files.push_back(move(file_path)); - options.names = move(names); + WriteCSVData(string file_path, vector sql_types, vector names) + : sql_types(std::move(sql_types)) { + files.push_back(std::move(file_path)); + options.names = std::move(names); } //! The SQL types to write @@ -91542,9 +96274,9 @@ namespace duckdb { ParallelCSVReader::ParallelCSVReader(ClientContext &context, BufferedCSVReaderOptions options_p, unique_ptr buffer_p, const vector &requested_types) - : BaseCSVReader(context, move(options_p), requested_types) { + : BaseCSVReader(context, std::move(options_p), requested_types) { Initialize(requested_types); - SetBufferRead(move(buffer_p)); + SetBufferRead(std::move(buffer_p)); if (options.delimiter.size() > 1 || options.escape.size() > 1 || options.quote.size() > 1) { throw InternalException("Parallel CSV reader cannot handle CSVs with multi-byte delimiters/escapes/quotes"); } @@ -91554,20 +96286,39 @@ ParallelCSVReader::~ParallelCSVReader() { } void ParallelCSVReader::Initialize(const vector &requested_types) { - sql_types = requested_types; - InitParseChunk(sql_types.size()); - InitInsertChunkIdx(sql_types.size()); + return_types = requested_types; + InitParseChunk(return_types.size()); + InitInsertChunkIdx(return_types.size()); +} + +bool ParallelCSVReader::NewLineDelimiter(bool carry, bool carry_followed_by_nl, bool first_char) { + // Set the delimiter if not set yet. + SetNewLineDelimiter(carry, carry_followed_by_nl); + D_ASSERT(options.new_line == NewLineIdentifier::SINGLE || options.new_line == NewLineIdentifier::CARRY_ON); + if (options.new_line == NewLineIdentifier::SINGLE) { + return (!carry) || (carry && !carry_followed_by_nl); + } + return (carry && carry_followed_by_nl) || (!carry && first_char); } bool ParallelCSVReader::SetPosition(DataChunk &insert_chunk) { if (buffer->buffer->IsCSVFileFirstBuffer() && start_buffer == position_buffer && start_buffer == buffer->buffer->GetStart()) { + verification_positions.beginning_of_first_line = position_buffer; + verification_positions.end_of_last_line = position_buffer; // First buffer doesn't need any setting // Unless we have a header if (options.header && options.auto_detect) { for (; position_buffer < end_buffer; position_buffer++) { if (StringUtil::CharacterIsNewline((*buffer)[position_buffer])) { + bool carrier_return = (*buffer)[position_buffer] == '\r'; position_buffer++; + if (carrier_return && position_buffer < buffer_size && (*buffer)[position_buffer] == '\n') { + position_buffer++; + } + if (position_buffer > end_buffer) { + return false; + } return true; } } @@ -91586,26 +96337,50 @@ bool ParallelCSVReader::SetPosition(DataChunk &insert_chunk) { first_line_chunk.Initialize(allocator, insert_chunk.GetTypes()); for (; position_buffer < end_buffer; position_buffer++) { if (StringUtil::CharacterIsNewline((*buffer)[position_buffer])) { + bool carriage_return = (*buffer)[position_buffer] == '\r'; + bool carriage_return_followed = false; position_buffer++; - break; + if (position_buffer < end_buffer) { + if (carriage_return && (*buffer)[position_buffer] == '\n') { + carriage_return_followed = true; + position_buffer++; + } + } + if (NewLineDelimiter(carriage_return, carriage_return_followed, position_buffer - 1 == start_buffer)) { + break; + } } } - D_ASSERT(position_buffer <= end_buffer); - if (position_buffer == end_buffer && !StringUtil::CharacterIsNewline((*buffer)[position_buffer - 1])) { + + if (position_buffer >= end_buffer && !StringUtil::CharacterIsNewline((*buffer)[position_buffer - 1])) { + break; + } + + if (position_buffer > end_buffer && options.new_line == NewLineIdentifier::CARRY_ON && + (*buffer)[position_buffer - 1] == '\n') { break; } idx_t position_set = position_buffer; start_buffer = position_buffer; // We check if we can add this line successfully_read_first_line = TryParseSimpleCSV(first_line_chunk, error_message, true); - start_buffer = position_set; + end_buffer = end_buffer_real; - position_buffer = position_set; - if (end_buffer == position_buffer) { + start_buffer = position_set; + if (position_buffer >= end_buffer) { + if (successfully_read_first_line) { + position_buffer = position_set; + } break; } + position_buffer = position_set; + } + if (verification_positions.beginning_of_first_line == 0) { + verification_positions.beginning_of_first_line = position_buffer; } + verification_positions.end_of_last_line = position_buffer; + finished = false; return successfully_read_first_line; } @@ -91622,13 +96397,22 @@ void ParallelCSVReader::SetBufferRead(unique_ptr buffer_read_p) { buffer_size = buffer_read_p->buffer->GetBufferSize(); } linenr = buffer_read_p->estimated_linenr; - buffer = move(buffer_read_p); + buffer = std::move(buffer_read_p); linenr_estimated = true; reached_remainder_state = false; + verification_positions.beginning_of_first_line = 0; + verification_positions.end_of_last_line = 0; + finished = false; D_ASSERT(end_buffer <= buffer_size); } +VerificationPositions ParallelCSVReader::GetVerificationPositions() { + verification_positions.beginning_of_first_line += buffer->buffer->GetCSVGlobalStart(); + verification_positions.end_of_last_line += buffer->buffer->GetCSVGlobalStart(); + return verification_positions; +} + // If BufferRemainder returns false, it means we are done scanning this buffer and should go to the end_state bool ParallelCSVReader::BufferRemainder() { if (position_buffer >= end_buffer && !reached_remainder_state) { @@ -91647,7 +96431,6 @@ bool ParallelCSVReader::BufferRemainder() { } bool ParallelCSVReader::TryParseSimpleCSV(DataChunk &insert_chunk, string &error_message, bool try_add_line) { - // used for parsing algorithm D_ASSERT(end_buffer <= buffer_size); bool finished_chunk = false; @@ -91655,10 +96438,15 @@ bool ParallelCSVReader::TryParseSimpleCSV(DataChunk &insert_chunk, string &error idx_t offset = 0; bool has_quotes = false; vector escape_positions; - if (start_buffer == buffer->buffer_start && !try_add_line) { + if ((start_buffer == buffer->buffer_start || start_buffer == buffer->buffer_end) && !try_add_line) { // First time reading this buffer piece if (!SetPosition(insert_chunk)) { // This means the buffer size does not contain a new line + if (position_buffer - start_buffer == options.buffer_size) { + error_message = "Line does not fit in one buffer. Increase the buffer size."; + return false; + } + finished = true; return true; } } @@ -91696,7 +96484,7 @@ normal : { goto add_value; } else if (StringUtil::CharacterIsNewline(c)) { // newline: add row - if (column > 0 || try_add_line) { + if (column > 0 || try_add_line || insert_chunk.data.size() == 1) { goto add_row; } } @@ -91730,20 +96518,21 @@ add_row : { if (try_add_line) { bool success = column == insert_chunk.ColumnCount(); if (success) { - AddRow(insert_chunk, column); + AddRow(insert_chunk, column, error_message); success = Flush(insert_chunk); } reached_remainder_state = false; parse_chunk.Reset(); return success; } else { - finished_chunk = AddRow(insert_chunk, column); + finished_chunk = AddRow(insert_chunk, column, error_message); } // increase position by 1 and move start to the new position offset = 0; has_quotes = false; start_buffer = ++position_buffer; - if (reached_remainder_state || finished_chunk) { + verification_positions.end_of_last_line = position_buffer; + if (reached_remainder_state) { goto final_state; } if (!BufferRemainder()) { @@ -91751,8 +96540,37 @@ add_row : { } if (carriage_return) { // \r newline, go to special state that parses an optional \n afterwards - goto carriage_return; + // optionally skips a newline (\n) character, which allows \r\n to be interpreted as a single line + if ((*buffer)[position_buffer] == '\n') { + if (options.new_line == NewLineIdentifier::SINGLE) { + error_message = "Wrong NewLine Identifier. Expecting \\r\\n"; + return false; + } + // newline after carriage return: skip + // increase position by 1 and move start to the new position + start_buffer = ++position_buffer; + verification_positions.end_of_last_line = position_buffer; + if (reached_remainder_state) { + goto final_state; + } + } else { + if (options.new_line == NewLineIdentifier::CARRY_ON) { + error_message = "Wrong NewLine Identifier. Expecting \\r or \\n"; + return false; + } + } + if (!BufferRemainder()) { + goto final_state; + } + if (reached_remainder_state || finished_chunk) { + goto final_state; + } + goto value_start; } else { + if (options.new_line == NewLineIdentifier::CARRY_ON) { + error_message = "Wrong NewLine Identifier. Expecting \\r or \\n"; + return false; + } // \n newline, move to value start if (finished_chunk) { goto final_state; @@ -91848,44 +96666,43 @@ handle_escape : { // escape was followed by quote or escape, go back to quoted state goto in_quotes; } - -carriage_return : { - /* state: carriage_return */ - // this stage optionally skips a newline (\n) character, which allows \r\n to be interpreted as a single line - if ((*buffer)[position_buffer] == '\n') { - // newline after carriage return: skip - // increase position by 1 and move start to the new position - start_buffer = ++position_buffer; - if (position_buffer >= buffer_size) { - // file ends right after delimiter, go to final state - goto final_state; - } - } - goto value_start; -} final_state : { /* state: final_stage reached after we finished reading the end_buffer of the csv buffer */ // reset end buffer end_buffer = buffer->buffer_end; + if (position_buffer == end_buffer) { + reached_remainder_state = false; + } if (finished_chunk) { + if (position_buffer >= end_buffer) { + if (position_buffer == end_buffer && StringUtil::CharacterIsNewline((*buffer)[position_buffer - 1]) && + position_buffer < buffer_size) { + // last position is a new line, we still have to go through one more line of this buffer + finished = false; + } else { + finished = true; + } + } return true; } // If this is the last buffer, we have to read the last value - if (buffer->buffer->IsCSVFileLastBuffer() || (buffer->next_buffer->IsCSVFileLastBuffer())) { - if (column > 0 || try_add_line) { + if (buffer->buffer->IsCSVFileLastBuffer() || (buffer->next_buffer && buffer->next_buffer->IsCSVFileLastBuffer())) { + if (column > 0 || try_add_line || (insert_chunk.data.size() == 1 && start_buffer != position_buffer)) { // remaining values to be added to the chunk - AddValue(buffer->GetValue(start_buffer, position_buffer, offset), column, escape_positions, has_quotes); + auto str_value = buffer->GetValue(start_buffer, position_buffer, offset); + AddValue(str_value, column, escape_positions, has_quotes); if (try_add_line) { - bool success = column == sql_types.size(); + bool success = column == return_types.size(); if (success) { - AddRow(insert_chunk, column); + AddRow(insert_chunk, column, error_message); success = Flush(insert_chunk); } parse_chunk.Reset(); reached_remainder_state = false; return success; } else { - AddRow(insert_chunk, column); + AddRow(insert_chunk, column, error_message); + verification_positions.end_of_last_line = position_buffer; } } } @@ -91893,6 +96710,22 @@ final_state : { if (mode == ParserMode::PARSING) { Flush(insert_chunk); } + if (position_buffer != verification_positions.end_of_last_line && + !StringUtil::CharacterIsNewline((*buffer)[position_buffer - 1])) { + error_message = "Line does not fit in one buffer. Increase the buffer size."; + return false; + } + if (position_buffer >= end_buffer) { + if (position_buffer >= end_buffer) { + if (position_buffer == end_buffer && StringUtil::CharacterIsNewline((*buffer)[position_buffer - 1]) && + position_buffer < buffer_size) { + // last position is a new line, we still have to go through one more line of this buffer + finished = false; + } else { + finished = true; + } + } + } return true; }; } @@ -91947,89 +96780,23 @@ bool ParallelCSVReader::TryParseCSV(ParserMode parser_mode, DataChunk &insert_ch -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/index_vector.hpp -// -// -//===----------------------------------------------------------------------===// - - - namespace duckdb { -template -class IndexVector { -public: - void push_back(T element) { - internal_vector.push_back(move(element)); - } - - T &operator[](INDEX_TYPE idx) { - return internal_vector[idx.index]; - } - - const T &operator[](INDEX_TYPE idx) const { - return internal_vector[idx.index]; - } - - idx_t size() const { - return internal_vector.size(); - } - - bool empty() const { - return internal_vector.empty(); - } - - void reserve(idx_t size) { - internal_vector.reserve(size); - } - - typename vector::iterator begin() { - return internal_vector.begin(); - } - typename vector::iterator end() { - return internal_vector.end(); - } - typename vector::const_iterator cbegin() { - return internal_vector.cbegin(); - } - typename vector::const_iterator cend() { - return internal_vector.cend(); - } - typename vector::const_iterator begin() const { - return internal_vector.begin(); - } - typename vector::const_iterator end() const { - return internal_vector.end(); - } - -private: - vector internal_vector; -}; - -template -using physical_index_vector_t = IndexVector; - -template -using logical_index_vector_t = IndexVector; - -} // namespace duckdb - - -namespace duckdb { +class InsertLocalState; //! Physically insert a set of data into a table class PhysicalInsert : public PhysicalOperator { public: //! INSERT INTO PhysicalInsert(vector types, TableCatalogEntry *table, physical_index_vector_t column_index_map, - vector> bound_defaults, idx_t estimated_cardinality, bool return_chunk, - bool parallel); + vector> bound_defaults, vector> set_expressions, + vector set_columns, vector set_types, idx_t estimated_cardinality, + bool return_chunk, bool parallel, OnConflictAction action_type, + unique_ptr on_conflict_condition, unique_ptr do_update_condition, + unordered_set on_conflict_filter, vector columns_to_fetch); //! CREATE TABLE AS PhysicalInsert(LogicalOperator &op, SchemaCatalogEntry *schema, unique_ptr info, idx_t estimated_cardinality, bool parallel); @@ -92051,6 +96818,27 @@ class PhysicalInsert : public PhysicalOperator { //! Whether or not the INSERT can be executed in parallel //! This insert is not order preserving if executed in parallel bool parallel; + // Which action to perform on conflict + OnConflictAction action_type; + + // The DO UPDATE set expressions, if 'action_type' is UPDATE + vector> set_expressions; + // Which columns are targeted by the set expressions + vector set_columns; + // The types of the columns targeted by a SET expression + vector set_types; + + // Condition for the ON CONFLICT clause + unique_ptr on_conflict_condition; + // Condition for the DO UPDATE clause + unique_ptr do_update_condition; + // The column ids to apply the ON CONFLICT on + unordered_set conflict_target; + + // Column ids from the original table to fetch + vector columns_to_fetch; + // Matching types to the column ids to fetch + vector types_to_fetch; public: // Source interface @@ -92082,6 +96870,14 @@ class PhysicalInsert : public PhysicalOperator { static void ResolveDefaults(TableCatalogEntry *table, DataChunk &chunk, const physical_index_vector_t &column_index_map, ExpressionExecutor &defaults_executor, DataChunk &result); + +protected: + void CombineExistingAndInsertTuples(DataChunk &result, DataChunk &scan_chunk, DataChunk &input_chunk, + ClientContext &client) const; + void OnConflictHandling(TableCatalogEntry *table, ExecutionContext &context, InsertLocalState &lstate) const; + void PerformOnConflictAction(ExecutionContext &context, DataChunk &chunk, TableCatalogEntry *table, + Vector &row_ids) const; + void RegisterUpdatedRows(InsertLocalState &lstate, const Vector &row_ids, idx_t count) const; }; } // namespace duckdb @@ -92111,6 +96907,8 @@ class PhysicalBatchInsert : public PhysicalOperator { SchemaCatalogEntry *schema; //! Create table info, in case of CREATE TABLE AS unique_ptr info; + // Which action to perform on conflict + OnConflictAction action_type; public: // Source interface @@ -92151,20 +96949,21 @@ class PhysicalBatchInsert : public PhysicalOperator { + namespace duckdb { PhysicalBatchInsert::PhysicalBatchInsert(vector types, TableCatalogEntry *table, physical_index_vector_t column_index_map, vector> bound_defaults, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::BATCH_INSERT, move(types), estimated_cardinality), + : PhysicalOperator(PhysicalOperatorType::BATCH_INSERT, std::move(types), estimated_cardinality), column_index_map(std::move(column_index_map)), insert_table(table), insert_types(table->GetTypes()), - bound_defaults(move(bound_defaults)) { + bound_defaults(std::move(bound_defaults)) { } PhysicalBatchInsert::PhysicalBatchInsert(LogicalOperator &op, SchemaCatalogEntry *schema, unique_ptr info_p, idx_t estimated_cardinality) : PhysicalOperator(PhysicalOperatorType::BATCH_CREATE_TABLE_AS, op.types, estimated_cardinality), - insert_table(nullptr), schema(schema), info(move(info_p)) { + insert_table(nullptr), schema(schema), info(std::move(info_p)) { PhysicalInsert::GetInsertInfo(*info, insert_types, bound_defaults); } @@ -92182,7 +96981,7 @@ class CollectionMerger { public: void AddCollection(unique_ptr collection) { - current_collections.push_back(move(collection)); + current_collections.push_back(std::move(collection)); } bool Empty() { @@ -92193,7 +96992,7 @@ class CollectionMerger { if (Empty()) { return nullptr; } - unique_ptr new_collection = move(current_collections[0]); + unique_ptr new_collection = std::move(current_collections[0]); if (current_collections.size() > 1) { // we have gathered multiple collections: create one big collection and merge that auto &types = new_collection->GetTypes(); @@ -92242,7 +97041,7 @@ class BatchInsertGlobalState : public GlobalSinkState { } mutex lock; - TableCatalogEntry *table; + DuckTableEntry *table; idx_t insert_count; map> collections; @@ -92265,7 +97064,7 @@ class BatchInsertGlobalState : public GlobalSinkState { } else { // add the D_ASSERT(result); - result->push_back(move(entry->second)); + result->push_back(std::move(entry->second)); collections.erase(batch_index); } return true; @@ -92283,7 +97082,7 @@ class BatchInsertGlobalState : public GlobalSinkState { OptimisticDataWriter &writer) { CollectionMerger merger(context); for (auto &collection : merge_collections) { - merger.AddCollection(move(collection)); + merger.AddCollection(std::move(collection)); } return merger.Flush(writer); } @@ -92333,7 +97132,7 @@ class BatchInsertGlobalState : public GlobalSinkState { // note that we need to gather them in order of batch index for (idx_t i = start_batch_index; i <= end_batch_index; i++) { if (i == batch_index) { - merge_collections.push_back(move(current_collection)); + merge_collections.push_back(std::move(current_collection)); continue; } auto can_merge = CheckMerge(i, merge_collections); @@ -92345,13 +97144,13 @@ class BatchInsertGlobalState : public GlobalSinkState { } if (merge_collections.empty()) { // no collections to merge together - add the collection to the batch index - collections[batch_index] = move(current_collection); + collections[batch_index] = std::move(current_collection); } } if (!merge_collections.empty()) { // merge together the collections D_ASSERT(writer); - auto final_collection = MergeCollections(context, move(merge_collections), *writer); + auto final_collection = MergeCollections(context, std::move(merge_collections), *writer); D_ASSERT(final_collection->GetTotalRows() == merge_count); D_ASSERT(final_collection->GetTotalRows() >= RowGroup::ROW_GROUP_SIZE); if (written_to_disk) { @@ -92361,7 +97160,7 @@ class BatchInsertGlobalState : public GlobalSinkState { { lock_guard l(lock); VerifyUniqueBatch(batch_index); - collections[batch_index] = move(final_collection); + collections[batch_index] = std::move(final_collection); } } } @@ -92393,9 +97192,9 @@ class BatchInsertLocalState : public LocalSinkState { writer->FlushToDisk(*current_collection, true); } - void CreateNewCollection(TableCatalogEntry *table, const vector &insert_types) { - auto &table_info = table->storage->info; - auto &block_manager = TableIOManager::Get(*table->storage).GetBlockManagerForRowData(); + void CreateNewCollection(DuckTableEntry *table, const vector &insert_types) { + auto &table_info = table->GetStorage().info; + auto &block_manager = TableIOManager::Get(table->GetStorage()).GetBlockManagerForRowData(); current_collection = make_unique(table_info, block_manager, insert_types, MAX_ROW_ID); current_collection->InitializeEmpty(); current_collection->InitializeAppend(current_append_state); @@ -92408,13 +97207,15 @@ unique_ptr PhysicalBatchInsert::GetGlobalSinkState(ClientContex if (info) { // CREATE TABLE AS D_ASSERT(!insert_table); - auto &catalog = Catalog::GetCatalog(context); - result->table = (TableCatalogEntry *)catalog.CreateTable(context, schema, info.get()); + auto &catalog = *schema->catalog; + result->table = + (DuckTableEntry *)catalog.CreateTable(catalog.GetCatalogTransaction(context), schema, info.get()); } else { D_ASSERT(insert_table); - result->table = insert_table; + D_ASSERT(insert_table->IsDuckTable()); + result->table = (DuckTableEntry *)insert_table; } - return move(result); + return std::move(result); } unique_ptr PhysicalBatchInsert::GetLocalSinkState(ExecutionContext &context) const { @@ -92433,18 +97234,20 @@ SinkResultType PhysicalBatchInsert::Sink(ExecutionContext &context, GlobalSinkSt lock_guard l(gstate.lock); // no collection yet: create a new one lstate.CreateNewCollection(table, insert_types); - lstate.writer = gstate.table->storage->CreateOptimisticWriter(context.client); + lstate.writer = gstate.table->GetStorage().CreateOptimisticWriter(context.client); } else if (lstate.current_index != lstate.batch_index) { // batch index has changed: move the old collection to the global state and create a new collection TransactionData tdata(0, 0); lstate.current_collection->FinalizeAppend(tdata, lstate.current_append_state); lstate.FlushToDisk(); - gstate.AddCollection(context.client, lstate.current_index, move(lstate.current_collection), lstate.writer, + gstate.AddCollection(context.client, lstate.current_index, std::move(lstate.current_collection), lstate.writer, &lstate.written_to_disk); lstate.CreateNewCollection(table, insert_types); } lstate.current_index = lstate.batch_index; - table->storage->VerifyAppendConstraints(*table, context.client, lstate.insert_chunk); + + table->GetStorage().VerifyAppendConstraints(*table, context.client, lstate.insert_chunk); + auto new_row_group = lstate.current_collection->Append(lstate.insert_chunk, lstate.current_append_state); if (new_row_group) { lstate.writer->CheckFlushToDisk(*lstate.current_collection); @@ -92469,7 +97272,7 @@ void PhysicalBatchInsert::Combine(ExecutionContext &context, GlobalSinkState &gs TransactionData tdata(0, 0); lstate.current_collection->FinalizeAppend(tdata, lstate.current_append_state); - gstate.AddCollection(context.client, lstate.current_index, move(lstate.current_collection)); + gstate.AddCollection(context.client, lstate.current_index, std::move(lstate.current_collection)); } SinkFinalizeType PhysicalBatchInsert::Finalize(Pipeline &pipeline, Event &event, ClientContext &context, @@ -92481,29 +97284,29 @@ SinkFinalizeType PhysicalBatchInsert::Finalize(Pipeline &pipeline, Event &event, vector> mergers; unique_ptr current_merger; - auto &storage = *gstate.table->storage; + auto &storage = gstate.table->GetStorage(); for (auto &collection : gstate.collections) { if (collection.second->GetTotalRows() < LocalStorage::MERGE_THRESHOLD) { // this collection has very few rows: add it to the merge set if (!current_merger) { current_merger = make_unique(context); } - current_merger->AddCollection(move(collection.second)); + current_merger->AddCollection(std::move(collection.second)); } else { // this collection has a lot of rows: it does not need to be merged // create a separate collection merger only for this entry if (current_merger) { // we have small collections remaining: flush them - mergers.push_back(move(current_merger)); + mergers.push_back(std::move(current_merger)); current_merger.reset(); } auto larger_merger = make_unique(context); - larger_merger->AddCollection(move(collection.second)); - mergers.push_back(move(larger_merger)); + larger_merger->AddCollection(std::move(collection.second)); + mergers.push_back(std::move(larger_merger)); } } if (current_merger) { - mergers.push_back(move(current_merger)); + mergers.push_back(std::move(current_merger)); } // now that we have created all of the mergers, perform the actual merging @@ -92577,6 +97380,14 @@ class PhysicalCopyToFile : public PhysicalOperator { unique_ptr bind_data; string file_path; bool use_tmp_file; + bool allow_overwrite; + bool parallel; + bool per_thread_output; + + bool partition_output; + vector partition_columns; + vector names; + vector expected_types; public: // Source interface @@ -92601,12 +97412,18 @@ class PhysicalCopyToFile : public PhysicalOperator { bool IsOrderDependent() const override { return true; } + + bool ParallelSink() const override { + return per_thread_output || partition_output || parallel; + } }; } // namespace duckdb + + #include namespace duckdb { @@ -92614,18 +97431,30 @@ namespace duckdb { class CopyToFunctionGlobalState : public GlobalSinkState { public: explicit CopyToFunctionGlobalState(unique_ptr global_state) - : rows_copied(0), global_state(move(global_state)) { + : rows_copied(0), last_file_offset(0), global_state(std::move(global_state)) { } - + mutex lock; idx_t rows_copied; + idx_t last_file_offset; unique_ptr global_state; + + //! shared state for HivePartitionedColumnData + shared_ptr partition_state; }; class CopyToFunctionLocalState : public LocalSinkState { public: - explicit CopyToFunctionLocalState(unique_ptr local_state) : local_state(move(local_state)) { + explicit CopyToFunctionLocalState(unique_ptr local_state) + : local_state(std::move(local_state)), writer_offset(0) { } + unique_ptr global_state; unique_ptr local_state; + + //! Buffers the tuples in partitions before writing + unique_ptr part_buffer; + unique_ptr part_buffer_append_state; + + idx_t writer_offset; }; //===--------------------------------------------------------------------===// @@ -92642,8 +97471,8 @@ void MoveTmpFile(ClientContext &context, const string &tmp_file_path) { PhysicalCopyToFile::PhysicalCopyToFile(vector types, CopyFunction function_p, unique_ptr bind_data, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::COPY_TO_FILE, move(types), estimated_cardinality), - function(move(function_p)), bind_data(move(bind_data)) { + : PhysicalOperator(PhysicalOperatorType::COPY_TO_FILE, std::move(types), estimated_cardinality), + function(std::move(function_p)), bind_data(std::move(bind_data)), parallel(false) { } SinkResultType PhysicalCopyToFile::Sink(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate, @@ -92651,27 +97480,100 @@ SinkResultType PhysicalCopyToFile::Sink(ExecutionContext &context, GlobalSinkSta auto &g = (CopyToFunctionGlobalState &)gstate; auto &l = (CopyToFunctionLocalState &)lstate; - g.rows_copied += input.size(); - function.copy_to_sink(context, *bind_data, *g.global_state, *l.local_state, input); + if (partition_output) { + l.part_buffer->Append(*l.part_buffer_append_state, input); + return SinkResultType::NEED_MORE_INPUT; + } + + { + lock_guard glock(g.lock); + g.rows_copied += input.size(); + } + function.copy_to_sink(context, *bind_data, per_thread_output ? *l.global_state : *g.global_state, *l.local_state, + input); return SinkResultType::NEED_MORE_INPUT; } +static void CreateDir(const string &dir_path, FileSystem &fs) { + if (!fs.DirectoryExists(dir_path)) { + fs.CreateDirectory(dir_path); + } +} + +static string CreateDirRecursive(const vector &cols, const vector &names, const vector &values, + string path, FileSystem &fs) { + CreateDir(path, fs); + + for (idx_t i = 0; i < cols.size(); i++) { + auto partition_col_name = names[cols[i]]; + auto partition_value = values[i]; + string p_dir = partition_col_name + "=" + partition_value.ToString(); + path = fs.JoinPath(path, p_dir); + CreateDir(path, fs); + } + + return path; +} + void PhysicalCopyToFile::Combine(ExecutionContext &context, GlobalSinkState &gstate, LocalSinkState &lstate) const { auto &g = (CopyToFunctionGlobalState &)gstate; auto &l = (CopyToFunctionLocalState &)lstate; + if (partition_output) { + auto &fs = FileSystem::GetFileSystem(context.client); + l.part_buffer->FlushAppendState(*l.part_buffer_append_state); + auto &partitions = l.part_buffer->GetPartitions(); + auto partition_key_map = l.part_buffer->GetReverseMap(); + + string trimmed_path = file_path; + StringUtil::RTrim(trimmed_path, fs.PathSeparator()); + + for (idx_t i = 0; i < partitions.size(); i++) { + string hive_path = + CreateDirRecursive(partition_columns, names, partition_key_map[i]->values, trimmed_path, fs); + string full_path = fs.JoinPath(hive_path, "data_" + to_string(l.writer_offset) + "." + function.extension); + if (fs.FileExists(full_path) && !allow_overwrite) { + throw IOException("failed to create " + full_path + + ", file exists! Enable ALLOW_OVERWRITE option to force writing"); + } + // Create a writer for the current file + auto fun_data_global = function.copy_to_initialize_global(context.client, *bind_data, full_path); + auto fun_data_local = function.copy_to_initialize_local(context, *bind_data); + + for (auto &chunk : partitions[i]->Chunks()) { + function.copy_to_sink(context, *bind_data, *fun_data_global, *fun_data_local, chunk); + } + + function.copy_to_combine(context, *bind_data, *fun_data_global, *fun_data_local); + function.copy_to_finalize(context.client, *bind_data, *fun_data_global); + } + + return; + } + if (function.copy_to_combine) { - function.copy_to_combine(context, *bind_data, *g.global_state, *l.local_state); + function.copy_to_combine(context, *bind_data, per_thread_output ? *l.global_state : *g.global_state, + *l.local_state); + + if (per_thread_output) { + function.copy_to_finalize(context.client, *bind_data, *l.global_state); + } } } SinkFinalizeType PhysicalCopyToFile::Finalize(Pipeline &pipeline, Event &event, ClientContext &context, GlobalSinkState &gstate_p) const { auto &gstate = (CopyToFunctionGlobalState &)gstate_p; + if (per_thread_output || partition_output) { + // already happened in combine + return SinkFinalizeType::READY; + } if (function.copy_to_finalize) { function.copy_to_finalize(context, *bind_data, *gstate.global_state); if (use_tmp_file) { + D_ASSERT(!per_thread_output); // FIXME + D_ASSERT(!partition_output); // FIXME MoveTmpFile(context, file_path); } } @@ -92679,9 +97581,68 @@ SinkFinalizeType PhysicalCopyToFile::Finalize(Pipeline &pipeline, Event &event, } unique_ptr PhysicalCopyToFile::GetLocalSinkState(ExecutionContext &context) const { - return make_unique(function.copy_to_initialize_local(context, *bind_data)); + if (partition_output) { + auto state = make_unique(nullptr); + { + auto &g = (CopyToFunctionGlobalState &)*sink_state; + lock_guard glock(g.lock); + state->writer_offset = g.last_file_offset++; + + state->part_buffer = make_unique(context.client, expected_types, + partition_columns, g.partition_state); + state->part_buffer_append_state = make_unique(); + state->part_buffer->InitializeAppendState(*state->part_buffer_append_state); + } + return std::move(state); + } + auto res = make_unique(function.copy_to_initialize_local(context, *bind_data)); + if (per_thread_output) { + idx_t this_file_offset; + { + auto &g = (CopyToFunctionGlobalState &)*sink_state; + lock_guard glock(g.lock); + this_file_offset = g.last_file_offset++; + } + auto &fs = FileSystem::GetFileSystem(context.client); + string output_path = + fs.JoinPath(file_path, StringUtil::Format("out_%llu", this_file_offset) + "." + function.extension); + if (fs.FileExists(output_path) && !allow_overwrite) { + throw IOException("%s exists! Enable ALLOW_OVERWRITE option to force writing", output_path); + } + res->global_state = function.copy_to_initialize_global(context.client, *bind_data, output_path); + } + return std::move(res); } + unique_ptr PhysicalCopyToFile::GetGlobalSinkState(ClientContext &context) const { + + if (partition_output || per_thread_output) { + auto &fs = FileSystem::GetFileSystem(context); + + if (fs.FileExists(file_path) && !allow_overwrite) { + throw IOException("%s exists! Enable ALLOW_OVERWRITE option to force writing", file_path); + } + if (!fs.DirectoryExists(file_path)) { + fs.CreateDirectory(file_path); + } else if (!allow_overwrite) { + idx_t n_files = 0; + fs.ListFiles( + file_path, [&n_files](const string &path, bool) { n_files++; }, FileOpener::Get(context)); + if (n_files > 0) { + throw IOException("Directory %s is not empty! Enable ALLOW_OVERWRITE option to force writing", + file_path); + } + } + + auto state = make_unique(nullptr); + + if (partition_output) { + state->partition_state = make_shared(); + } + + return std::move(state); + } + return make_unique(function.copy_to_initialize_global(context, *bind_data, file_path)); } @@ -92734,7 +97695,7 @@ class PhysicalDelete : public PhysicalOperator { public: PhysicalDelete(vector types, TableCatalogEntry &tableref, DataTable &table, idx_t row_id_index, idx_t estimated_cardinality, bool return_chunk) - : PhysicalOperator(PhysicalOperatorType::DELETE_OPERATOR, move(types), estimated_cardinality), + : PhysicalOperator(PhysicalOperatorType::DELETE_OPERATOR, std::move(types), estimated_cardinality), tableref(tableref), table(table), row_id_index(row_id_index), return_chunk(return_chunk) { } @@ -92774,6 +97735,7 @@ class PhysicalDelete : public PhysicalOperator { + namespace duckdb { //===--------------------------------------------------------------------===// @@ -92804,7 +97766,7 @@ SinkResultType PhysicalDelete::Sink(ExecutionContext &context, GlobalSinkState & auto &ustate = (DeleteLocalState &)lstate; // get rows and - auto &transaction = Transaction::GetTransaction(context.client); + auto &transaction = DuckTransaction::Get(context.client, table.db); auto &row_identifiers = input.data[row_id_index]; vector column_ids; @@ -92910,6 +97872,9 @@ struct ExportedTableData { //! Name of the schema string schema_name; + //! Name of the database + string database_name; + //! Path to be exported string file_path; }; @@ -92932,8 +97897,8 @@ class PhysicalExport : public PhysicalOperator { public: PhysicalExport(vector types, CopyFunction function, unique_ptr info, idx_t estimated_cardinality, BoundExportData exported_tables) - : PhysicalOperator(PhysicalOperatorType::EXPORT, move(types), estimated_cardinality), - function(std::move(function)), info(move(info)), exported_tables(move(exported_tables)) { + : PhysicalOperator(PhysicalOperatorType::EXPORT, std::move(types), estimated_cardinality), + function(std::move(function)), info(std::move(info)), exported_tables(std::move(exported_tables)) { } //! The copy function to use to read the file @@ -93084,7 +98049,7 @@ void PhysicalExport::GetData(ExecutionContext &context, DataChunk &chunk, Global vector indexes; vector macros; - auto schema_list = Catalog::GetCatalog(ccontext).schemas->GetEntries(context.client); + auto schema_list = Catalog::GetSchemas(ccontext, info->catalog); for (auto &schema : schema_list) { if (!schema->internal) { schemas.push_back(schema); @@ -93190,21 +98155,52 @@ vector PhysicalExport::GetSources() const { + + + + + + namespace duckdb { -PhysicalInsert::PhysicalInsert(vector types, TableCatalogEntry *table, +PhysicalInsert::PhysicalInsert(vector types_p, TableCatalogEntry *table, physical_index_vector_t column_index_map, - vector> bound_defaults, idx_t estimated_cardinality, - bool return_chunk, bool parallel) - : PhysicalOperator(PhysicalOperatorType::INSERT, move(types), estimated_cardinality), + vector> bound_defaults, + vector> set_expressions, vector set_columns, + vector set_types, idx_t estimated_cardinality, bool return_chunk, + bool parallel, OnConflictAction action_type, + unique_ptr on_conflict_condition_p, + unique_ptr do_update_condition_p, unordered_set conflict_target_p, + vector columns_to_fetch_p) + : PhysicalOperator(PhysicalOperatorType::INSERT, std::move(types_p), estimated_cardinality), column_index_map(std::move(column_index_map)), insert_table(table), insert_types(table->GetTypes()), - bound_defaults(move(bound_defaults)), return_chunk(return_chunk), parallel(parallel) { + bound_defaults(std::move(bound_defaults)), return_chunk(return_chunk), parallel(parallel), + action_type(action_type), set_expressions(std::move(set_expressions)), set_columns(std::move(set_columns)), + set_types(std::move(set_types)), on_conflict_condition(std::move(on_conflict_condition_p)), + do_update_condition(std::move(do_update_condition_p)), conflict_target(std::move(conflict_target_p)), + columns_to_fetch(std::move(columns_to_fetch_p)) { + + if (action_type == OnConflictAction::THROW) { + return; + } + + D_ASSERT(set_expressions.size() == set_columns.size()); + + // One or more columns are referenced from the existing table, + // we use the 'insert_types' to figure out which types these columns have + types_to_fetch = vector(columns_to_fetch.size(), LogicalType::SQLNULL); + for (idx_t i = 0; i < columns_to_fetch.size(); i++) { + auto &id = columns_to_fetch[i]; + D_ASSERT(id < insert_types.size()); + types_to_fetch[i] = insert_types[id]; + } } PhysicalInsert::PhysicalInsert(LogicalOperator &op, SchemaCatalogEntry *schema, unique_ptr info_p, idx_t estimated_cardinality, bool parallel) : PhysicalOperator(PhysicalOperatorType::CREATE_TABLE_AS, op.types, estimated_cardinality), insert_table(nullptr), - return_chunk(false), schema(schema), info(move(info_p)), parallel(parallel) { + return_chunk(false), schema(schema), info(std::move(info_p)), parallel(parallel), + action_type(OnConflictAction::THROW) { GetInsertInfo(*info, insert_types, bound_defaults); } @@ -93227,7 +98223,7 @@ class InsertGlobalState : public GlobalSinkState { } mutex lock; - TableCatalogEntry *table; + DuckTableEntry *table; idx_t insert_count; bool initialized; LocalAppendState append_state; @@ -93247,6 +98243,8 @@ class InsertLocalState : public LocalSinkState { TableAppendState local_append_state; unique_ptr local_collection; OptimisticDataWriter *writer; + // Rows that have been updated by a DO UPDATE conflict + unordered_set updated_rows; }; unique_ptr PhysicalInsert::GetGlobalSinkState(ClientContext &context) const { @@ -93254,13 +98252,15 @@ unique_ptr PhysicalInsert::GetGlobalSinkState(ClientContext &co if (info) { // CREATE TABLE AS D_ASSERT(!insert_table); - auto &catalog = Catalog::GetCatalog(context); - result->table = (TableCatalogEntry *)catalog.CreateTable(context, schema, info.get()); + auto &catalog = *schema->catalog; + result->table = + (DuckTableEntry *)catalog.CreateTable(catalog.GetCatalogTransaction(context), schema, info.get()); } else { D_ASSERT(insert_table); - result->table = insert_table; + D_ASSERT(insert_table->IsDuckTable()); + result->table = (DuckTableEntry *)insert_table; } - return move(result); + return std::move(result); } unique_ptr PhysicalInsert::GetLocalSinkState(ExecutionContext &context) const { @@ -93278,7 +98278,7 @@ void PhysicalInsert::ResolveDefaults(TableCatalogEntry *table, DataChunk &chunk, if (!column_index_map.empty()) { // columns specified by the user, use column_index_map - for (auto &col : table->columns.Physical()) { + for (auto &col : table->GetColumns().Physical()) { auto storage_idx = col.StorageOid(); auto mapped_index = column_index_map[col.Physical()]; if (mapped_index == DConstants::INVALID_INDEX) { @@ -93300,20 +98300,218 @@ void PhysicalInsert::ResolveDefaults(TableCatalogEntry *table, DataChunk &chunk, } } +bool AllConflictsMeetCondition(DataChunk &result) { + auto data = FlatVector::GetData(result.data[0]); + for (idx_t i = 0; i < result.size(); i++) { + if (!data[i]) { + return false; + } + } + return true; +} + +void CheckOnConflictCondition(ExecutionContext &context, DataChunk &conflicts, const unique_ptr &condition, + DataChunk &result) { + ExpressionExecutor executor(context.client, *condition); + result.Initialize(context.client, {LogicalType::BOOLEAN}); + executor.Execute(conflicts, result); + result.SetCardinality(conflicts.size()); +} + +void PhysicalInsert::CombineExistingAndInsertTuples(DataChunk &result, DataChunk &scan_chunk, DataChunk &input_chunk, + ClientContext &client) const { + if (types_to_fetch.empty()) { + // We have not scanned the initial table, so we can just duplicate the initial chunk + result.Initialize(client, input_chunk.GetTypes()); + result.Reference(input_chunk); + result.SetCardinality(input_chunk); + return; + } + vector combined_types; + combined_types.reserve(insert_types.size() + types_to_fetch.size()); + combined_types.insert(combined_types.end(), insert_types.begin(), insert_types.end()); + combined_types.insert(combined_types.end(), types_to_fetch.begin(), types_to_fetch.end()); + + result.Initialize(client, combined_types); + result.Reset(); + // Add the VALUES list + for (idx_t i = 0; i < insert_types.size(); i++) { + idx_t col_idx = i; + auto &other_col = input_chunk.data[i]; + auto &this_col = result.data[col_idx]; + D_ASSERT(other_col.GetType() == this_col.GetType()); + this_col.Reference(other_col); + } + // Add the columns from the original conflicting tuples + for (idx_t i = 0; i < types_to_fetch.size(); i++) { + idx_t col_idx = i + insert_types.size(); + auto &other_col = scan_chunk.data[i]; + auto &this_col = result.data[col_idx]; + D_ASSERT(other_col.GetType() == this_col.GetType()); + this_col.Reference(other_col); + } + // This is guaranteed by the requirement of a conflict target to have a condition or set expressions + // Only when we have any sort of condition or SET expression that references the existing table is this possible + // to not be true. + // We can have a SET expression without a conflict target ONLY if there is only 1 Index on the table + // In which case this also can't cause a discrepancy between existing tuple count and insert tuple count + D_ASSERT(input_chunk.size() == scan_chunk.size()); + result.SetCardinality(input_chunk.size()); +} + +void PhysicalInsert::PerformOnConflictAction(ExecutionContext &context, DataChunk &chunk, TableCatalogEntry *table, + Vector &row_ids) const { + if (action_type == OnConflictAction::NOTHING) { + return; + } + + DataChunk update_chunk; // contains only the to-update columns + + // Check the optional condition for the DO UPDATE clause, to filter which rows will be updated + if (do_update_condition) { + DataChunk do_update_filter_result; + do_update_filter_result.Initialize(context.client, {LogicalType::BOOLEAN}); + ExpressionExecutor where_executor(context.client, *do_update_condition); + where_executor.Execute(chunk, do_update_filter_result); + do_update_filter_result.SetCardinality(chunk.size()); + + ManagedSelection selection(chunk.size()); + + auto where_data = FlatVector::GetData(do_update_filter_result.data[0]); + for (idx_t i = 0; i < chunk.size(); i++) { + if (where_data[i]) { + selection.Append(i); + } + } + if (selection.Count() != selection.Size()) { + // Not all conflicts met the condition, need to filter out the ones that don't + chunk.Slice(selection.Selection(), selection.Count()); + chunk.SetCardinality(selection.Count()); + // Also apply this Slice to the to-update row_ids + row_ids.Slice(selection.Selection(), selection.Count()); + } + } + + // Execute the SET expressions + update_chunk.Initialize(context.client, set_types); + ExpressionExecutor executor(context.client, set_expressions); + executor.Execute(chunk, update_chunk); + update_chunk.SetCardinality(chunk); + + auto &data_table = table->GetStorage(); + // Perform the update, using the results of the SET expressions + data_table.Update(*table, context.client, row_ids, set_columns, update_chunk); +} + +// TODO: should we use a hash table to keep track of this instead? +void PhysicalInsert::RegisterUpdatedRows(InsertLocalState &lstate, const Vector &row_ids, idx_t count) const { + // Insert all rows, if any of the rows has already been updated before, we throw an error + auto data = FlatVector::GetData(row_ids); + for (idx_t i = 0; i < count; i++) { + auto result = lstate.updated_rows.insert(data[i]); + if (result.second == false) { + throw InvalidInputException( + "ON CONFLICT DO UPDATE can not update the same row twice in the same command, Ensure that no rows " + "proposed for insertion within the same command have duplicate constrained values"); + } + } +} + +void PhysicalInsert::OnConflictHandling(TableCatalogEntry *table, ExecutionContext &context, + InsertLocalState &lstate) const { + auto &data_table = table->GetStorage(); + if (action_type == OnConflictAction::THROW) { + data_table.VerifyAppendConstraints(*table, context.client, lstate.insert_chunk, nullptr); + return; + } + // Check whether any conflicts arise, and if they all meet the conflict_target + condition + // If that's not the case - We throw the first error + + // We either want to do nothing, or perform an update when conflicts arise + ConflictInfo conflict_info(conflict_target); + ConflictManager conflict_manager(VerifyExistenceType::APPEND, lstate.insert_chunk.size(), &conflict_info); + data_table.VerifyAppendConstraints(*table, context.client, lstate.insert_chunk, &conflict_manager); + conflict_manager.Finalize(); + if (conflict_manager.ConflictCount() == 0) { + // No conflicts found + return; + } + auto &conflicts = conflict_manager.Conflicts(); + auto &row_ids = conflict_manager.RowIds(); + + DataChunk conflict_chunk; // contains only the conflicting values + DataChunk scan_chunk; // contains the original values, that caused the conflict + DataChunk combined_chunk; // contains conflict_chunk + scan_chunk (wide) + + // Filter out everything but the conflicting rows + conflict_chunk.Initialize(context.client, lstate.insert_chunk.GetTypes()); + conflict_chunk.Reference(lstate.insert_chunk); + conflict_chunk.Slice(conflicts.Selection(), conflicts.Count()); + conflict_chunk.SetCardinality(conflicts.Count()); + + if (!types_to_fetch.empty()) { + D_ASSERT(scan_chunk.size() == 0); + // When these values are required for the conditions or the SET expressions, + // then we scan the existing table for the conflicting tuples, using the rowids + scan_chunk.Initialize(context.client, types_to_fetch); + auto fetch_state = make_unique(); + auto &transaction = DuckTransaction::Get(context.client, *table->catalog); + data_table.Fetch(transaction, scan_chunk, columns_to_fetch, row_ids, conflicts.Count(), *fetch_state); + } + + // Splice the Input chunk and the fetched chunk together + CombineExistingAndInsertTuples(combined_chunk, scan_chunk, conflict_chunk, context.client); + + if (on_conflict_condition) { + DataChunk conflict_condition_result; + CheckOnConflictCondition(context, combined_chunk, on_conflict_condition, conflict_condition_result); + bool conditions_met = AllConflictsMeetCondition(conflict_condition_result); + if (!conditions_met) { + // Filter out the tuples that did pass the filter, then run the verify again + ManagedSelection sel(combined_chunk.size()); + auto data = FlatVector::GetData(conflict_condition_result.data[0]); + for (idx_t i = 0; i < combined_chunk.size(); i++) { + if (!data[i]) { + // Only populate the selection vector with the tuples that did not meet the condition + sel.Append(i); + } + } + combined_chunk.Slice(sel.Selection(), sel.Count()); + row_ids.Slice(sel.Selection(), sel.Count()); + data_table.VerifyAppendConstraints(*table, context.client, combined_chunk, nullptr); + throw InternalException("The previous operation was expected to throw but didn't"); + } + } + + RegisterUpdatedRows(lstate, row_ids, combined_chunk.size()); + + PerformOnConflictAction(context, combined_chunk, table, row_ids); + + // Remove the conflicting tuples from the insert chunk + SelectionVector sel_vec(lstate.insert_chunk.size()); + idx_t new_size = + SelectionVector::Inverted(conflicts.Selection(), sel_vec, conflicts.Count(), lstate.insert_chunk.size()); + lstate.insert_chunk.Slice(sel_vec, new_size); + lstate.insert_chunk.SetCardinality(new_size); +} + SinkResultType PhysicalInsert::Sink(ExecutionContext &context, GlobalSinkState &state, LocalSinkState &lstate_p, DataChunk &chunk) const { auto &gstate = (InsertGlobalState &)state; auto &lstate = (InsertLocalState &)lstate_p; auto table = gstate.table; + auto &storage = table->GetStorage(); PhysicalInsert::ResolveDefaults(table, chunk, column_index_map, lstate.default_executor, lstate.insert_chunk); if (!parallel) { if (!gstate.initialized) { - table->storage->InitializeLocalAppend(gstate.append_state, context.client); + storage.InitializeLocalAppend(gstate.append_state, context.client); gstate.initialized = true; } - table->storage->LocalAppend(gstate.append_state, *table, context.client, lstate.insert_chunk); + + OnConflictHandling(table, context, lstate); + storage.LocalAppend(gstate.append_state, *table, context.client, lstate.insert_chunk, true); if (return_chunk) { gstate.return_collection.Append(lstate.insert_chunk); @@ -93324,15 +98522,15 @@ SinkResultType PhysicalInsert::Sink(ExecutionContext &context, GlobalSinkState & // parallel append if (!lstate.local_collection) { lock_guard l(gstate.lock); - auto &table_info = table->storage->info; - auto &block_manager = TableIOManager::Get(*table->storage).GetBlockManagerForRowData(); + auto &table_info = storage.info; + auto &block_manager = TableIOManager::Get(storage).GetBlockManagerForRowData(); lstate.local_collection = make_unique(table_info, block_manager, insert_types, MAX_ROW_ID); lstate.local_collection->InitializeEmpty(); lstate.local_collection->InitializeAppend(lstate.local_append_state); - lstate.writer = gstate.table->storage->CreateOptimisticWriter(context.client); + lstate.writer = gstate.table->GetStorage().CreateOptimisticWriter(context.client); } - table->storage->VerifyAppendConstraints(*table, context.client, lstate.insert_chunk); + OnConflictHandling(table, context, lstate); auto new_row_group = lstate.local_collection->Append(lstate.insert_chunk, lstate.local_append_state); if (new_row_group) { lstate.writer->CheckFlushToDisk(*lstate.local_collection); @@ -93366,13 +98564,14 @@ void PhysicalInsert::Combine(ExecutionContext &context, GlobalSinkState &gstate_ lock_guard lock(gstate.lock); gstate.insert_count += append_count; auto table = gstate.table; - table->storage->InitializeLocalAppend(gstate.append_state, context.client); - auto &transaction = Transaction::GetTransaction(context.client); + auto &storage = table->GetStorage(); + storage.InitializeLocalAppend(gstate.append_state, context.client); + auto &transaction = DuckTransaction::Get(context.client, *table->catalog); lstate.local_collection->Scan(transaction, [&](DataChunk &insert_chunk) { - table->storage->LocalAppend(gstate.append_state, *table, context.client, insert_chunk); + storage.LocalAppend(gstate.append_state, *table, context.client, insert_chunk); return true; }); - table->storage->FinalizeLocalAppend(gstate.append_state); + storage.FinalizeLocalAppend(gstate.append_state); } else { // we have many rows - flush the row group collection to disk (if required) and merge into the transaction-local // state @@ -93381,7 +98580,7 @@ void PhysicalInsert::Combine(ExecutionContext &context, GlobalSinkState &gstate_ lock_guard lock(gstate.lock); gstate.insert_count += append_count; - gstate.table->storage->LocalMerge(context.client, *lstate.local_collection); + gstate.table->GetStorage().LocalMerge(context.client, *lstate.local_collection); } } @@ -93390,7 +98589,8 @@ SinkFinalizeType PhysicalInsert::Finalize(Pipeline &pipeline, Event &event, Clie auto &gstate = (InsertGlobalState &)state; if (!parallel && gstate.initialized) { auto table = gstate.table; - table->storage->FinalizeLocalAppend(gstate.append_state); + auto &storage = table->GetStorage(); + storage.FinalizeLocalAppend(gstate.append_state); } return SinkFinalizeType::READY; } @@ -93505,9 +98705,9 @@ PhysicalUpdate::PhysicalUpdate(vector types, TableCatalogEntry &tab vector columns, vector> expressions, vector> bound_defaults, idx_t estimated_cardinality, bool return_chunk) - : PhysicalOperator(PhysicalOperatorType::UPDATE, move(types), estimated_cardinality), tableref(tableref), - table(table), columns(std::move(columns)), expressions(move(expressions)), bound_defaults(move(bound_defaults)), - return_chunk(return_chunk) { + : PhysicalOperator(PhysicalOperatorType::UPDATE, std::move(types), estimated_cardinality), tableref(tableref), + table(table), columns(std::move(columns)), expressions(std::move(expressions)), + bound_defaults(std::move(bound_defaults)), return_chunk(return_chunk) { } //===--------------------------------------------------------------------===// @@ -93561,7 +98761,9 @@ SinkResultType PhysicalUpdate::Sink(ExecutionContext &context, GlobalSinkState & // update data in the base table // the row ids are given to us as the last column of the child chunk auto &row_ids = chunk.data[chunk.ColumnCount() - 1]; + update_chunk.Reset(); update_chunk.SetCardinality(chunk); + for (idx_t i = 0; i < expressions.size(); i++) { if (expressions[i]->type == ExpressionType::VALUE_DEFAULT) { // default expression, set to the default value of the column @@ -93732,8 +98934,8 @@ class ProjectionState : public OperatorState { PhysicalProjection::PhysicalProjection(vector types, vector> select_list, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::PROJECTION, move(types), estimated_cardinality), - select_list(move(select_list)) { + : PhysicalOperator(PhysicalOperatorType::PROJECTION, std::move(types), estimated_cardinality), + select_list(std::move(select_list)) { } OperatorResultType PhysicalProjection::Execute(ExecutionContext &context, DataChunk &input, DataChunk &chunk, @@ -93777,7 +98979,7 @@ class PhysicalTableInOutFunction : public PhysicalOperator { public: PhysicalTableInOutFunction(vector types, TableFunction function_p, unique_ptr bind_data_p, vector column_ids_p, - idx_t estimated_cardinality); + idx_t estimated_cardinality, vector projected_input); public: unique_ptr GetOperatorState(ExecutionContext &context) const override; @@ -93800,8 +99002,10 @@ class PhysicalTableInOutFunction : public PhysicalOperator { TableFunction function; //! Bind data of the function unique_ptr bind_data; - + //! The set of column ids to fetch vector column_ids; + //! The set of input columns to project out + vector projected_input; }; } // namespace duckdb @@ -93811,10 +99015,13 @@ namespace duckdb { class TableInOutLocalState : public OperatorState { public: - TableInOutLocalState() { + TableInOutLocalState() : row_index(0), new_row(true) { } unique_ptr local_state; + idx_t row_index; + bool new_row; + DataChunk input_chunk; }; class TableInOutGlobalState : public GlobalOperatorState { @@ -93827,9 +99034,11 @@ class TableInOutGlobalState : public GlobalOperatorState { PhysicalTableInOutFunction::PhysicalTableInOutFunction(vector types, TableFunction function_p, unique_ptr bind_data_p, - vector column_ids_p, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::INOUT_FUNCTION, move(types), estimated_cardinality), - function(move(function_p)), bind_data(move(bind_data_p)), column_ids(move(column_ids_p)) { + vector column_ids_p, idx_t estimated_cardinality, + vector project_input_p) + : PhysicalOperator(PhysicalOperatorType::INOUT_FUNCTION, std::move(types), estimated_cardinality), + function(std::move(function_p)), bind_data(std::move(bind_data_p)), column_ids(std::move(column_ids_p)), + projected_input(std::move(project_input_p)) { } unique_ptr PhysicalTableInOutFunction::GetOperatorState(ExecutionContext &context) const { @@ -93839,7 +99048,10 @@ unique_ptr PhysicalTableInOutFunction::GetOperatorState(Execution TableFunctionInitInput input(bind_data.get(), column_ids, vector(), nullptr); result->local_state = function.init_local(context, input, gstate.global_state.get()); } - return move(result); + if (!projected_input.empty()) { + result->input_chunk.Initialize(context.client, children[0]->types); + } + return std::move(result); } unique_ptr PhysicalTableInOutFunction::GetGlobalOperatorState(ClientContext &context) const { @@ -93848,7 +99060,7 @@ unique_ptr PhysicalTableInOutFunction::GetGlobalOperatorSta TableFunctionInitInput input(bind_data.get(), column_ids, vector(), nullptr); result->global_state = function.init_global(context, input); } - return move(result); + return std::move(result); } OperatorResultType PhysicalTableInOutFunction::Execute(ExecutionContext &context, DataChunk &input, DataChunk &chunk, @@ -93856,7 +99068,46 @@ OperatorResultType PhysicalTableInOutFunction::Execute(ExecutionContext &context auto &gstate = (TableInOutGlobalState &)gstate_p; auto &state = (TableInOutLocalState &)state_p; TableFunctionInput data(bind_data.get(), state.local_state.get(), gstate.global_state.get()); - return function.in_out_function(context, data, input, chunk); + if (projected_input.empty()) { + // straightforward case - no need to project input + return function.in_out_function(context, data, input, chunk); + } + // when project_input is set we execute the input function row-by-row + if (state.new_row) { + if (state.row_index >= input.size()) { + // finished processing this chunk + state.new_row = true; + state.row_index = 0; + return OperatorResultType::NEED_MORE_INPUT; + } + // we are processing a new row: fetch the data for the current row + D_ASSERT(input.ColumnCount() == state.input_chunk.ColumnCount()); + // set up the input data to the table in-out function + for (idx_t col_idx = 0; col_idx < input.ColumnCount(); col_idx++) { + ConstantVector::Reference(state.input_chunk.data[col_idx], input.data[col_idx], state.row_index, 1); + } + state.input_chunk.SetCardinality(1); + state.row_index++; + state.new_row = false; + } + // set up the output data in "chunk" + D_ASSERT(chunk.ColumnCount() > projected_input.size()); + D_ASSERT(state.row_index > 0); + idx_t base_idx = chunk.ColumnCount() - projected_input.size(); + for (idx_t project_idx = 0; project_idx < projected_input.size(); project_idx++) { + auto source_idx = projected_input[project_idx]; + auto target_idx = base_idx + project_idx; + ConstantVector::Reference(chunk.data[target_idx], input.data[source_idx], state.row_index - 1, 1); + } + auto result = function.in_out_function(context, data, state.input_chunk, chunk); + if (result == OperatorResultType::FINISHED) { + return result; + } + if (result == OperatorResultType::NEED_MORE_INPUT) { + // we finished processing this row: move to the next row + state.new_row = true; + } + return OperatorResultType::HAVE_MORE_OUTPUT; } OperatorFinalizeResultType PhysicalTableInOutFunction::FinalExecute(ExecutionContext &context, DataChunk &chunk, @@ -93864,6 +99115,9 @@ OperatorFinalizeResultType PhysicalTableInOutFunction::FinalExecute(ExecutionCon OperatorState &state_p) const { auto &gstate = (TableInOutGlobalState &)gstate_p; auto &state = (TableInOutLocalState &)state_p; + if (!projected_input.empty()) { + throw InternalException("FinalExecute not supported for project_input"); + } TableFunctionInput data(bind_data.get(), state.local_state.get(), gstate.global_state.get()); return function.in_out_function_final(context, data, chunk); } @@ -93885,13 +99139,14 @@ OperatorFinalizeResultType PhysicalTableInOutFunction::FinalExecute(ExecutionCon namespace duckdb { -//! PhysicalWindow implements window functions +//! PhysicalUnnest implements the physical UNNEST operation class PhysicalUnnest : public PhysicalOperator { public: PhysicalUnnest(vector types, vector> select_list, idx_t estimated_cardinality, PhysicalOperatorType type = PhysicalOperatorType::UNNEST); //! The projection list of the UNNEST + //! E.g. SELECT 1, UNNEST([1]), UNNEST([2, 3]); has two UNNESTs in its select_list vector> select_list; public: @@ -93906,6 +99161,9 @@ class PhysicalUnnest : public PhysicalOperator { public: static unique_ptr GetState(ExecutionContext &context, const vector> &select_list); + //! Executes the UNNEST operator internally and emits a chunk of unnested data. If include_input is set, then + //! the resulting chunk also contains vectors for all non-UNNEST columns in the projection. If include_input is + //! not set, then the UNNEST behaves as a table function and only emits the unnested data. static OperatorResultType ExecuteInternal(ExecutionContext &context, DataChunk &input, DataChunk &chunk, OperatorState &state, const vector> &select_list, bool include_input = true); @@ -93925,7 +99183,11 @@ namespace duckdb { class UnnestOperatorState : public OperatorState { public: UnnestOperatorState(ClientContext &context, const vector> &select_list) - : parent_position(0), list_position(0), list_length(-1), first_fetch(true), executor(context) { + : current_row(0), list_position(0), longest_list_length(DConstants::INVALID_INDEX), first_fetch(true), + executor(context) { + + // for each UNNEST in the select_list, we add the child expression to the expression executor + // and set the return type in the list_data chunk, which will contain the evaluated expression results vector list_data_types; for (auto &exp : select_list) { D_ASSERT(exp->type == ExpressionType::BOUND_UNNEST); @@ -93933,6 +99195,7 @@ class UnnestOperatorState : public OperatorState { list_data_types.push_back(bue->child->return_type); executor.AddExpression(*bue->child.get()); } + auto &allocator = Allocator::Get(context); list_data.Initialize(allocator, list_data_types); @@ -93940,25 +99203,59 @@ class UnnestOperatorState : public OperatorState { list_child_data.resize(list_data.ColumnCount()); } - idx_t parent_position; + idx_t current_row; idx_t list_position; - int64_t list_length; + idx_t longest_list_length; bool first_fetch; ExpressionExecutor executor; DataChunk list_data; vector list_vector_data; vector list_child_data; + +public: + //! Reset the fields of the unnest operator state + void Reset(); + //! Set the longest list's length for the current row + void SetLongestListLength(); }; -// this implements a sorted window functions variant +void UnnestOperatorState::Reset() { + current_row = 0; + list_position = 0; + longest_list_length = DConstants::INVALID_INDEX; + first_fetch = true; +} + +void UnnestOperatorState::SetLongestListLength() { + + longest_list_length = 0; + for (idx_t col_idx = 0; col_idx < list_data.ColumnCount(); col_idx++) { + + auto &vector_data = list_vector_data[col_idx]; + auto current_idx = vector_data.sel->get_index(current_row); + + if (vector_data.validity.RowIsValid(current_idx)) { + + // check if this list is longer + auto list_data = (list_entry_t *)vector_data.data; + auto list_entry = list_data[current_idx]; + if (list_entry.length > longest_list_length) { + longest_list_length = list_entry.length; + } + } + } +} + PhysicalUnnest::PhysicalUnnest(vector types, vector> select_list, idx_t estimated_cardinality, PhysicalOperatorType type) - : PhysicalOperator(type, move(types), estimated_cardinality), select_list(std::move(select_list)) { + : PhysicalOperator(type, std::move(types), estimated_cardinality), select_list(std::move(select_list)) { D_ASSERT(!this->select_list.empty()); } static void UnnestNull(idx_t start, idx_t end, Vector &result) { + + D_ASSERT(result.GetVectorType() == VectorType::FLAT_VECTOR); auto &validity = FlatVector::Validity(result); for (idx_t i = start; i < end; i++) { validity.SetInvalid(i); @@ -93972,14 +99269,17 @@ static void UnnestNull(idx_t start, idx_t end, Vector &result) { } template -static void TemplatedUnnest(UnifiedVectorFormat &vdata, idx_t start, idx_t end, Vector &result) { - auto source_data = (T *)vdata.data; - auto &source_mask = vdata.validity; +static void TemplatedUnnest(UnifiedVectorFormat &vector_data, idx_t start, idx_t end, Vector &result) { + + auto source_data = (T *)vector_data.data; + auto &source_mask = vector_data.validity; + + D_ASSERT(result.GetVectorType() == VectorType::FLAT_VECTOR); auto result_data = FlatVector::GetData(result); auto &result_mask = FlatVector::Validity(result); for (idx_t i = start; i < end; i++) { - auto source_idx = vdata.sel->get_index(i); + auto source_idx = vector_data.sel->get_index(i); auto target_idx = i - start; if (source_mask.RowIsValid(source_idx)) { result_data[target_idx] = source_data[source_idx]; @@ -93990,81 +99290,129 @@ static void TemplatedUnnest(UnifiedVectorFormat &vdata, idx_t start, idx_t end, } } -static void UnnestValidity(UnifiedVectorFormat &vdata, idx_t start, idx_t end, Vector &result) { - auto &source_mask = vdata.validity; +static void UnnestValidity(UnifiedVectorFormat &vector_data, idx_t start, idx_t end, Vector &result) { + + auto &source_mask = vector_data.validity; + D_ASSERT(result.GetVectorType() == VectorType::FLAT_VECTOR); auto &result_mask = FlatVector::Validity(result); for (idx_t i = start; i < end; i++) { - auto source_idx = vdata.sel->get_index(i); + auto source_idx = vector_data.sel->get_index(i); auto target_idx = i - start; result_mask.Set(target_idx, source_mask.RowIsValid(source_idx)); } } -static void UnnestVector(UnifiedVectorFormat &vdata, Vector &source, idx_t list_size, idx_t start, idx_t end, - Vector &result) { +static void UnnestVector(UnifiedVectorFormat &child_vector_data, Vector &child_vector, idx_t list_size, idx_t start, + idx_t end, Vector &result) { + + D_ASSERT(child_vector.GetType() == result.GetType()); switch (result.GetType().InternalType()) { case PhysicalType::BOOL: case PhysicalType::INT8: - TemplatedUnnest(vdata, start, end, result); + TemplatedUnnest(child_vector_data, start, end, result); break; case PhysicalType::INT16: - TemplatedUnnest(vdata, start, end, result); + TemplatedUnnest(child_vector_data, start, end, result); break; case PhysicalType::INT32: - TemplatedUnnest(vdata, start, end, result); + TemplatedUnnest(child_vector_data, start, end, result); break; case PhysicalType::INT64: - TemplatedUnnest(vdata, start, end, result); + TemplatedUnnest(child_vector_data, start, end, result); break; case PhysicalType::INT128: - TemplatedUnnest(vdata, start, end, result); + TemplatedUnnest(child_vector_data, start, end, result); break; case PhysicalType::UINT8: - TemplatedUnnest(vdata, start, end, result); + TemplatedUnnest(child_vector_data, start, end, result); break; case PhysicalType::UINT16: - TemplatedUnnest(vdata, start, end, result); + TemplatedUnnest(child_vector_data, start, end, result); break; case PhysicalType::UINT32: - TemplatedUnnest(vdata, start, end, result); + TemplatedUnnest(child_vector_data, start, end, result); break; case PhysicalType::UINT64: - TemplatedUnnest(vdata, start, end, result); + TemplatedUnnest(child_vector_data, start, end, result); break; case PhysicalType::FLOAT: - TemplatedUnnest(vdata, start, end, result); + TemplatedUnnest(child_vector_data, start, end, result); break; case PhysicalType::DOUBLE: - TemplatedUnnest(vdata, start, end, result); + TemplatedUnnest(child_vector_data, start, end, result); break; case PhysicalType::INTERVAL: - TemplatedUnnest(vdata, start, end, result); + TemplatedUnnest(child_vector_data, start, end, result); break; case PhysicalType::VARCHAR: - TemplatedUnnest(vdata, start, end, result); + TemplatedUnnest(child_vector_data, start, end, result); break; case PhysicalType::LIST: { + // the child vector of result now references the child vector source + // FIXME: only reference relevant children (start - end) instead of all auto &target = ListVector::GetEntry(result); - target.Reference(ListVector::GetEntry(source)); - ListVector::SetListSize(result, ListVector::GetListSize(source)); - TemplatedUnnest(vdata, start, end, result); + target.Reference(ListVector::GetEntry(child_vector)); + ListVector::SetListSize(result, ListVector::GetListSize(child_vector)); + // unnest + TemplatedUnnest(child_vector_data, start, end, result); break; } case PhysicalType::STRUCT: { - auto &source_entries = StructVector::GetEntries(source); - auto &target_entries = StructVector::GetEntries(result); - UnnestValidity(vdata, start, end, result); - for (idx_t i = 0; i < source_entries.size(); i++) { - UnifiedVectorFormat sdata; - source_entries[i]->ToUnifiedFormat(list_size, sdata); - UnnestVector(sdata, *source_entries[i], list_size, start, end, *target_entries[i]); + auto &child_vector_entries = StructVector::GetEntries(child_vector); + auto &result_entries = StructVector::GetEntries(result); + + // set the validity mask for the 'outer' struct vector before unnesting its children + UnnestValidity(child_vector_data, start, end, result); + + for (idx_t i = 0; i < child_vector_entries.size(); i++) { + UnifiedVectorFormat child_vector_entries_data; + child_vector_entries[i]->ToUnifiedFormat(list_size, child_vector_entries_data); + UnnestVector(child_vector_entries_data, *child_vector_entries[i], list_size, start, end, + *result_entries[i]); } break; } default: - throw InternalException("Unimplemented type for UNNEST"); + throw InternalException("Unimplemented type for UNNEST."); + } +} + +static void PrepareInput(UnnestOperatorState &state, DataChunk &input, + const vector> &select_list) { + + state.list_data.Reset(); + // execute the expressions inside each UNNEST in the select_list to get the list data + // execution results (lists) are kept in state.list_data chunk + state.executor.Execute(input, state.list_data); + + // verify incoming lists + state.list_data.Verify(); + D_ASSERT(input.size() == state.list_data.size()); + D_ASSERT(state.list_data.ColumnCount() == select_list.size()); + D_ASSERT(state.list_vector_data.size() == state.list_data.ColumnCount()); + D_ASSERT(state.list_child_data.size() == state.list_data.ColumnCount()); + + // get the UnifiedVectorFormat of each list_data vector (LIST vectors for the different UNNESTs) + // both for the vector itself and its child vector + for (idx_t col_idx = 0; col_idx < state.list_data.ColumnCount(); col_idx++) { + + auto &list_vector = state.list_data.data[col_idx]; + list_vector.ToUnifiedFormat(state.list_data.size(), state.list_vector_data[col_idx]); + + if (list_vector.GetType() == LogicalType::SQLNULL) { + // UNNEST(NULL): SQLNULL vectors don't have child vectors, but we need to point to the child vector of + // each vector, so we just get the UnifiedVectorFormat of the vector itself + auto &child_vector = list_vector; + child_vector.ToUnifiedFormat(0, state.list_child_data[col_idx]); + } else { + auto list_size = ListVector::GetListSize(list_vector); + auto &child_vector = ListVector::GetEntry(list_vector); + child_vector.ToUnifiedFormat(list_size, state.list_child_data[col_idx]); + } } + + state.first_fetch = false; } unique_ptr PhysicalUnnest::GetOperatorState(ExecutionContext &context) const { @@ -94080,137 +99428,107 @@ OperatorResultType PhysicalUnnest::ExecuteInternal(ExecutionContext &context, Da OperatorState &state_p, const vector> &select_list, bool include_input) { + auto &state = (UnnestOperatorState &)state_p; + do { + // prepare the input data by executing any expressions and getting the + // UnifiedVectorFormat of each LIST vector (list_vector_data) and its child vector (list_child_data) if (state.first_fetch) { - // get the list data to unnest - state.list_data.Reset(); - state.executor.Execute(input, state.list_data); - - // paranoia aplenty - state.list_data.Verify(); - D_ASSERT(input.size() == state.list_data.size()); - D_ASSERT(state.list_data.ColumnCount() == select_list.size()); - D_ASSERT(state.list_vector_data.size() == state.list_data.ColumnCount()); - D_ASSERT(state.list_child_data.size() == state.list_data.ColumnCount()); - - // initialize UnifiedVectorFormat object so the nullmask can accessed - for (idx_t col_idx = 0; col_idx < state.list_data.ColumnCount(); col_idx++) { - auto &list_vector = state.list_data.data[col_idx]; - list_vector.ToUnifiedFormat(state.list_data.size(), state.list_vector_data[col_idx]); - - if (list_vector.GetType() == LogicalType::SQLNULL) { - // UNNEST(NULL) - auto &child_vector = list_vector; - child_vector.ToUnifiedFormat(0, state.list_child_data[col_idx]); - } else { - auto list_size = ListVector::GetListSize(list_vector); - auto &child_vector = ListVector::GetEntry(list_vector); - child_vector.ToUnifiedFormat(list_size, state.list_child_data[col_idx]); - } - } - state.first_fetch = false; + PrepareInput(state, input, select_list); } - if (state.parent_position >= input.size()) { - // finished with this input chunk - state.parent_position = 0; - state.list_position = 0; - state.list_length = -1; - state.first_fetch = true; + + // finished with all rows of this input chunk, reset + if (state.current_row >= input.size()) { + state.Reset(); return OperatorResultType::NEED_MORE_INPUT; } - // need to figure out how many times we need to repeat for current row - if (state.list_length < 0) { - for (idx_t col_idx = 0; col_idx < state.list_data.ColumnCount(); col_idx++) { - auto &vdata = state.list_vector_data[col_idx]; - auto current_idx = vdata.sel->get_index(state.parent_position); - - int64_t list_length; - // deal with NULL values - if (!vdata.validity.RowIsValid(current_idx)) { - list_length = 0; - } else { - auto list_data = (list_entry_t *)vdata.data; - auto list_entry = list_data[current_idx]; - list_length = (int64_t)list_entry.length; - } - - if (list_length > state.list_length) { - state.list_length = list_length; - } - } + // each UNNEST in the select_list contains a list (or NULL) for this row, find longest list + // because this length determines how many times we need to repeat for the current row + if (state.longest_list_length == DConstants::INVALID_INDEX) { + state.SetLongestListLength(); } + D_ASSERT(state.longest_list_length != DConstants::INVALID_INDEX); - D_ASSERT(state.list_length >= 0); - - auto this_chunk_len = MinValue(STANDARD_VECTOR_SIZE, state.list_length - state.list_position); - - // first cols are from child, last n cols from unnest + // we emit chunks of either STANDARD_VECTOR_SIZE or smaller + auto this_chunk_len = MinValue(STANDARD_VECTOR_SIZE, state.longest_list_length - state.list_position); chunk.SetCardinality(this_chunk_len); - idx_t output_offset = 0; + // if we include other projection input columns, e.g. SELECT 1, UNNEST([1, 2]);, then + // we need to add them as a constant vector to the resulting chunk + // FIXME: emit multiple unnested rows. Currently, we never emit a chunk containing multiple unnested input rows, + // so setting a constant vector for the value at state.current_row is fine + idx_t col_offset = 0; if (include_input) { for (idx_t col_idx = 0; col_idx < input.ColumnCount(); col_idx++) { - ConstantVector::Reference(chunk.data[col_idx], input.data[col_idx], state.parent_position, - input.size()); + ConstantVector::Reference(chunk.data[col_idx], input.data[col_idx], state.current_row, input.size()); } - output_offset = input.ColumnCount(); + col_offset = input.ColumnCount(); } + // unnest the lists for (idx_t col_idx = 0; col_idx < state.list_data.ColumnCount(); col_idx++) { - auto &result_vector = chunk.data[col_idx + output_offset]; + + auto &result_vector = chunk.data[col_idx + col_offset]; if (state.list_data.data[col_idx].GetType() == LogicalType::SQLNULL) { // UNNEST(NULL) chunk.SetCardinality(0); + break; + } else { - auto &vdata = state.list_vector_data[col_idx]; - auto &child_data = state.list_child_data[col_idx]; - auto current_idx = vdata.sel->get_index(state.parent_position); - auto list_data = (list_entry_t *)vdata.data; - auto list_entry = list_data[current_idx]; + auto &vector_data = state.list_vector_data[col_idx]; + auto current_idx = vector_data.sel->get_index(state.current_row); + + if (!vector_data.validity.RowIsValid(current_idx)) { + UnnestNull(0, this_chunk_len, result_vector); - idx_t list_count; - if (state.list_position >= list_entry.length) { - list_count = 0; } else { - list_count = MinValue(this_chunk_len, list_entry.length - state.list_position); - } - if (list_entry.length > state.list_position) { - if (!vdata.validity.RowIsValid(current_idx)) { - UnnestNull(0, list_count, result_vector); - } else { + auto list_data = (list_entry_t *)vector_data.data; + auto list_entry = list_data[current_idx]; + + idx_t list_count = 0; + if (state.list_position < list_entry.length) { + // there are still list_count elements to unnest + list_count = MinValue(this_chunk_len, list_entry.length - state.list_position); + auto &list_vector = state.list_data.data[col_idx]; auto &child_vector = ListVector::GetEntry(list_vector); auto list_size = ListVector::GetListSize(list_vector); + auto &child_vector_data = state.list_child_data[col_idx]; auto base_offset = list_entry.offset + state.list_position; - UnnestVector(child_data, child_vector, list_size, base_offset, base_offset + list_count, + UnnestVector(child_vector_data, child_vector, list_size, base_offset, base_offset + list_count, result_vector); } - } - UnnestNull(list_count, this_chunk_len, result_vector); + // fill the rest with NULLs + if (list_count != this_chunk_len) { + UnnestNull(list_count, this_chunk_len, result_vector); + } + } } } + chunk.Verify(); + state.list_position += this_chunk_len; - if ((int64_t)state.list_position == state.list_length) { - state.parent_position++; - state.list_length = -1; + if (state.list_position == state.longest_list_length) { + state.current_row++; + state.longest_list_length = DConstants::INVALID_INDEX; state.list_position = 0; } - chunk.Verify(); + // we only emit one unnested row (that contains data) at a time } while (chunk.size() == 0); return OperatorResultType::HAVE_MORE_OUTPUT; } OperatorResultType PhysicalUnnest::Execute(ExecutionContext &context, DataChunk &input, DataChunk &chunk, - GlobalOperatorState &gstate, OperatorState &state) const { + GlobalOperatorState &, OperatorState &state) const { return ExecuteInternal(context, input, chunk, state, select_list); } @@ -94302,7 +99620,7 @@ namespace duckdb { class PhysicalDummyScan : public PhysicalOperator { public: explicit PhysicalDummyScan(vector types, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::DUMMY_SCAN, move(types), estimated_cardinality) { + : PhysicalOperator(PhysicalOperatorType::DUMMY_SCAN, std::move(types), estimated_cardinality) { } public: @@ -94356,7 +99674,7 @@ namespace duckdb { class PhysicalEmptyResult : public PhysicalOperator { public: explicit PhysicalEmptyResult(vector types, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::EMPTY_RESULT, move(types), estimated_cardinality) { + : PhysicalOperator(PhysicalOperatorType::EMPTY_RESULT, std::move(types), estimated_cardinality) { } public: @@ -94394,8 +99712,8 @@ class PhysicalExpressionScan : public PhysicalOperator { public: PhysicalExpressionScan(vector types, vector>> expressions, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::EXPRESSION_SCAN, move(types), estimated_cardinality), - expressions(move(expressions)) { + : PhysicalOperator(PhysicalOperatorType::EXPRESSION_SCAN, std::move(types), estimated_cardinality), + expressions(std::move(expressions)) { } //! The set of expressions to scan @@ -94487,6 +99805,193 @@ bool PhysicalExpressionScan::IsFoldable() const { +#include + +namespace duckdb { + +PhysicalPositionalScan::PhysicalPositionalScan(vector types, unique_ptr left, + unique_ptr right) + : PhysicalOperator(PhysicalOperatorType::POSITIONAL_SCAN, std::move(types), + MinValue(left->estimated_cardinality, right->estimated_cardinality)) { + + // Manage the children ourselves + D_ASSERT(left->type == PhysicalOperatorType::TABLE_SCAN); + D_ASSERT(right->type == PhysicalOperatorType::TABLE_SCAN); + child_tables.emplace_back(std::move(left)); + child_tables.emplace_back(std::move(right)); +} + +class PositionalScanGlobalSourceState : public GlobalSourceState { +public: + PositionalScanGlobalSourceState(ClientContext &context, const PhysicalPositionalScan &op) { + for (const auto &table : op.child_tables) { + global_states.emplace_back(table->GetGlobalSourceState(context)); + } + } + + vector> global_states; + + idx_t MaxThreads() override { + return 1; + } +}; + +class PositionalTableScanner { +public: + PositionalTableScanner(ExecutionContext &context, PhysicalOperator &table_p, GlobalSourceState &gstate_p) + : table(table_p), global_state(gstate_p), source_offset(0), exhausted(false) { + local_state = table.GetLocalSourceState(context, gstate_p); + source.Initialize(Allocator::Get(context.client), table.types); + } + + idx_t Refill(ExecutionContext &context) { + if (source_offset >= source.size()) { + if (!exhausted) { + source.Reset(); + table.GetData(context, source, global_state, *local_state); + } + source_offset = 0; + } + + const auto available = source.size() - source_offset; + if (!available) { + if (!exhausted) { + source.Reset(); + for (idx_t i = 0; i < source.ColumnCount(); ++i) { + auto &vec = source.data[i]; + vec.SetVectorType(VectorType::CONSTANT_VECTOR); + ConstantVector::SetNull(vec, true); + } + exhausted = true; + } + } + + return available; + } + + idx_t CopyData(ExecutionContext &context, DataChunk &output, const idx_t count, const idx_t col_offset) { + if (!source_offset && (source.size() >= count || exhausted)) { + // Fast track: aligned and has enough data + for (idx_t i = 0; i < source.ColumnCount(); ++i) { + output.data[col_offset + i].Reference(source.data[i]); + } + source_offset += count; + } else { + // Copy data + for (idx_t target_offset = 0; target_offset < count;) { + const auto needed = count - target_offset; + const auto available = exhausted ? needed : (source.size() - source_offset); + const auto copy_size = MinValue(needed, available); + const auto source_count = source_offset + copy_size; + for (idx_t i = 0; i < source.ColumnCount(); ++i) { + VectorOperations::Copy(source.data[i], output.data[col_offset + i], source_count, source_offset, + target_offset); + } + target_offset += copy_size; + source_offset += copy_size; + Refill(context); + } + } + + return source.ColumnCount(); + } + + double GetProgress(ClientContext &context) { + return table.GetProgress(context, global_state); + } + + PhysicalOperator &table; + GlobalSourceState &global_state; + unique_ptr local_state; + DataChunk source; + idx_t source_offset; + bool exhausted; +}; + +class PositionalScanLocalSourceState : public LocalSourceState { +public: + PositionalScanLocalSourceState(ExecutionContext &context, PositionalScanGlobalSourceState &gstate, + const PhysicalPositionalScan &op) { + for (size_t i = 0; i < op.child_tables.size(); ++i) { + auto &child = *op.child_tables[i]; + auto &global_state = *gstate.global_states[i]; + scanners.emplace_back(make_unique(context, child, global_state)); + } + } + + vector> scanners; +}; + +unique_ptr PhysicalPositionalScan::GetLocalSourceState(ExecutionContext &context, + GlobalSourceState &gstate) const { + return make_unique(context, (PositionalScanGlobalSourceState &)gstate, *this); +} + +unique_ptr PhysicalPositionalScan::GetGlobalSourceState(ClientContext &context) const { + return make_unique(context, *this); +} + +void PhysicalPositionalScan::GetData(ExecutionContext &context, DataChunk &output, GlobalSourceState &gstate_p, + LocalSourceState &lstate_p) const { + auto &lstate = (PositionalScanLocalSourceState &)lstate_p; + + // Find the longest source block + idx_t count = 0; + for (auto &scanner : lstate.scanners) { + count = MaxValue(count, scanner->Refill(context)); + } + + // All done? + if (!count) { + return; + } + + // Copy or reference the source columns + idx_t col_offset = 0; + for (auto &scanner : lstate.scanners) { + col_offset += scanner->CopyData(context, output, count, col_offset); + } + + output.SetCardinality(count); +} + +double PhysicalPositionalScan::GetProgress(ClientContext &context, GlobalSourceState &gstate_p) const { + auto &gstate = (PositionalScanGlobalSourceState &)gstate_p; + + double result = child_tables[0]->GetProgress(context, *gstate.global_states[0]); + for (size_t t = 1; t < child_tables.size(); ++t) { + result = MinValue(result, child_tables[t]->GetProgress(context, *gstate.global_states[t])); + } + + return result; +} + +bool PhysicalPositionalScan::Equals(const PhysicalOperator &other_p) const { + if (type != other_p.type) { + return false; + } + + auto &other = (PhysicalPositionalScan &)other_p; + if (child_tables.size() != other.child_tables.size()) { + return false; + } + for (size_t i = 0; i < child_tables.size(); ++i) { + if (!child_tables[i]->Equals(*other.child_tables[i])) { + return false; + } + } + + return true; +} + +} // namespace duckdb + + + + + + + #include namespace duckdb { @@ -94495,9 +100000,9 @@ PhysicalTableScan::PhysicalTableScan(vector types, TableFunction fu unique_ptr bind_data_p, vector column_ids_p, vector names_p, unique_ptr table_filters_p, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::TABLE_SCAN, move(types), estimated_cardinality), - function(move(function_p)), bind_data(move(bind_data_p)), column_ids(move(column_ids_p)), names(move(names_p)), - table_filters(move(table_filters_p)) { + : PhysicalOperator(PhysicalOperatorType::TABLE_SCAN, std::move(types), estimated_cardinality), + function(std::move(function_p)), bind_data(std::move(bind_data_p)), column_ids(std::move(column_ids_p)), + names(std::move(names_p)), table_filters(std::move(table_filters_p)) { } PhysicalTableScan::PhysicalTableScan(vector types, TableFunction function_p, @@ -94505,10 +100010,10 @@ PhysicalTableScan::PhysicalTableScan(vector types, TableFunction fu vector column_ids_p, vector projection_ids_p, vector names_p, unique_ptr table_filters_p, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::TABLE_SCAN, move(types), estimated_cardinality), - function(move(function_p)), bind_data(move(bind_data_p)), returned_types(move(returned_types_p)), - column_ids(move(column_ids_p)), projection_ids(move(projection_ids_p)), names(move(names_p)), - table_filters(move(table_filters_p)) { + : PhysicalOperator(PhysicalOperatorType::TABLE_SCAN, std::move(types), estimated_cardinality), + function(std::move(function_p)), bind_data(std::move(bind_data_p)), returned_types(std::move(returned_types_p)), + column_ids(std::move(column_ids_p)), projection_ids(std::move(projection_ids_p)), names(std::move(names_p)), + table_filters(std::move(table_filters_p)) { } class TableScanGlobalSourceState : public GlobalSourceState { @@ -94617,7 +100122,8 @@ string PhysicalTableScan::ParamsToString() const { } } } - result += "\nEC=" + to_string(estimated_cardinality) + "\n"; + result += "\n[INFOSEPARATOR]\n"; + result += StringUtil::Format("EC: %llu", estimated_props->GetCardinality()); return result; } @@ -94659,7 +100165,7 @@ class PhysicalAlter : public PhysicalOperator { public: explicit PhysicalAlter(unique_ptr info, idx_t estimated_cardinality) : PhysicalOperator(PhysicalOperatorType::ALTER, {LogicalType::BOOLEAN}, estimated_cardinality), - info(move(info)) { + info(std::move(info)) { } unique_ptr info; @@ -94699,11 +100205,223 @@ void PhysicalAlter::GetData(ExecutionContext &context, DataChunk &chunk, GlobalS if (state.finished) { return; } - auto &catalog = Catalog::GetCatalog(context.client); + auto &catalog = Catalog::GetCatalog(context.client, info->catalog); catalog.Alter(context.client, info.get()); state.finished = true; } +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/execution/operator/schema/physical_attach.hpp +// +// +//===----------------------------------------------------------------------===// + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/parsed_data/attach_info.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + + +namespace duckdb { + +struct AttachInfo : public ParseInfo { + AttachInfo() { + } + + //! The alias of the attached database + string name; + //! The path to the attached database + string path; + //! Set of (key, value) options + unordered_map options; + +public: + unique_ptr Copy() const { + auto result = make_unique(); + result->name = name; + result->path = path; + result->options = options; + return result; + } +}; + +} // namespace duckdb + + +namespace duckdb { + +//! PhysicalLoad represents an extension LOAD operation +class PhysicalAttach : public PhysicalOperator { +public: + explicit PhysicalAttach(unique_ptr info, idx_t estimated_cardinality) + : PhysicalOperator(PhysicalOperatorType::ATTACH, {LogicalType::BOOLEAN}, estimated_cardinality), + info(std::move(info)) { + } + + unique_ptr info; + +public: + // Source interface + unique_ptr GetGlobalSourceState(ClientContext &context) const override; + void GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, + LocalSourceState &lstate) const override; +}; + +} // namespace duckdb + + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/storage/storage_extension.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { +class AttachedDatabase; +struct AttachInfo; +class Catalog; +class TransactionManager; + +//! The StorageExtensionInfo holds static information relevant to the storage extension +struct StorageExtensionInfo { + DUCKDB_API virtual ~StorageExtensionInfo() { + } +}; + +typedef unique_ptr (*attach_function_t)(StorageExtensionInfo *storage_info, AttachedDatabase &db, + const string &name, AttachInfo &info, AccessMode access_mode); +typedef unique_ptr (*create_transaction_manager_t)(StorageExtensionInfo *storage_info, + AttachedDatabase &db, Catalog &catalog); + +class StorageExtension { +public: + attach_function_t attach; + create_transaction_manager_t create_transaction_manager; + + //! Additional info passed to the various storage functions + shared_ptr storage_info; + + DUCKDB_API virtual ~StorageExtension() { + } +}; + +} // namespace duckdb + + + +namespace duckdb { + +//===--------------------------------------------------------------------===// +// Source +//===--------------------------------------------------------------------===// +class AttachSourceState : public GlobalSourceState { +public: + AttachSourceState() : finished(false) { + } + + bool finished; +}; + +unique_ptr PhysicalAttach::GetGlobalSourceState(ClientContext &context) const { + return make_unique(); +} + +void PhysicalAttach::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, + LocalSourceState &lstate) const { + auto &state = (AttachSourceState &)gstate; + if (state.finished) { + return; + } + // parse the options + auto &config = DBConfig::GetConfig(context.client); + AccessMode access_mode = config.options.access_mode; + string type; + string unrecognized_option; + for (auto &entry : info->options) { + if (entry.first == "readonly" || entry.first == "read_only") { + auto read_only = BooleanValue::Get(entry.second.DefaultCastAs(LogicalType::BOOLEAN)); + if (read_only) { + access_mode = AccessMode::READ_ONLY; + } else { + access_mode = AccessMode::READ_WRITE; + } + } else if (entry.first == "readwrite" || entry.first == "read_write") { + auto read_only = !BooleanValue::Get(entry.second.DefaultCastAs(LogicalType::BOOLEAN)); + if (read_only) { + access_mode = AccessMode::READ_ONLY; + } else { + access_mode = AccessMode::READ_WRITE; + } + } else if (entry.first == "type") { + type = StringValue::Get(entry.second.DefaultCastAs(LogicalType::VARCHAR)); + } else if (unrecognized_option.empty()) { + unrecognized_option = entry.first; + } + } + auto &db = DatabaseInstance::GetDatabase(context.client); + if (type.empty()) { + // try to extract type from path + type = db.ExtractDatabaseType(info->path); + } + if (!type.empty()) { + type = ExtensionHelper::ApplyExtensionAlias(type); + } + if (type.empty() && !unrecognized_option.empty()) { + throw BinderException("Unrecognized option for attach \"%s\"", unrecognized_option); + } + + // if we are loading a database type from an extension - check if that extension is loaded + if (!type.empty()) { + if (!db.ExtensionIsLoaded(type)) { + ExtensionHelper::LoadExternalExtension(context.client, type); + } + } + + // attach the database + auto &name = info->name; + const auto &path = info->path; + + if (name.empty()) { + name = AttachedDatabase::ExtractDatabaseName(path); + } + auto &db_manager = DatabaseManager::Get(context.client); + auto existing_db = db_manager.GetDatabaseFromPath(context.client, path); + if (existing_db) { + throw BinderException("Database \"%s\" is already attached with alias \"%s\"", path, existing_db->GetName()); + } + auto new_db = db.CreateAttachedDatabase(*info, type, access_mode); + new_db->Initialize(); + + db_manager.AddDatabase(context.client, std::move(new_db)); + state.finished = true; +} + } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB @@ -94725,7 +100443,7 @@ class PhysicalCreateFunction : public PhysicalOperator { public: explicit PhysicalCreateFunction(unique_ptr info, idx_t estimated_cardinality) : PhysicalOperator(PhysicalOperatorType::CREATE_MACRO, {LogicalType::BIGINT}, estimated_cardinality), - info(move(info)) { + info(std::move(info)) { } unique_ptr info; @@ -94766,7 +100484,8 @@ void PhysicalCreateFunction::GetData(ExecutionContext &context, DataChunk &chunk if (state.finished) { return; } - Catalog::GetCatalog(context.client).CreateFunction(context.client, info.get()); + auto &catalog = Catalog::GetCatalog(context.client, info->catalog); + catalog.CreateFunction(context.client, info.get()); state.finished = true; } @@ -94790,41 +100509,33 @@ void PhysicalCreateFunction::GetData(ExecutionContext &context, DataChunk &chunk #include namespace duckdb { +class DuckTableEntry; -//! Physically CREATE INDEX statement +//! Physical CREATE (UNIQUE) INDEX statement class PhysicalCreateIndex : public PhysicalOperator { public: - PhysicalCreateIndex(LogicalOperator &op, TableCatalogEntry &table, vector column_ids, - vector> expressions, unique_ptr info, - vector> unbound_expressions, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::CREATE_INDEX, op.types, estimated_cardinality), table(table), - expressions(move(expressions)), info(std::move(info)), unbound_expressions(move(unbound_expressions)) { - - // convert virtual column ids to storage column ids - for (auto &column_id : column_ids) { - storage_ids.push_back(table.columns.LogicalToPhysical(LogicalIndex(column_id)).index); - } - } + PhysicalCreateIndex(LogicalOperator &op, TableCatalogEntry &table, const vector &column_ids, + unique_ptr info, vector> unbound_expressions, + idx_t estimated_cardinality); //! The table to create the index for - TableCatalogEntry &table; + DuckTableEntry &table; //! The list of column IDs required for the index vector storage_ids; - //! Set of expressions to index by - vector> expressions; //! Info for index creation unique_ptr info; //! Unbound expressions to be used in the optimizer vector> unbound_expressions; public: - // Source interface + //! Source interface, NOP for this operator void GetData(ExecutionContext &context, DataChunk &chunk, GlobalSourceState &gstate, LocalSourceState &lstate) const override; public: - // Sink interface + //! Sink interface, thread-local sink states unique_ptr GetLocalSinkState(ExecutionContext &context) const override; + //! Sink interface, global sink state unique_ptr GetGlobalSinkState(ClientContext &context) const override; SinkResultType Sink(ExecutionContext &context, GlobalSinkState &gstate_p, LocalSinkState &lstate_p, @@ -94852,6 +100563,19 @@ class PhysicalCreateIndex : public PhysicalOperator { namespace duckdb { +PhysicalCreateIndex::PhysicalCreateIndex(LogicalOperator &op, TableCatalogEntry &table_p, + const vector &column_ids, unique_ptr info, + vector> unbound_expressions, + idx_t estimated_cardinality) + : PhysicalOperator(PhysicalOperatorType::CREATE_INDEX, op.types, estimated_cardinality), + table((DuckTableEntry &)table_p), info(std::move(info)), unbound_expressions(std::move(unbound_expressions)) { + D_ASSERT(table_p.IsDuckTable()); + // convert virtual column ids to storage column ids + for (auto &column_id : column_ids) { + storage_ids.push_back(table.GetColumns().LogicalToPhysical(LogicalIndex(column_id)).index); + } +} + //===--------------------------------------------------------------------===// // Sink //===--------------------------------------------------------------------===// @@ -94864,133 +100588,92 @@ class CreateIndexGlobalSinkState : public GlobalSinkState { class CreateIndexLocalSinkState : public LocalSinkState { public: - explicit CreateIndexLocalSinkState(const vector> &expressions) : executor(expressions) { - } + explicit CreateIndexLocalSinkState(ClientContext &context) : arena_allocator(Allocator::Get(context)) {}; - //! Local indexes build from chunks of the scanned data unique_ptr local_index; - + ArenaAllocator arena_allocator; + vector keys; DataChunk key_chunk; - unique_ptr global_sort_state; - LocalSortState local_sort_state; - - RowLayout payload_layout; - vector payload_types; - - ExpressionExecutor executor; + vector key_column_ids; }; unique_ptr PhysicalCreateIndex::GetGlobalSinkState(ClientContext &context) const { - auto state = make_unique(); // create the global index switch (info->index_type) { case IndexType::ART: { - state->global_index = make_unique(storage_ids, TableIOManager::Get(*table.storage), unbound_expressions, - info->constraint_type, *context.db); + auto &storage = table.GetStorage(); + state->global_index = make_unique(storage_ids, TableIOManager::Get(storage), unbound_expressions, + info->constraint_type, storage.db, true); break; } default: throw InternalException("Unimplemented index type"); } - - return (move(state)); + return (std::move(state)); } unique_ptr PhysicalCreateIndex::GetLocalSinkState(ExecutionContext &context) const { - auto &allocator = Allocator::Get(table.storage->db); - - auto state = make_unique(expressions); + auto state = make_unique(context.client); // create the local index switch (info->index_type) { case IndexType::ART: { - state->local_index = make_unique(storage_ids, TableIOManager::Get(*table.storage), unbound_expressions, - info->constraint_type, *context.client.db); + auto &storage = table.GetStorage(); + state->local_index = make_unique(storage_ids, TableIOManager::Get(storage), unbound_expressions, + info->constraint_type, storage.db, false); break; } default: throw InternalException("Unimplemented index type"); } + state->keys = vector(STANDARD_VECTOR_SIZE); + state->key_chunk.Initialize(Allocator::Get(context.client), state->local_index->logical_types); - state->key_chunk.Initialize(allocator, state->local_index->logical_types); - - // ordering of the entries of the index - vector orders; - for (idx_t i = 0; i < state->local_index->logical_types.size(); i++) { - auto col_expr = make_unique_base(state->local_index->logical_types[i], i); - orders.emplace_back(OrderType::ASCENDING, OrderByNullType::NULLS_FIRST, move(col_expr)); + for (idx_t i = 0; i < state->key_chunk.ColumnCount(); i++) { + state->key_column_ids.push_back(i); } - - // row layout of the global sort state - state->payload_types = state->local_index->logical_types; - state->payload_types.emplace_back(LogicalType::ROW_TYPE); - state->payload_layout.Initialize(state->payload_types); - - // initialize global and local sort state - auto &buffer_manager = BufferManager::GetBufferManager(table.storage->db); - state->global_sort_state = make_unique(buffer_manager, orders, state->payload_layout); - state->local_sort_state.Initialize(*state->global_sort_state, buffer_manager); - - return move(state); + return std::move(state); } SinkResultType PhysicalCreateIndex::Sink(ExecutionContext &context, GlobalSinkState &gstate_p, LocalSinkState &lstate_p, DataChunk &input) const { - // here, we sink all incoming data into the local_sink_state after executing the expression executor + D_ASSERT(input.ColumnCount() >= 2); auto &lstate = (CreateIndexLocalSinkState &)lstate_p; + auto &row_identifiers = input.data[input.ColumnCount() - 1]; - // resolve the expressions for this chunk - D_ASSERT(!lstate.executor.HasContext()); - lstate.key_chunk.Reset(); - lstate.executor.Execute(input, lstate.key_chunk); - - // create the payload chunk - DataChunk payload_chunk; - payload_chunk.InitializeEmpty(lstate.payload_types); - for (idx_t i = 0; i < lstate.local_index->logical_types.size(); i++) { - payload_chunk.data[i].Reference(lstate.key_chunk.data[i]); + // generate the keys for the given input + lstate.key_chunk.ReferenceColumns(input, lstate.key_column_ids); + lstate.arena_allocator.Reset(); + ART::GenerateKeys(lstate.arena_allocator, lstate.key_chunk, lstate.keys); + + auto &storage = table.GetStorage(); + auto art = make_unique(lstate.local_index->column_ids, lstate.local_index->table_io_manager, + lstate.local_index->unbound_expressions, lstate.local_index->constraint_type, + storage.db, false); + if (!art->ConstructFromSorted(lstate.key_chunk.size(), lstate.keys, row_identifiers)) { + throw ConstraintException("Data contains duplicates on indexed column(s)"); } - payload_chunk.data[lstate.payload_types.size() - 1].Reference(input.data[input.ColumnCount() - 1]); - payload_chunk.SetCardinality(input.size()); - - // sink the chunks into the local sort state - lstate.local_sort_state.SinkChunk(lstate.key_chunk, payload_chunk); + // merge into the local ART + if (!lstate.local_index->MergeIndexes(art.get())) { + throw ConstraintException("Data contains duplicates on indexed column(s)"); + } return SinkResultType::NEED_MORE_INPUT; } void PhysicalCreateIndex::Combine(ExecutionContext &context, GlobalSinkState &gstate_p, LocalSinkState &lstate_p) const { - // here, we take the sunk data chunks and sort them - // then, we scan the sorted data and build a local index from it - // finally, we merge the local index into the global index - auto &gstate = (CreateIndexGlobalSinkState &)gstate_p; auto &lstate = (CreateIndexLocalSinkState &)lstate_p; - auto &allocator = Allocator::Get(table.storage->db); - - // add local state to global state, which sorts the data - lstate.global_sort_state->AddLocalState(lstate.local_sort_state); - lstate.global_sort_state->PrepareMergePhase(); - - // scan the sorted row data and construct the index from it - { - IndexLock local_lock; - lstate.local_index->InitializeLock(local_lock); - if (!lstate.global_sort_state->sorted_blocks.empty()) { - PayloadScanner scanner(*lstate.global_sort_state->sorted_blocks[0]->payload_data, - *lstate.global_sort_state); - lstate.local_index->ConstructAndMerge(local_lock, scanner, allocator); - } - } - // merge the local index into the global index - gstate.global_index->MergeIndexes(lstate.local_index.get()); + if (!gstate.global_index->MergeIndexes(lstate.local_index.get())) { + throw ConstraintException("Data contains duplicates on indexed column(s)"); + } } SinkFinalizeType PhysicalCreateIndex::Finalize(Pipeline &pipeline, Event &event, ClientContext &context, @@ -94999,25 +100682,30 @@ SinkFinalizeType PhysicalCreateIndex::Finalize(Pipeline &pipeline, Event &event, // here, we just set the resulting global index as the newly created index of the table auto &state = (CreateIndexGlobalSinkState &)gstate_p; - - if (!table.storage->IsRoot()) { + auto &storage = table.GetStorage(); + if (!storage.IsRoot()) { throw TransactionException("Transaction conflict: cannot add an index to a table that has been altered!"); } + state.global_index->Verify(); + if (state.global_index->track_memory) { + state.global_index->buffer_manager.IncreaseUsedMemory(state.global_index->memory_size); + } + auto &schema = *table.schema; - auto index_entry = (IndexCatalogEntry *)schema.CreateIndex(context, info.get(), &table); + auto index_entry = (DuckIndexEntry *)schema.CreateIndex(context, info.get(), &table); if (!index_entry) { // index already exists, but error ignored because of IF NOT EXISTS return SinkFinalizeType::READY; } index_entry->index = state.global_index.get(); - index_entry->info = table.storage->info; + index_entry->info = storage.info; for (auto &parsed_expr : info->parsed_expressions) { index_entry->parsed_expressions.push_back(parsed_expr->Copy()); } - table.storage->info->indexes.AddIndex(move(state.global_index)); + storage.info->indexes.AddIndex(std::move(state.global_index)); return SinkFinalizeType::READY; } @@ -95051,7 +100739,7 @@ class PhysicalCreateSchema : public PhysicalOperator { public: explicit PhysicalCreateSchema(unique_ptr info, idx_t estimated_cardinality) : PhysicalOperator(PhysicalOperatorType::CREATE_SCHEMA, {LogicalType::BIGINT}, estimated_cardinality), - info(move(info)) { + info(std::move(info)) { } unique_ptr info; @@ -95090,7 +100778,11 @@ void PhysicalCreateSchema::GetData(ExecutionContext &context, DataChunk &chunk, if (state.finished) { return; } - Catalog::GetCatalog(context.client).CreateSchema(context.client, info.get()); + auto &catalog = Catalog::GetCatalog(context.client, info->catalog); + if (catalog.IsSystemCatalog()) { + throw BinderException("Cannot create schema in system catalog"); + } + catalog.CreateSchema(context.client, info.get()); state.finished = true; } @@ -95115,7 +100807,7 @@ class PhysicalCreateSequence : public PhysicalOperator { public: explicit PhysicalCreateSequence(unique_ptr info, idx_t estimated_cardinality) : PhysicalOperator(PhysicalOperatorType::CREATE_SEQUENCE, {LogicalType::BIGINT}, estimated_cardinality), - info(move(info)) { + info(std::move(info)) { } unique_ptr info; @@ -95154,7 +100846,8 @@ void PhysicalCreateSequence::GetData(ExecutionContext &context, DataChunk &chunk if (state.finished) { return; } - Catalog::GetCatalog(context.client).CreateSequence(context.client, info.get()); + auto &catalog = Catalog::GetCatalog(context.client, info->catalog); + catalog.CreateSequence(context.client, info.get()); state.finished = true; } @@ -95204,7 +100897,7 @@ namespace duckdb { PhysicalCreateTable::PhysicalCreateTable(LogicalOperator &op, SchemaCatalogEntry *schema, unique_ptr info, idx_t estimated_cardinality) : PhysicalOperator(PhysicalOperatorType::CREATE_TABLE, op.types, estimated_cardinality), schema(schema), - info(move(info)) { + info(std::move(info)) { } //===--------------------------------------------------------------------===// @@ -95228,8 +100921,8 @@ void PhysicalCreateTable::GetData(ExecutionContext &context, DataChunk &chunk, G if (state.finished) { return; } - auto &catalog = Catalog::GetCatalog(context.client); - catalog.CreateTable(context.client, schema, info.get()); + auto &catalog = *schema->catalog; + catalog.CreateTable(catalog.GetCatalogTransaction(context.client), schema, info.get()); state.finished = true; } @@ -95288,7 +100981,7 @@ namespace duckdb { PhysicalCreateType::PhysicalCreateType(unique_ptr info, idx_t estimated_cardinality) : PhysicalOperator(PhysicalOperatorType::CREATE_TYPE, {LogicalType::BIGINT}, estimated_cardinality), - info(move(info)) { + info(std::move(info)) { } //===--------------------------------------------------------------------===// @@ -95389,7 +101082,7 @@ void PhysicalCreateType::GetData(ExecutionContext &context, DataChunk &chunk, Gl info->type = LogicalType::ENUM(info->name, result, total_row_count); } - auto &catalog = Catalog::GetCatalog(context.client); + auto &catalog = Catalog::GetCatalog(context.client, info->catalog); catalog.CreateType(context.client, info.get()); state.finished = true; } @@ -95415,7 +101108,7 @@ class PhysicalCreateView : public PhysicalOperator { public: explicit PhysicalCreateView(unique_ptr info, idx_t estimated_cardinality) : PhysicalOperator(PhysicalOperatorType::CREATE_VIEW, {LogicalType::BIGINT}, estimated_cardinality), - info(move(info)) { + info(std::move(info)) { } unique_ptr info; @@ -95454,7 +101147,8 @@ void PhysicalCreateView::GetData(ExecutionContext &context, DataChunk &chunk, Gl if (state.finished) { return; } - Catalog::GetCatalog(context.client).CreateView(context.client, info.get()); + auto &catalog = Catalog::GetCatalog(context.client, info->catalog); + catalog.CreateView(context.client, info.get()); state.finished = true; } @@ -95479,7 +101173,7 @@ class PhysicalDrop : public PhysicalOperator { public: explicit PhysicalDrop(unique_ptr info, idx_t estimated_cardinality) : PhysicalOperator(PhysicalOperatorType::DROP, {LogicalType::BOOLEAN}, estimated_cardinality), - info(move(info)) { + info(std::move(info)) { } unique_ptr info; @@ -95495,6 +101189,439 @@ class PhysicalDrop : public PhysicalOperator { + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/settings.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { +class ClientContext; +class DatabaseInstance; +struct DBConfig; + +struct AccessModeSetting { + static constexpr const char *Name = "access_mode"; + static constexpr const char *Description = "Access mode of the database (AUTOMATIC, READ_ONLY or READ_WRITE)"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct CheckpointThresholdSetting { + static constexpr const char *Name = "checkpoint_threshold"; + static constexpr const char *Description = + "The WAL size threshold at which to automatically trigger a checkpoint (e.g. 1GB)"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct DebugCheckpointAbort { + static constexpr const char *Name = "debug_checkpoint_abort"; + static constexpr const char *Description = + "DEBUG SETTING: trigger an abort while checkpointing for testing purposes"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct DebugForceExternal { + static constexpr const char *Name = "debug_force_external"; + static constexpr const char *Description = + "DEBUG SETTING: force out-of-core computation for operators that support it, used for testing"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(ClientContext &context); +}; + +struct DebugForceNoCrossProduct { + static constexpr const char *Name = "debug_force_no_cross_product"; + static constexpr const char *Description = + "DEBUG SETTING: Force disable cross product generation when hyper graph isn't connected, used for testing"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(ClientContext &context); +}; + +struct DebugWindowMode { + static constexpr const char *Name = "debug_window_mode"; + static constexpr const char *Description = "DEBUG SETTING: switch window mode to use"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct DefaultCollationSetting { + static constexpr const char *Name = "default_collation"; + static constexpr const char *Description = "The collation setting used when none is specified"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(ClientContext &context); +}; + +struct DefaultOrderSetting { + static constexpr const char *Name = "default_order"; + static constexpr const char *Description = "The order type used when none is specified (ASC or DESC)"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct DefaultNullOrderSetting { + static constexpr const char *Name = "default_null_order"; + static constexpr const char *Description = "Null ordering used when none is specified (NULLS_FIRST or NULLS_LAST)"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct DisabledOptimizersSetting { + static constexpr const char *Name = "disabled_optimizers"; + static constexpr const char *Description = "DEBUG SETTING: disable a specific set of optimizers (comma separated)"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct EnableExternalAccessSetting { + static constexpr const char *Name = "enable_external_access"; + static constexpr const char *Description = + "Allow the database to access external state (through e.g. loading/installing modules, COPY TO/FROM, CSV " + "readers, pandas replacement scans, etc)"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct EnableFSSTVectors { + static constexpr const char *Name = "enable_fsst_vectors"; + static constexpr const char *Description = + "Allow scans on FSST compressed segments to emit compressed vectors to utilize late decompression"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct AllowUnsignedExtensionsSetting { + static constexpr const char *Name = "allow_unsigned_extensions"; + static constexpr const char *Description = "Allow to load extensions with invalid or missing signatures"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct CustomExtensionRepository { + static constexpr const char *Name = "custom_extension_repository"; + static constexpr const char *Description = "Overrides the custom endpoint for remote extension installation"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(ClientContext &context); +}; + +struct EnableObjectCacheSetting { + static constexpr const char *Name = "enable_object_cache"; + static constexpr const char *Description = "Whether or not object cache is used to cache e.g. Parquet metadata"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct EnableHTTPMetadataCacheSetting { + static constexpr const char *Name = "enable_http_metadata_cache"; + static constexpr const char *Description = "Whether or not the global http metadata is used to cache HTTP metadata"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static Value GetSetting(ClientContext &context); +}; + +struct EnableProfilingSetting { + static constexpr const char *Name = "enable_profiling"; + static constexpr const char *Description = + "Enables profiling, and sets the output format (JSON, QUERY_TREE, QUERY_TREE_OPTIMIZER)"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(ClientContext &context); +}; + +struct EnableProgressBarSetting { + static constexpr const char *Name = "enable_progress_bar"; + static constexpr const char *Description = + "Enables the progress bar, printing progress to the terminal for long queries"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(ClientContext &context); +}; +struct EnableProgressBarPrintSetting { + static constexpr const char *Name = "enable_progress_bar_print"; + static constexpr const char *Description = + "Controls the printing of the progress bar, when 'enable_progress_bar' is true"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(ClientContext &context); +}; + +struct ExperimentalParallelCSVSetting { + static constexpr const char *Name = "experimental_parallel_csv"; + static constexpr const char *Description = "Whether or not to use the experimental parallel CSV reader"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct ExplainOutputSetting { + static constexpr const char *Name = "explain_output"; + static constexpr const char *Description = "Output of EXPLAIN statements (ALL, OPTIMIZED_ONLY, PHYSICAL_ONLY)"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(ClientContext &context); +}; + +struct ExternalThreadsSetting { + static constexpr const char *Name = "external_threads"; + static constexpr const char *Description = "The number of external threads that work on DuckDB tasks."; + static constexpr const LogicalTypeId InputType = LogicalTypeId::BIGINT; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct FileSearchPathSetting { + static constexpr const char *Name = "file_search_path"; + static constexpr const char *Description = "A comma separated list of directories to search for input files"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(ClientContext &context); +}; + +struct ForceCompressionSetting { + static constexpr const char *Name = "force_compression"; + static constexpr const char *Description = "DEBUG SETTING: forces a specific compression method to be used"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct ForceBitpackingModeSetting { + static constexpr const char *Name = "force_bitpacking_mode"; + static constexpr const char *Description = "DEBUG SETTING: forces a specific bitpacking mode"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct HomeDirectorySetting { + static constexpr const char *Name = "home_directory"; + static constexpr const char *Description = "Sets the home directory used by the system"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(ClientContext &context); +}; + +struct LogQueryPathSetting { + static constexpr const char *Name = "log_query_path"; + static constexpr const char *Description = + "Specifies the path to which queries should be logged (default: empty string, queries are not logged)"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(ClientContext &context); +}; + +struct ImmediateTransactionModeSetting { + static constexpr const char *Name = "immediate_transaction_mode"; + static constexpr const char *Description = + "Whether transactions should be started lazily when needed, or immediately when BEGIN TRANSACTION is called"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct MaximumExpressionDepthSetting { + static constexpr const char *Name = "max_expression_depth"; + static constexpr const char *Description = + "The maximum expression depth limit in the parser. WARNING: increasing this setting and using very deep " + "expressions might lead to stack overflow errors."; + static constexpr const LogicalTypeId InputType = LogicalTypeId::UBIGINT; + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(ClientContext &context); +}; + +struct MaximumMemorySetting { + static constexpr const char *Name = "max_memory"; + static constexpr const char *Description = "The maximum memory of the system (e.g. 1GB)"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct PasswordSetting { + static constexpr const char *Name = "password"; + static constexpr const char *Description = "The password to use. Ignored for legacy compatibility."; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct PerfectHashThresholdSetting { + static constexpr const char *Name = "perfect_ht_threshold"; + static constexpr const char *Description = "Threshold in bytes for when to use a perfect hash table (default: 12)"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::BIGINT; + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(ClientContext &context); +}; + +struct PreserveIdentifierCase { + static constexpr const char *Name = "preserve_identifier_case"; + static constexpr const char *Description = + "Whether or not to preserve the identifier case, instead of always lowercasing all non-quoted identifiers"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(ClientContext &context); +}; + +struct PreserveInsertionOrder { + static constexpr const char *Name = "preserve_insertion_order"; + static constexpr const char *Description = + "Whether or not to preserve insertion order. If set to false the system is allowed to re-order any results " + "that do not contain ORDER BY clauses."; + static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct ProfilerHistorySize { + static constexpr const char *Name = "profiler_history_size"; + static constexpr const char *Description = "Sets the profiler history size"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::BIGINT; + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(ClientContext &context); +}; + +struct ProfileOutputSetting { + static constexpr const char *Name = "profile_output"; + static constexpr const char *Description = + "The file to which profile output should be saved, or empty to print to the terminal"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(ClientContext &context); +}; + +struct ProfilingModeSetting { + static constexpr const char *Name = "profiling_mode"; + static constexpr const char *Description = "The profiling mode (STANDARD or DETAILED)"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(ClientContext &context); +}; + +struct ProgressBarTimeSetting { + static constexpr const char *Name = "progress_bar_time"; + static constexpr const char *Description = + "Sets the time (in milliseconds) how long a query needs to take before we start printing a progress bar"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::BIGINT; + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(ClientContext &context); +}; + +struct SchemaSetting { + static constexpr const char *Name = "schema"; + static constexpr const char *Description = + "Sets the default search schema. Equivalent to setting search_path to a single value."; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(ClientContext &context); +}; + +struct SearchPathSetting { + static constexpr const char *Name = "search_path"; + static constexpr const char *Description = + "Sets the default search search path as a comma-separated list of values"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetLocal(ClientContext &context, const Value ¶meter); + static void ResetLocal(ClientContext &context); + static Value GetSetting(ClientContext &context); +}; + +struct TempDirectorySetting { + static constexpr const char *Name = "temp_directory"; + static constexpr const char *Description = "Set the directory to which to write temp files"; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct ThreadsSetting { + static constexpr const char *Name = "threads"; + static constexpr const char *Description = "The number of total threads used by the system."; + static constexpr const LogicalTypeId InputType = LogicalTypeId::BIGINT; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +struct UsernameSetting { + static constexpr const char *Name = "username"; + static constexpr const char *Description = "The username to use. Ignored for legacy compatibility."; + static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; + static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); + static void ResetGlobal(DatabaseInstance *db, DBConfig &config); + static Value GetSetting(ClientContext &context); +}; + +} // namespace duckdb + + namespace duckdb { //===--------------------------------------------------------------------===// @@ -95527,10 +101654,35 @@ void PhysicalDrop::GetData(ExecutionContext &context, DataChunk &chunk, GlobalSo } break; } - default: - Catalog::GetCatalog(context.client).DropEntry(context.client, info.get()); + case CatalogType::DATABASE_ENTRY: { + auto &db_manager = DatabaseManager::Get(context.client); + db_manager.DetachDatabase(context.client, info->name, info->if_exists); break; } + case CatalogType::SCHEMA_ENTRY: { + auto &catalog = Catalog::GetCatalog(context.client, info->catalog); + catalog.DropEntry(context.client, info.get()); + auto qualified_name = QualifiedName::Parse(info->name); + + // Check if the dropped schema was set as the current schema + auto &client_data = ClientData::Get(context.client); + auto &default_entry = client_data.catalog_search_path->GetDefault(); + auto ¤t_catalog = default_entry.catalog; + auto ¤t_schema = default_entry.schema; + D_ASSERT(info->name != DEFAULT_SCHEMA); + + if (info->catalog == current_catalog && current_schema == info->name) { + // Reset the schema to default + SchemaSetting::SetLocal(context.client, DEFAULT_SCHEMA); + } + break; + } + default: { + auto &catalog = Catalog::GetCatalog(context.client, info->catalog); + catalog.DropEntry(context.client, info.get()); + break; + } + } state.finished = true; } @@ -95551,9 +101703,10 @@ namespace duckdb { PhysicalRecursiveCTE::PhysicalRecursiveCTE(vector types, bool union_all, unique_ptr top, unique_ptr bottom, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::RECURSIVE_CTE, move(types), estimated_cardinality), union_all(union_all) { - children.push_back(move(top)); - children.push_back(move(bottom)); + : PhysicalOperator(PhysicalOperatorType::RECURSIVE_CTE, std::move(types), estimated_cardinality), + union_all(union_all) { + children.push_back(std::move(top)); + children.push_back(std::move(bottom)); } PhysicalRecursiveCTE::~PhysicalRecursiveCTE() { @@ -95769,9 +101922,9 @@ namespace duckdb { PhysicalUnion::PhysicalUnion(vector types, unique_ptr top, unique_ptr bottom, idx_t estimated_cardinality) - : PhysicalOperator(PhysicalOperatorType::UNION, move(types), estimated_cardinality) { - children.push_back(move(top)); - children.push_back(move(bottom)); + : PhysicalOperator(PhysicalOperatorType::UNION, std::move(types), estimated_cardinality) { + children.push_back(std::move(top)); + children.push_back(std::move(bottom)); } //===--------------------------------------------------------------------===// @@ -95865,9 +102018,9 @@ PartitionableHashTable::PartitionableHashTable(ClientContext &context, Allocator RadixPartitionInfo &partition_info_p, vector group_types_p, vector payload_types_p, vector bindings_p) - : context(context), allocator(allocator), group_types(move(group_types_p)), payload_types(move(payload_types_p)), - bindings(move(bindings_p)), is_partitioned(false), partition_info(partition_info_p), hashes(LogicalType::HASH), - hashes_subset(LogicalType::HASH) { + : context(context), allocator(allocator), group_types(std::move(group_types_p)), + payload_types(std::move(payload_types_p)), bindings(std::move(bindings_p)), is_partitioned(false), + partition_info(partition_info_p), hashes(LogicalType::HASH), hashes_subset(LogicalType::HASH) { sel_vectors.resize(partition_info.n_partitions); sel_vector_sizes.resize(partition_info.n_partitions); @@ -95976,11 +102129,11 @@ HashTableList PartitionableHashTable::GetPartition(idx_t partition) { D_ASSERT(IsPartitioned()); D_ASSERT(partition < partition_info.n_partitions); D_ASSERT(radix_partitioned_hts.size() > partition); - return move(radix_partitioned_hts[partition]); + return std::move(radix_partitioned_hts[partition]); } HashTableList PartitionableHashTable::GetUnpartitioned() { D_ASSERT(!IsPartitioned()); - return move(unpartitioned_hts); + return std::move(unpartitioned_hts); } void PartitionableHashTable::Finalize() { @@ -96011,9 +102164,9 @@ PerfectAggregateHashTable::PerfectAggregateHashTable(ClientContext &context, All vector payload_types_p, vector aggregate_objects_p, vector group_minima_p, vector required_bits_p) - : BaseAggregateHashTable(context, allocator, aggregate_objects_p, move(payload_types_p)), - addresses(LogicalType::POINTER), required_bits(move(required_bits_p)), total_required_bits(0), - group_minima(move(group_minima_p)), sel(STANDARD_VECTOR_SIZE) { + : BaseAggregateHashTable(context, allocator, aggregate_objects_p, std::move(payload_types_p)), + addresses(LogicalType::POINTER), required_bits(std::move(required_bits_p)), total_required_bits(0), + group_minima(std::move(group_minima_p)), sel(STANDARD_VECTOR_SIZE) { for (auto &group_bits : required_bits) { total_required_bits += group_bits; } @@ -96021,7 +102174,7 @@ PerfectAggregateHashTable::PerfectAggregateHashTable(ClientContext &context, All total_groups = (uint64_t)1 << total_required_bits; // we don't need to store the groups in a perfect hash table, since the group keys can be deduced by their location grouping_columns = group_types_p.size(); - layout.Initialize(move(aggregate_objects_p)); + layout.Initialize(std::move(aggregate_objects_p)); tuple_size = layout.GetRowWidth(); // allocate and null initialize the data @@ -96473,6 +102626,9 @@ bool PhysicalOperator::AllSourcesSupportBatchIndex() const { } bool PhysicalOperator::AllOperatorsPreserveOrder() const { + if (type == PhysicalOperatorType::ORDER_BY) { + return true; + } if (!IsOrderPreserving()) { return false; } @@ -96515,7 +102671,7 @@ bool CachingPhysicalOperator::CanCacheType(const LogicalType &type) { CachingPhysicalOperator::CachingPhysicalOperator(PhysicalOperatorType type, vector types_p, idx_t estimated_cardinality) - : PhysicalOperator(type, move(types_p), estimated_cardinality) { + : PhysicalOperator(type, std::move(types_p), estimated_cardinality) { caching_supported = true; for (auto &col_type : types) { @@ -96627,7 +102783,7 @@ class ComparisonExpression : public ParsedExpression { public: string ToString() const override; - static bool Equals(const ComparisonExpression *a, const ComparisonExpression *b); + static bool Equal(const ComparisonExpression *a, const ComparisonExpression *b); unique_ptr Copy() const override; @@ -96810,7 +102966,7 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalAggregate auto plan = CreatePlan(*op.children[0]); - plan = ExtractAggregateExpressions(move(plan), op.expressions, op.groups); + plan = ExtractAggregateExpressions(std::move(plan), op.expressions, op.groups); if (op.groups.empty()) { // no groups, check if we can use a simple aggregation @@ -96825,11 +102981,11 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalAggregate } } if (use_simple_aggregation) { - groupby = make_unique_base(op.types, move(op.expressions), - op.estimated_cardinality); + groupby = make_unique_base( + op.types, std::move(op.expressions), op.estimated_cardinality); } else { - groupby = make_unique_base(context, op.types, move(op.expressions), - op.estimated_cardinality); + groupby = make_unique_base( + context, op.types, std::move(op.expressions), op.estimated_cardinality); } } else { // groups! create a GROUP BY aggregator @@ -96837,15 +102993,15 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalAggregate vector required_bits; if (CanUsePerfectHashAggregate(context, op, required_bits)) { groupby = make_unique_base( - context, op.types, move(op.expressions), move(op.groups), move(op.group_stats), move(required_bits), - op.estimated_cardinality); + context, op.types, std::move(op.expressions), std::move(op.groups), std::move(op.group_stats), + std::move(required_bits), op.estimated_cardinality); } else { groupby = make_unique_base( - context, op.types, move(op.expressions), move(op.groups), move(op.grouping_sets), - move(op.grouping_functions), op.estimated_cardinality); + context, op.types, std::move(op.expressions), std::move(op.groups), std::move(op.grouping_sets), + std::move(op.grouping_functions), op.estimated_cardinality); } } - groupby->children.push_back(move(plan)); + groupby->children.push_back(std::move(plan)); return groupby; } @@ -96859,8 +103015,8 @@ PhysicalPlanGenerator::ExtractAggregateExpressions(unique_ptr for (auto &group : groups) { auto ref = make_unique(group->return_type, expressions.size()); types.push_back(group->return_type); - expressions.push_back(move(group)); - group = move(ref); + expressions.push_back(std::move(group)); + group = std::move(ref); } for (auto &aggr : aggregates) { @@ -96868,23 +103024,24 @@ PhysicalPlanGenerator::ExtractAggregateExpressions(unique_ptr for (auto &child : bound_aggr.children) { auto ref = make_unique(child->return_type, expressions.size()); types.push_back(child->return_type); - expressions.push_back(move(child)); - child = move(ref); + expressions.push_back(std::move(child)); + child = std::move(ref); } if (bound_aggr.filter) { auto &filter = bound_aggr.filter; auto ref = make_unique(filter->return_type, expressions.size()); types.push_back(filter->return_type); - expressions.push_back(move(filter)); - bound_aggr.filter = move(ref); + expressions.push_back(std::move(filter)); + bound_aggr.filter = std::move(ref); } } if (expressions.empty()) { return child; } - auto projection = make_unique(move(types), move(expressions), child->estimated_cardinality); - projection->children.push_back(move(child)); - return move(projection); + auto projection = + make_unique(std::move(types), std::move(expressions), child->estimated_cardinality); + projection->children.push_back(std::move(child)); + return std::move(projection); } } // namespace duckdb @@ -96933,8 +103090,8 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalAnyJoin &o auto right = CreatePlan(*op.children[1]); // create the blockwise NL join - return make_unique(op, move(left), move(right), move(op.condition), op.join_type, - op.estimated_cardinality); + return make_unique(op, std::move(left), std::move(right), std::move(op.condition), + op.join_type, op.estimated_cardinality); } } // namespace duckdb @@ -96992,9 +103149,9 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalColumnData // create a PhysicalChunkScan pointing towards the owned collection auto chunk_scan = make_unique(op.types, PhysicalOperatorType::COLUMN_DATA_SCAN, op.estimated_cardinality); - chunk_scan->owned_collection = move(op.collection); + chunk_scan->owned_collection = std::move(op.collection); chunk_scan->collection = chunk_scan->owned_collection.get(); - return move(chunk_scan); + return std::move(chunk_scan); } } // namespace duckdb @@ -97016,16 +103173,18 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalColumnData + namespace duckdb { -static bool CanPlanIndexJoin(Transaction &transaction, TableScanBindData *bind_data, PhysicalTableScan &scan) { +static bool CanPlanIndexJoin(ClientContext &context, TableScanBindData *bind_data, PhysicalTableScan &scan) { if (!bind_data) { // not a table scan return false; } auto table = bind_data->table; + auto &transaction = DuckTransaction::Get(context, *table->catalog); auto &local_storage = LocalStorage::Get(transaction); - if (local_storage.Find(table->storage.get())) { + if (local_storage.Find(table->GetStoragePtr())) { // transaction local appends: skip index join return false; } @@ -97132,7 +103291,7 @@ void CheckForPerfectJoinOpt(LogicalComparisonJoin &op, PerfectHashJoinStats &joi } static void CanUseIndexJoin(TableScanBindData *tbl, Expression &expr, Index **result_index) { - tbl->table->storage->info->indexes.Scan([&](Index &index) { + tbl->table->GetStorage().info->indexes.Scan([&](Index &index) { if (index.unbound_expressions.size() != 1) { return false; } @@ -97146,7 +103305,6 @@ static void CanUseIndexJoin(TableScanBindData *tbl, Expression &expr, Index **re void TransformIndexJoin(ClientContext &context, LogicalComparisonJoin &op, Index **left_index, Index **right_index, PhysicalOperator *left, PhysicalOperator *right) { - auto &transaction = Transaction::GetTransaction(context); // check if one of the tables has an index on column if (op.join_type == JoinType::INNER && op.conditions.size() == 1) { // check if one of the children are table scans and if they have an index in the join attribute @@ -97154,14 +103312,14 @@ void TransformIndexJoin(ClientContext &context, LogicalComparisonJoin &op, Index if (left->type == PhysicalOperatorType::TABLE_SCAN) { auto &tbl_scan = (PhysicalTableScan &)*left; auto tbl = dynamic_cast(tbl_scan.bind_data.get()); - if (CanPlanIndexJoin(transaction, tbl, tbl_scan)) { + if (CanPlanIndexJoin(context, tbl, tbl_scan)) { CanUseIndexJoin(tbl, *op.conditions[0].left, left_index); } } if (right->type == PhysicalOperatorType::TABLE_SCAN) { auto &tbl_scan = (PhysicalTableScan &)*right; auto tbl = dynamic_cast(tbl_scan.bind_data.get()); - if (CanPlanIndexJoin(transaction, tbl, tbl_scan)) { + if (CanPlanIndexJoin(context, tbl, tbl_scan)) { CanUseIndexJoin(tbl, *op.conditions[0].right, right_index); } } @@ -97187,7 +103345,7 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalComparison if (op.conditions.empty()) { // no conditions: insert a cross product - return make_unique(op.types, move(left), move(right), op.estimated_cardinality); + return make_unique(op.types, std::move(left), std::move(right), op.estimated_cardinality); } bool has_equality = false; @@ -97223,23 +103381,23 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalComparison (ClientConfig::GetConfig(context).force_index_join || rhs_cardinality < 0.01 * lhs_cardinality)) { auto &tbl_scan = (PhysicalTableScan &)*left; swap(op.conditions[0].left, op.conditions[0].right); - return make_unique(op, move(right), move(left), move(op.conditions), op.join_type, - op.right_projection_map, op.left_projection_map, tbl_scan.column_ids, - left_index, false, op.estimated_cardinality); + return make_unique(op, std::move(right), std::move(left), std::move(op.conditions), + op.join_type, op.right_projection_map, op.left_projection_map, + tbl_scan.column_ids, left_index, false, op.estimated_cardinality); } if (right_index && (ClientConfig::GetConfig(context).force_index_join || lhs_cardinality < 0.01 * rhs_cardinality)) { auto &tbl_scan = (PhysicalTableScan &)*right; - return make_unique(op, move(left), move(right), move(op.conditions), op.join_type, - op.left_projection_map, op.right_projection_map, tbl_scan.column_ids, - right_index, true, op.estimated_cardinality); + return make_unique(op, std::move(left), std::move(right), std::move(op.conditions), + op.join_type, op.left_projection_map, op.right_projection_map, + tbl_scan.column_ids, right_index, true, op.estimated_cardinality); } // Equality join with small number of keys : possible perfect join optimization PerfectHashJoinStats perfect_join_stats; CheckForPerfectJoinOpt(op, perfect_join_stats); - plan = make_unique(op, move(left), move(right), move(op.conditions), op.join_type, - op.left_projection_map, op.right_projection_map, move(op.delim_types), - op.estimated_cardinality, perfect_join_stats); + plan = make_unique(op, std::move(left), std::move(right), std::move(op.conditions), + op.join_type, op.left_projection_map, op.right_projection_map, + std::move(op.delim_types), op.estimated_cardinality, perfect_join_stats); } else { static constexpr const idx_t NESTED_LOOP_JOIN_THRESHOLD = 5; @@ -97261,23 +103419,24 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalComparison can_merge = false; } if (can_iejoin) { - plan = make_unique(op, move(left), move(right), move(op.conditions), op.join_type, - op.estimated_cardinality); + plan = make_unique(op, std::move(left), std::move(right), std::move(op.conditions), + op.join_type, op.estimated_cardinality); } else if (can_merge) { // range join: use piecewise merge join - plan = make_unique(op, move(left), move(right), move(op.conditions), - op.join_type, op.estimated_cardinality); + plan = + make_unique(op, std::move(left), std::move(right), std::move(op.conditions), + op.join_type, op.estimated_cardinality); } else if (PhysicalNestedLoopJoin::IsSupported(op.conditions, op.join_type)) { // inequality join: use nested loop - plan = make_unique(op, move(left), move(right), move(op.conditions), op.join_type, - op.estimated_cardinality); + plan = make_unique(op, std::move(left), std::move(right), std::move(op.conditions), + op.join_type, op.estimated_cardinality); } else { for (auto &cond : op.conditions) { RewriteJoinCondition(*cond.right, left->types.size()); } - auto condition = JoinCondition::CreateExpression(move(op.conditions)); - plan = make_unique(op, move(left), move(right), move(condition), op.join_type, - op.estimated_cardinality); + auto condition = JoinCondition::CreateExpression(std::move(op.conditions)); + plan = make_unique(op, std::move(left), std::move(right), std::move(condition), + op.join_type, op.estimated_cardinality); } } return plan; @@ -97305,13 +103464,20 @@ namespace duckdb { class LogicalCopyToFile : public LogicalOperator { public: LogicalCopyToFile(CopyFunction function, unique_ptr bind_data) - : LogicalOperator(LogicalOperatorType::LOGICAL_COPY_TO_FILE), function(function), bind_data(move(bind_data)) { + : LogicalOperator(LogicalOperatorType::LOGICAL_COPY_TO_FILE), function(function), + bind_data(std::move(bind_data)) { } CopyFunction function; unique_ptr bind_data; std::string file_path; bool use_tmp_file; - bool is_file_and_exists; + bool allow_overwrite; + bool per_thread_output; + + bool partition_output; + vector partition_columns; + vector names; + vector expected_types; public: void Serialize(FieldWriter &writer) const override; @@ -97333,17 +103499,26 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalCopyToFile auto &fs = FileSystem::GetFileSystem(context); op.file_path = fs.ExpandPath(op.file_path, FileSystem::GetFileOpener(context)); - bool use_tmp_file = op.is_file_and_exists && op.use_tmp_file; - if (use_tmp_file) { + if (op.use_tmp_file) { op.file_path += ".tmp"; } // COPY from select statement to file - auto copy = make_unique(op.types, op.function, move(op.bind_data), op.estimated_cardinality); + auto copy = + make_unique(op.types, op.function, std::move(op.bind_data), op.estimated_cardinality); copy->file_path = op.file_path; - copy->use_tmp_file = use_tmp_file; + copy->use_tmp_file = op.use_tmp_file; + copy->allow_overwrite = op.allow_overwrite; + copy->per_thread_output = op.per_thread_output; + copy->partition_output = op.partition_output; + copy->partition_columns = op.partition_columns; + copy->names = op.names; + copy->expected_types = op.expected_types; + if (op.function.parallel) { + copy->parallel = op.function.parallel(context, *copy->bind_data); + } - copy->children.push_back(move(plan)); - return move(copy); + copy->children.push_back(std::move(plan)); + return std::move(copy); } } // namespace duckdb @@ -97374,7 +103549,7 @@ namespace duckdb { class LogicalCreate : public LogicalOperator { public: LogicalCreate(LogicalOperatorType type, unique_ptr info, SchemaCatalogEntry *schema = nullptr) - : LogicalOperator(type), schema(schema), info(move(info)) { + : LogicalOperator(type), schema(schema), info(std::move(info)) { } SchemaCatalogEntry *schema; @@ -97398,24 +103573,24 @@ namespace duckdb { unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalCreate &op) { switch (op.type) { case LogicalOperatorType::LOGICAL_CREATE_SEQUENCE: - return make_unique(unique_ptr_cast(move(op.info)), + return make_unique(unique_ptr_cast(std::move(op.info)), op.estimated_cardinality); case LogicalOperatorType::LOGICAL_CREATE_VIEW: - return make_unique(unique_ptr_cast(move(op.info)), + return make_unique(unique_ptr_cast(std::move(op.info)), op.estimated_cardinality); case LogicalOperatorType::LOGICAL_CREATE_SCHEMA: - return make_unique(unique_ptr_cast(move(op.info)), + return make_unique(unique_ptr_cast(std::move(op.info)), op.estimated_cardinality); case LogicalOperatorType::LOGICAL_CREATE_MACRO: - return make_unique(unique_ptr_cast(move(op.info)), + return make_unique(unique_ptr_cast(std::move(op.info)), op.estimated_cardinality); case LogicalOperatorType::LOGICAL_CREATE_TYPE: { unique_ptr create = make_unique( - unique_ptr_cast(move(op.info)), op.estimated_cardinality); + unique_ptr_cast(std::move(op.info)), op.estimated_cardinality); if (!op.children.empty()) { D_ASSERT(op.children.size() == 1); auto plan = CreatePlan(*op.children[0]); - create->children.push_back(move(plan)); + create->children.push_back(std::move(plan)); } return create; } @@ -97435,13 +103610,30 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalCreate &op + + namespace duckdb { unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalCreateIndex &op) { + // generate a physical plan for the parallel index creation which consists of the following operators + // table scan - projection (for expression execution) - filter (NOT NULL) - order - create index + D_ASSERT(op.children.empty()); + // validate that all expressions contain valid scalar functions + // e.g. get_current_timestamp(), random(), and sequence values are not allowed as ART keys + // because they make deletions and lookups unfeasible + for (idx_t i = 0; i < op.unbound_expressions.size(); i++) { + auto &expr = op.unbound_expressions[i]; + if (expr->HasSideEffects()) { + throw BinderException("Index keys cannot contain expressions with side " + "effects."); + } + } + // table scan operator for index key columns and row IDs + unique_ptr table_filters; op.info->column_ids.emplace_back(COLUMN_IDENTIFIER_ROW_ID); @@ -97449,39 +103641,71 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalCreateInde bind_data.is_create_index = true; auto table_scan = - make_unique(op.info->scan_types, op.function, move(op.bind_data), op.info->column_ids, - op.info->names, move(table_filters), op.estimated_cardinality); + make_unique(op.info->scan_types, op.function, std::move(op.bind_data), op.info->column_ids, + op.info->names, std::move(table_filters), op.estimated_cardinality); - dependencies.insert(&op.table); + dependencies.AddDependency(&op.table); op.info->column_ids.pop_back(); D_ASSERT(op.info->scan_types.size() - 1 <= op.info->names.size()); D_ASSERT(op.info->scan_types.size() - 1 <= op.info->column_ids.size()); + // projection to execute expressions on the key columns + + vector new_column_types; + vector> select_list; + for (idx_t i = 0; i < op.expressions.size(); i++) { + new_column_types.push_back(op.expressions[i]->return_type); + select_list.push_back(std::move(op.expressions[i])); + } + new_column_types.emplace_back(LogicalType::ROW_TYPE); + select_list.push_back(make_unique(LogicalType::ROW_TYPE, op.info->scan_types.size() - 1)); + + auto projection = + make_unique(new_column_types, std::move(select_list), op.estimated_cardinality); + projection->children.push_back(std::move(table_scan)); + // filter operator for IS_NOT_NULL on each key column + vector filter_types; vector> filter_select_list; - for (idx_t i = 0; i < op.info->scan_types.size() - 1; i++) { - filter_types.push_back(op.info->scan_types[i]); + for (idx_t i = 0; i < new_column_types.size() - 1; i++) { + filter_types.push_back(new_column_types[i]); auto is_not_null_expr = make_unique(ExpressionType::OPERATOR_IS_NOT_NULL, LogicalType::BOOLEAN); - auto bound_ref = - make_unique(op.info->names[op.info->column_ids[i]], op.info->scan_types[i], i); - is_not_null_expr->children.push_back(move(bound_ref)); - filter_select_list.push_back(move(is_not_null_expr)); + auto bound_ref = make_unique(new_column_types[i], i); + is_not_null_expr->children.push_back(std::move(bound_ref)); + filter_select_list.push_back(std::move(is_not_null_expr)); } - auto null_filter = make_unique(move(filter_types), move(filter_select_list), STANDARD_VECTOR_SIZE); + auto null_filter = + make_unique(std::move(filter_types), std::move(filter_select_list), op.estimated_cardinality); null_filter->types.emplace_back(LogicalType::ROW_TYPE); - null_filter->children.push_back(move(table_scan)); + null_filter->children.push_back(std::move(projection)); + + // order operator + + vector orders; + vector projections; + for (idx_t i = 0; i < new_column_types.size() - 1; i++) { + auto col_expr = make_unique_base(new_column_types[i], i); + orders.emplace_back(OrderType::ASCENDING, OrderByNullType::NULLS_FIRST, std::move(col_expr)); + projections.emplace_back(i); + } + projections.emplace_back(new_column_types.size() - 1); + + auto physical_order = make_unique(new_column_types, std::move(orders), std::move(projections), + op.estimated_cardinality); + physical_order->children.push_back(std::move(null_filter)); // actual physical create index operator + auto physical_create_index = - make_unique(op, op.table, op.info->column_ids, move(op.expressions), move(op.info), - move(op.unbound_expressions), op.estimated_cardinality); - physical_create_index->children.push_back(move(null_filter)); - return move(physical_create_index); + make_unique(op, op.table, op.info->column_ids, std::move(op.info), + std::move(op.unbound_expressions), op.estimated_cardinality); + physical_create_index->children.push_back(std::move(physical_order)); + return std::move(physical_create_index); } } // namespace duckdb @@ -97491,6 +103715,7 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalCreateInde + //===----------------------------------------------------------------------===// // DuckDB // @@ -97509,7 +103734,7 @@ namespace duckdb { class LogicalCreateTable : public LogicalOperator { public: LogicalCreateTable(SchemaCatalogEntry *schema, unique_ptr info) - : LogicalOperator(LogicalOperatorType::LOGICAL_CREATE_TABLE), schema(schema), info(move(info)) { + : LogicalOperator(LogicalOperatorType::LOGICAL_CREATE_TABLE), schema(schema), info(std::move(info)) { } //! Schema to insert to @@ -97534,34 +103759,38 @@ class LogicalCreateTable : public LogicalOperator { + namespace duckdb { +unique_ptr DuckCatalog::PlanCreateTableAs(ClientContext &context, LogicalCreateTable &op, + unique_ptr plan) { + bool parallel_streaming_insert = !PhysicalPlanGenerator::PreserveInsertionOrder(context, *plan); + bool use_batch_index = PhysicalPlanGenerator::UseBatchIndex(context, *plan); + auto num_threads = TaskScheduler::GetScheduler(context).NumberOfThreads(); + unique_ptr create; + if (!parallel_streaming_insert && use_batch_index) { + create = make_unique(op, op.schema, std::move(op.info), op.estimated_cardinality); + + } else { + create = make_unique(op, op.schema, std::move(op.info), op.estimated_cardinality, + parallel_streaming_insert && num_threads > 1); + } + + D_ASSERT(op.children.size() == 1); + create->children.push_back(std::move(plan)); + return create; +} + unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalCreateTable &op) { - auto &create_info = (CreateTableInfo &)*op.info->base; - auto &catalog = Catalog::GetCatalog(context); - auto existing_entry = - catalog.GetEntry(context, CatalogType::TABLE_ENTRY, create_info.schema, create_info.table, true); + const auto &create_info = (CreateTableInfo &)*op.info->base; + auto &catalog = *op.info->schema->catalog; + auto existing_entry = catalog.GetEntry(context, create_info.schema, create_info.table, true); bool replace = op.info->Base().on_conflict == OnCreateConflict::REPLACE_ON_CONFLICT; if ((!existing_entry || replace) && !op.children.empty()) { auto plan = CreatePlan(*op.children[0]); - - bool parallel_streaming_insert = !PreserveInsertionOrder(*plan); - bool use_batch_index = UseBatchIndex(*plan); - auto num_threads = TaskScheduler::GetScheduler(context).NumberOfThreads(); - unique_ptr create; - if (!parallel_streaming_insert && use_batch_index) { - create = make_unique(op, op.schema, move(op.info), op.estimated_cardinality); - - } else { - create = make_unique(op, op.schema, move(op.info), op.estimated_cardinality, - parallel_streaming_insert && num_threads > 1); - } - - D_ASSERT(op.children.size() == 1); - create->children.push_back(move(plan)); - return create; + return op.schema->catalog->PlanCreateTableAs(context, op, std::move(plan)); } else { - return make_unique(op, op.schema, move(op.info), op.estimated_cardinality); + return make_unique(op, op.schema, std::move(op.info), op.estimated_cardinality); } } @@ -97578,13 +103807,44 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalCreateTabl +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/operator/logical_unconditional_join.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +//! LogicalUnconditionalJoin represents a join between two relations +//! where the join condition is implicit (cross product, position, etc.) +class LogicalUnconditionalJoin : public LogicalOperator { +public: + explicit LogicalUnconditionalJoin(LogicalOperatorType logical_type) : LogicalOperator(logical_type) {}; + +public: + LogicalUnconditionalJoin(LogicalOperatorType logical_type, unique_ptr left, + unique_ptr right); + +public: + vector GetColumnBindings() override; + +protected: + void ResolveTypes() override; +}; +} // namespace duckdb namespace duckdb { //! LogicalCrossProduct represents a cross product between two relations -class LogicalCrossProduct : public LogicalOperator { - LogicalCrossProduct() : LogicalOperator(LogicalOperatorType::LOGICAL_CROSS_PRODUCT) {}; +class LogicalCrossProduct : public LogicalUnconditionalJoin { + LogicalCrossProduct() : LogicalUnconditionalJoin(LogicalOperatorType::LOGICAL_CROSS_PRODUCT) {}; public: LogicalCrossProduct(unique_ptr left, unique_ptr right); @@ -97592,13 +103852,8 @@ class LogicalCrossProduct : public LogicalOperator { public: static unique_ptr Create(unique_ptr left, unique_ptr right); - vector GetColumnBindings() override; - void Serialize(FieldWriter &writer) const override; static unique_ptr Deserialize(LogicalDeserializationState &state, FieldReader &reader); - -protected: - void ResolveTypes() override; }; } // namespace duckdb @@ -97610,7 +103865,7 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalCrossProdu auto left = CreatePlan(*op.children[0]); auto right = CreatePlan(*op.children[1]); - return make_unique(op.types, move(left), move(right), op.estimated_cardinality); + return make_unique(op.types, std::move(left), std::move(right), op.estimated_cardinality); } } // namespace duckdb @@ -97630,16 +103885,12 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalCrossProdu - - namespace duckdb { +class TableCatalogEntry; class LogicalDelete : public LogicalOperator { public: - explicit LogicalDelete(TableCatalogEntry *table, idx_t table_index) - : LogicalOperator(LogicalOperatorType::LOGICAL_DELETE), table(table), table_index(table_index), - return_chunk(false) { - } + explicit LogicalDelete(TableCatalogEntry *table, idx_t table_index); TableCatalogEntry *table; idx_t table_index; @@ -97652,26 +103903,26 @@ class LogicalDelete : public LogicalOperator { vector GetTableIndex() const override; protected: - vector GetColumnBindings() override { - if (return_chunk) { - return GenerateColumnBindings(table_index, table->GetTypes().size()); - } - return {ColumnBinding(0, 0)}; - } - - void ResolveTypes() override { - if (return_chunk) { - types = table->GetTypes(); - } else { - types.emplace_back(LogicalType::BIGINT); - } - } + vector GetColumnBindings() override; + void ResolveTypes() override; }; } // namespace duckdb + namespace duckdb { +unique_ptr DuckCatalog::PlanDelete(ClientContext &context, LogicalDelete &op, + unique_ptr plan) { + // get the index of the row_id column + auto &bound_ref = (BoundReferenceExpression &)*op.expressions[0]; + + auto del = make_unique(op.types, *op.table, op.table->GetStorage(), bound_ref.index, + op.estimated_cardinality, op.return_chunk); + del->children.push_back(std::move(plan)); + return std::move(del); +} + unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalDelete &op) { D_ASSERT(op.children.size() == 1); D_ASSERT(op.expressions.size() == 1); @@ -97679,14 +103930,8 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalDelete &op auto plan = CreatePlan(*op.children[0]); - // get the index of the row_id column - auto &bound_ref = (BoundReferenceExpression &)*op.expressions[0]; - - dependencies.insert(op.table); - auto del = make_unique(op.types, *op.table, *op.table->storage, bound_ref.index, - op.estimated_cardinality, op.return_chunk); - del->children.push_back(move(plan)); - return move(del); + dependencies.AddDependency(op.table); + return op.table->catalog->PlanDelete(context, op, std::move(plan)); } } // namespace duckdb @@ -97745,7 +103990,7 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalDelimGet & // create a PhysicalChunkScan without an owned_collection, the collection will be added later auto chunk_scan = make_unique(op.types, PhysicalOperatorType::DELIM_SCAN, op.estimated_cardinality); - return move(chunk_scan); + return std::move(chunk_scan); } } // namespace duckdb @@ -97795,11 +104040,11 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalDelimJoin distinct_groups.push_back(make_unique(bound_ref.return_type, bound_ref.index)); } // now create the duplicate eliminated join - auto delim_join = make_unique(op.types, move(plan), delim_scans, op.estimated_cardinality); + auto delim_join = make_unique(op.types, std::move(plan), delim_scans, op.estimated_cardinality); // we still have to create the DISTINCT clause that is used to generate the duplicate eliminated chunk - delim_join->distinct = make_unique(context, delim_types, move(distinct_expressions), - move(distinct_groups), op.estimated_cardinality); - return move(delim_join); + delim_join->distinct = make_unique(context, delim_types, std::move(distinct_expressions), + std::move(distinct_groups), op.estimated_cardinality); + return std::move(delim_join); } } // namespace duckdb @@ -97829,7 +104074,7 @@ class LogicalDistinct : public LogicalOperator { LogicalDistinct() : LogicalOperator(LogicalOperatorType::LOGICAL_DISTINCT) { } explicit LogicalDistinct(vector> targets) - : LogicalOperator(LogicalOperatorType::LOGICAL_DISTINCT), distinct_targets(move(targets)) { + : LogicalOperator(LogicalOperatorType::LOGICAL_DISTINCT), distinct_targets(std::move(targets)) { } //! The set of distinct targets (optional). vector> distinct_targets; @@ -97872,7 +104117,7 @@ unique_ptr PhysicalPlanGenerator::CreateDistinctOn(unique_ptr< group_by_references[bound_ref.index] = i; } aggregate_types.push_back(target->return_type); - groups.push_back(move(target)); + groups.push_back(std::move(target)); } bool requires_projection = false; if (types.size() != group_count) { @@ -97895,40 +104140,41 @@ unique_ptr PhysicalPlanGenerator::CreateDistinctOn(unique_ptr< // entry is not one of the groups: need to push a FIRST aggregate auto bound = make_unique(logical_type, i); vector> first_children; - first_children.push_back(move(bound)); + first_children.push_back(std::move(bound)); FunctionBinder function_binder(context); auto first_aggregate = function_binder.BindAggregateFunction( - FirstFun::GetFunction(logical_type), move(first_children), nullptr, AggregateType::NON_DISTINCT); + FirstFun::GetFunction(logical_type), std::move(first_children), nullptr, AggregateType::NON_DISTINCT); // add the projection projections.push_back(make_unique(logical_type, group_count + aggregates.size())); // push it to the list of aggregates aggregate_types.push_back(logical_type); - aggregates.push_back(move(first_aggregate)); + aggregates.push_back(std::move(first_aggregate)); requires_projection = true; } } - child = ExtractAggregateExpressions(move(child), aggregates, groups); + child = ExtractAggregateExpressions(std::move(child), aggregates, groups); // we add a physical hash aggregation in the plan to select the distinct groups - auto groupby = make_unique(context, aggregate_types, move(aggregates), move(groups), - child->estimated_cardinality); - groupby->children.push_back(move(child)); + auto groupby = make_unique(context, aggregate_types, std::move(aggregates), + std::move(groups), child->estimated_cardinality); + groupby->children.push_back(std::move(child)); if (!requires_projection) { - return move(groupby); + return std::move(groupby); } // we add a physical projection on top of the aggregation to project all members in the select list - auto aggr_projection = make_unique(types, move(projections), groupby->estimated_cardinality); - aggr_projection->children.push_back(move(groupby)); - return move(aggr_projection); + auto aggr_projection = + make_unique(types, std::move(projections), groupby->estimated_cardinality); + aggr_projection->children.push_back(std::move(groupby)); + return std::move(aggr_projection); } unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalDistinct &op) { D_ASSERT(op.children.size() == 1); auto plan = CreatePlan(*op.children[0]); - return CreateDistinctOn(move(plan), move(op.distinct_targets)); + return CreateDistinctOn(std::move(plan), std::move(op.distinct_targets)); } } // namespace duckdb @@ -98062,7 +104308,7 @@ namespace duckdb { class LogicalExecute : public LogicalOperator { public: explicit LogicalExecute(shared_ptr prepared_p) - : LogicalOperator(LogicalOperatorType::LOGICAL_EXECUTE), prepared(move(prepared_p)) { + : LogicalOperator(LogicalOperatorType::LOGICAL_EXECUTE), prepared(std::move(prepared_p)) { D_ASSERT(prepared); types = prepared->types; } @@ -98095,9 +104341,9 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalExecute &o D_ASSERT(op.children.size() == 1); auto owned_plan = CreatePlan(*op.children[0]); auto execute = make_unique(owned_plan.get()); - execute->owned_plan = move(owned_plan); - execute->prepared = move(op.prepared); - return move(execute); + execute->owned_plan = std::move(owned_plan); + execute->prepared = std::move(op.prepared); + return std::move(execute); } else { D_ASSERT(op.children.size() == 0); return make_unique(op.prepared->plan.get()); @@ -98160,7 +104406,7 @@ class LogicalExplain : public LogicalOperator { public: LogicalExplain(unique_ptr plan, ExplainType explain_type) : LogicalOperator(LogicalOperatorType::LOGICAL_EXPLAIN), explain_type(explain_type) { - children.push_back(move(plan)); + children.push_back(std::move(plan)); } ExplainType explain_type; @@ -98200,8 +104446,8 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalExplain &o auto plan = CreatePlan(*op.children[0]); if (op.explain_type == ExplainType::EXPLAIN_ANALYZE) { auto result = make_unique(op.types); - result->children.push_back(move(plan)); - return move(result); + result->children.push_back(std::move(plan)); + return std::move(result); } op.physical_plan = plan->ToString(); @@ -98243,9 +104489,9 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalExplain &o // create a chunk scan to output the result auto chunk_scan = make_unique(op.types, PhysicalOperatorType::COLUMN_DATA_SCAN, op.estimated_cardinality); - chunk_scan->owned_collection = move(collection); + chunk_scan->owned_collection = std::move(collection); chunk_scan->collection = chunk_scan->owned_collection.get(); - return move(chunk_scan); + return std::move(chunk_scan); } } // namespace duckdb @@ -98271,8 +104517,8 @@ namespace duckdb { class LogicalExport : public LogicalOperator { public: LogicalExport(CopyFunction function, unique_ptr copy_info, BoundExportData exported_tables) - : LogicalOperator(LogicalOperatorType::LOGICAL_EXPORT), function(function), copy_info(move(copy_info)), - exported_tables(move(exported_tables)) { + : LogicalOperator(LogicalOperatorType::LOGICAL_EXPORT), function(function), copy_info(std::move(copy_info)), + exported_tables(std::move(exported_tables)) { } CopyFunction function; unique_ptr copy_info; @@ -98299,14 +104545,14 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalExport &op if (!config.options.enable_external_access) { throw PermissionException("Export is disabled through configuration"); } - auto export_node = make_unique(op.types, op.function, move(op.copy_info), op.estimated_cardinality, - op.exported_tables); + auto export_node = make_unique(op.types, op.function, std::move(op.copy_info), + op.estimated_cardinality, op.exported_tables); // plan the underlying copy statements, if any if (!op.children.empty()) { auto plan = CreatePlan(*op.children[0]); - export_node->children.push_back(move(plan)); + export_node->children.push_back(std::move(plan)); } - return move(export_node); + return std::move(export_node); } } // namespace duckdb @@ -98332,7 +104578,7 @@ class LogicalExpressionGet : public LogicalOperator { LogicalExpressionGet(idx_t table_index, vector types, vector>> expressions) : LogicalOperator(LogicalOperatorType::LOGICAL_EXPRESSION_GET), table_index(table_index), expr_types(types), - expressions(move(expressions)) { + expressions(std::move(expressions)) { } //! The table index in the current bind context @@ -98370,10 +104616,10 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalExpression D_ASSERT(op.children.size() == 1); auto plan = CreatePlan(*op.children[0]); - auto expr_scan = make_unique(op.types, move(op.expressions), op.estimated_cardinality); - expr_scan->children.push_back(move(plan)); + auto expr_scan = make_unique(op.types, std::move(op.expressions), op.estimated_cardinality); + expr_scan->children.push_back(std::move(plan)); if (!expr_scan->IsFoldable()) { - return move(expr_scan); + return std::move(expr_scan); } auto &allocator = Allocator::Get(context); // simple expression scan (i.e. no subqueries to evaluate and no prepared statement parameters) @@ -98393,7 +104639,7 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalExpression expr_scan->EvaluateExpression(context, expression_idx, nullptr, chunk); chunk_scan->owned_collection->Append(append_state, chunk); } - return move(chunk_scan); + return std::move(chunk_scan); } } // namespace duckdb @@ -98455,7 +104701,7 @@ class SpecificExpressionTypeMatcher : public ExpressionTypeMatcher { //! The ManyExpressionTypeMatcher class matches a set of ExpressionTypes class ManyExpressionTypeMatcher : public ExpressionTypeMatcher { public: - explicit ManyExpressionTypeMatcher(vector types) : types(move(types)) { + explicit ManyExpressionTypeMatcher(vector types) : types(std::move(types)) { } bool Match(ExpressionType type) override { @@ -98683,7 +104929,7 @@ class FunctionMatcher { //! The SpecificFunctionMatcher class matches a single specified function name class SpecificFunctionMatcher : public FunctionMatcher { public: - explicit SpecificFunctionMatcher(string name) : name(move(name)) { + explicit SpecificFunctionMatcher(string name) : name(std::move(name)) { } bool Match(string &name) override { @@ -98697,7 +104943,7 @@ class SpecificFunctionMatcher : public FunctionMatcher { //! The ManyFunctionMatcher class matches a set of functions class ManyFunctionMatcher : public FunctionMatcher { public: - explicit ManyFunctionMatcher(unordered_set names) : names(move(names)) { + explicit ManyFunctionMatcher(unordered_set names) : names(std::move(names)) { } bool Match(string &name) override { @@ -98888,9 +105134,9 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalFilter &op if (!op.expressions.empty()) { D_ASSERT(plan->types.size() > 0); // create a filter if there is anything to filter - auto filter = make_unique(plan->types, move(op.expressions), op.estimated_cardinality); - filter->children.push_back(move(plan)); - plan = move(filter); + auto filter = make_unique(plan->types, std::move(op.expressions), op.estimated_cardinality); + filter->children.push_back(std::move(plan)); + plan = std::move(filter); } if (!op.projection_map.empty()) { // there is a projection map, generate a physical projection @@ -98898,9 +105144,9 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalFilter &op for (idx_t i = 0; i < op.projection_map.size(); i++) { select_list.push_back(make_unique(op.types[i], op.projection_map[i])); } - auto proj = make_unique(op.types, move(select_list), op.estimated_cardinality); - proj->children.push_back(move(plan)); - plan = move(proj); + auto proj = make_unique(op.types, std::move(select_list), op.estimated_cardinality); + proj->children.push_back(std::move(plan)); + plan = std::move(proj); } return plan; } @@ -98932,7 +105178,7 @@ unique_ptr CreateTableFilterSet(TableFilterSet &table_filters, v if (column_index == DConstants::INVALID_INDEX) { throw InternalException("Could not find column index for table filter"); } - table_filter_set->filters[column_index] = move(table_filter.second); + table_filter_set->filters[column_index] = std::move(table_filter.second); } return table_filter_set; } @@ -98941,10 +105187,14 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalGet &op) { if (!op.children.empty()) { // this is for table producing functions that consume subquery results D_ASSERT(op.children.size() == 1); - auto node = make_unique(op.returned_types, op.function, move(op.bind_data), - op.column_ids, op.estimated_cardinality); - node->children.push_back(CreatePlan(move(op.children[0]))); - return move(node); + auto node = + make_unique(op.types, op.function, std::move(op.bind_data), op.column_ids, + op.estimated_cardinality, std::move(op.projected_input)); + node->children.push_back(CreatePlan(std::move(op.children[0]))); + return std::move(node); + } + if (!op.projected_input.empty()) { + throw InternalException("LogicalGet::project_input can only be set for table-in-out functions"); } unique_ptr table_filters; @@ -98958,9 +105208,9 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalGet &op) { // create the table scan node if (!op.function.projection_pushdown) { // function does not support projection pushdown - auto node = make_unique(op.returned_types, op.function, move(op.bind_data), + auto node = make_unique(op.returned_types, op.function, std::move(op.bind_data), op.returned_types, op.column_ids, vector(), op.names, - move(table_filters), op.estimated_cardinality); + std::move(table_filters), op.estimated_cardinality); // first check if an additional projection is necessary if (op.column_ids.size() == op.returned_types.size()) { bool projection_necessary = false; @@ -98974,7 +105224,7 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalGet &op) { // a projection is not necessary if all columns have been requested in-order // in that case we just return the node - return move(node); + return std::move(node); } } // push a projection on top that does the projection @@ -98991,12 +105241,13 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalGet &op) { } } - auto projection = make_unique(move(types), move(expressions), op.estimated_cardinality); - projection->children.push_back(move(node)); - return move(projection); + auto projection = + make_unique(std::move(types), std::move(expressions), op.estimated_cardinality); + projection->children.push_back(std::move(node)); + return std::move(projection); } else { - return make_unique(op.types, op.function, move(op.bind_data), op.returned_types, - op.column_ids, op.projection_ids, op.names, move(table_filters), + return make_unique(op.types, op.function, std::move(op.bind_data), op.returned_types, + op.column_ids, op.projection_ids, op.names, std::move(table_filters), op.estimated_cardinality); } } @@ -99005,71 +105256,12 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalGet &op) { -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/operator/logical_insert.hpp -// -// -//===----------------------------------------------------------------------===// -namespace duckdb { - -//! LogicalInsert represents an insertion of data into a base table -class LogicalInsert : public LogicalOperator { -public: - LogicalInsert(TableCatalogEntry *table, idx_t table_index) - : LogicalOperator(LogicalOperatorType::LOGICAL_INSERT), table(table), table_index(table_index), - return_chunk(false) { - } - - vector>> insert_values; - //! The insertion map ([table_index -> index in result, or DConstants::INVALID_INDEX if not specified]) - physical_index_vector_t column_index_map; - //! The expected types for the INSERT statement (obtained from the column types) - vector expected_types; - //! The base table to insert into - TableCatalogEntry *table; - idx_t table_index; - //! if returning option is used, return actual chunk to projection - bool return_chunk; - //! The default statements used by the table - vector> bound_defaults; - -public: - void Serialize(FieldWriter &writer) const override; - static unique_ptr Deserialize(LogicalDeserializationState &state, FieldReader &reader); - -protected: - vector GetColumnBindings() override { - if (return_chunk) { - return GenerateColumnBindings(table_index, table->GetTypes().size()); - } - return {ColumnBinding(0, 0)}; - } - - void ResolveTypes() override { - if (return_chunk) { - types = table->GetTypes(); - } else { - types.emplace_back(LogicalType::BIGINT); - } - } - - idx_t EstimateCardinality(ClientContext &context) override; - vector GetTableIndex() const override; -}; -} // namespace duckdb - - - - - namespace duckdb { @@ -99091,6 +105283,7 @@ bool PhysicalPlanGenerator::PreserveInsertionOrder(PhysicalOperator &plan) { } bool PhysicalPlanGenerator::UseBatchIndex(ClientContext &context, PhysicalOperator &plan) { + // TODO: always preserve order if query contains ORDER BY auto &scheduler = TaskScheduler::GetScheduler(context); if (scheduler.NumberOfThreads() == 1) { // batch index usage only makes sense if we are using multiple threads @@ -99107,37 +105300,51 @@ bool PhysicalPlanGenerator::UseBatchIndex(PhysicalOperator &plan) { return UseBatchIndex(context, plan); } -unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalInsert &op) { - unique_ptr plan; - if (!op.children.empty()) { - D_ASSERT(op.children.size() == 1); - plan = CreatePlan(*op.children[0]); - } - dependencies.insert(op.table); - - bool parallel_streaming_insert = !PreserveInsertionOrder(*plan); - bool use_batch_index = UseBatchIndex(*plan); +unique_ptr DuckCatalog::PlanInsert(ClientContext &context, LogicalInsert &op, + unique_ptr plan) { + bool parallel_streaming_insert = !PhysicalPlanGenerator::PreserveInsertionOrder(context, *plan); + bool use_batch_index = PhysicalPlanGenerator::UseBatchIndex(context, *plan); auto num_threads = TaskScheduler::GetScheduler(context).NumberOfThreads(); if (op.return_chunk) { // not supported for RETURNING (yet?) parallel_streaming_insert = false; use_batch_index = false; } + if (op.action_type != OnConflictAction::THROW) { + // We don't support ON CONFLICT clause in batch insertion operation currently + use_batch_index = false; + } + if (op.action_type == OnConflictAction::UPDATE) { + // When we potentially need to perform updates, we have to check that row is not updated twice + // that currently needs to be done for every chunk, which would add a huge bottleneck to parallelized insertion + parallel_streaming_insert = false; + } unique_ptr insert; if (use_batch_index && !parallel_streaming_insert) { - insert = make_unique(op.types, op.table, op.column_index_map, move(op.bound_defaults), + insert = make_unique(op.types, op.table, op.column_index_map, std::move(op.bound_defaults), op.estimated_cardinality); } else { - insert = make_unique(op.types, op.table, op.column_index_map, move(op.bound_defaults), - op.estimated_cardinality, op.return_chunk, - parallel_streaming_insert && num_threads > 1); - } - if (plan) { - insert->children.push_back(move(plan)); + insert = make_unique( + op.types, op.table, op.column_index_map, std::move(op.bound_defaults), std::move(op.expressions), + std::move(op.set_columns), std::move(op.set_types), op.estimated_cardinality, op.return_chunk, + parallel_streaming_insert && num_threads > 1, op.action_type, std::move(op.on_conflict_condition), + std::move(op.do_update_condition), std::move(op.on_conflict_filter), std::move(op.columns_to_fetch)); } + D_ASSERT(plan); + insert->children.push_back(std::move(plan)); return insert; } +unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalInsert &op) { + unique_ptr plan; + if (!op.children.empty()) { + D_ASSERT(op.children.size() == 1); + plan = CreatePlan(*op.children[0]); + } + dependencies.AddDependency(op.table); + return op.table->catalog->PlanInsert(context, op, std::move(plan)); +} + } // namespace duckdb @@ -99193,22 +105400,23 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalLimit &op) unique_ptr limit; if (!PreserveInsertionOrder(*plan)) { // use parallel streaming limit if insertion order is not important - limit = make_unique(op.types, (idx_t)op.limit_val, op.offset_val, move(op.limit), - move(op.offset), op.estimated_cardinality, true); + limit = make_unique(op.types, (idx_t)op.limit_val, op.offset_val, std::move(op.limit), + std::move(op.offset), op.estimated_cardinality, true); } else { // maintaining insertion order is important if (UseBatchIndex(*plan)) { // source supports batch index: use parallel batch limit - limit = make_unique(op.types, (idx_t)op.limit_val, op.offset_val, move(op.limit), - move(op.offset), op.estimated_cardinality); + limit = make_unique(op.types, (idx_t)op.limit_val, op.offset_val, std::move(op.limit), + std::move(op.offset), op.estimated_cardinality); } else { // source does not support batch index: use a non-parallel streaming limit - limit = make_unique(op.types, (idx_t)op.limit_val, op.offset_val, move(op.limit), - move(op.offset), op.estimated_cardinality, false); + limit = + make_unique(op.types, (idx_t)op.limit_val, op.offset_val, std::move(op.limit), + std::move(op.offset), op.estimated_cardinality, false); } } - limit->children.push_back(move(plan)); + limit->children.push_back(std::move(plan)); return limit; } @@ -99224,10 +105432,10 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalLimitPerce auto plan = CreatePlan(*op.children[0]); - auto limit = make_unique(op.types, op.limit_percent, op.offset_val, move(op.limit), - move(op.offset), op.estimated_cardinality); - limit->children.push_back(move(plan)); - return move(limit); + auto limit = make_unique(op.types, op.limit_percent, op.offset_val, std::move(op.limit), + std::move(op.offset), op.estimated_cardinality); + limit->children.push_back(std::move(plan)); + return std::move(limit); } } // namespace duckdb @@ -99254,7 +105462,7 @@ namespace duckdb { class LogicalOrder : public LogicalOperator { public: explicit LogicalOrder(vector orders) - : LogicalOperator(LogicalOperatorType::LOGICAL_ORDER_BY), orders(move(orders)) { + : LogicalOperator(LogicalOperatorType::LOGICAL_ORDER_BY), orders(std::move(orders)) { } vector orders; @@ -99316,17 +105524,67 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalOrder &op) projections.push_back(i); } } else { - projections = move(op.projections); + projections = std::move(op.projections); } - auto order = make_unique(op.types, move(op.orders), move(projections), op.estimated_cardinality); - order->children.push_back(move(plan)); - plan = move(order); + auto order = make_unique(op.types, std::move(op.orders), std::move(projections), + op.estimated_cardinality); + order->children.push_back(std::move(plan)); + plan = std::move(order); } return plan; } } // namespace duckdb + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/operator/logical_positional_join.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +//! LogicalPositionalJoin represents a row-wise join between two relations +class LogicalPositionalJoin : public LogicalUnconditionalJoin { + LogicalPositionalJoin() : LogicalUnconditionalJoin(LogicalOperatorType::LOGICAL_POSITIONAL_JOIN) {}; + +public: + LogicalPositionalJoin(unique_ptr left, unique_ptr right); + +public: + static unique_ptr Create(unique_ptr left, unique_ptr right); + + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(LogicalDeserializationState &state, FieldReader &reader); +}; +} // namespace duckdb + + +namespace duckdb { + +unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalPositionalJoin &op) { + D_ASSERT(op.children.size() == 2); + + auto left = CreatePlan(*op.children[0]); + auto right = CreatePlan(*op.children[1]); + if (left->type == PhysicalOperatorType::TABLE_SCAN && right->type == PhysicalOperatorType::TABLE_SCAN) { + return make_unique(op.types, std::move(left), std::move(right)); + } else { + return make_unique(op.types, std::move(left), std::move(right), + op.estimated_cardinality); + } +} + +} // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // @@ -99347,7 +105605,8 @@ namespace duckdb { class LogicalPragma : public LogicalOperator { public: LogicalPragma(PragmaFunction function_p, PragmaInfo info_p) - : LogicalOperator(LogicalOperatorType::LOGICAL_PRAGMA), function(move(function_p)), info(move(info_p)) { + : LogicalOperator(LogicalOperatorType::LOGICAL_PRAGMA), function(std::move(function_p)), + info(std::move(info_p)) { } //! The pragma function to call @@ -99400,9 +105659,9 @@ class TableCatalogEntry; class LogicalPrepare : public LogicalOperator { public: LogicalPrepare(string name, shared_ptr prepared, unique_ptr logical_plan) - : LogicalOperator(LogicalOperatorType::LOGICAL_PREPARE), name(name), prepared(move(prepared)) { + : LogicalOperator(LogicalOperatorType::LOGICAL_PREPARE), name(name), prepared(std::move(prepared)) { if (logical_plan) { - children.push_back(move(logical_plan)); + children.push_back(std::move(logical_plan)); } } @@ -99439,10 +105698,10 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalPrepare &o if (!op.children.empty()) { auto plan = CreatePlan(*op.children[0]); op.prepared->types = plan->types; - op.prepared->plan = move(plan); + op.prepared->plan = std::move(plan); } - return make_unique(op.name, move(op.prepared), op.estimated_cardinality); + return make_unique(op.name, std::move(op.prepared), op.estimated_cardinality); } } // namespace duckdb @@ -99515,9 +105774,9 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalProjection } } - auto projection = make_unique(op.types, move(op.expressions), op.estimated_cardinality); - projection->children.push_back(move(plan)); - return move(projection); + auto projection = make_unique(op.types, std::move(op.expressions), op.estimated_cardinality); + projection->children.push_back(std::move(plan)); + return std::move(projection); } } // namespace duckdb @@ -99549,8 +105808,8 @@ class LogicalRecursiveCTE : public LogicalOperator { unique_ptr bottom, LogicalOperatorType type) : LogicalOperator(type), union_all(union_all), table_index(table_index), column_count(column_count) { D_ASSERT(type == LogicalOperatorType::LOGICAL_RECURSIVE_CTE); - children.push_back(move(top)); - children.push_back(move(bottom)); + children.push_back(std::move(top)); + children.push_back(std::move(bottom)); } bool union_all; @@ -99637,11 +105896,11 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalRecursiveC auto left = CreatePlan(*op.children[0]); auto right = CreatePlan(*op.children[1]); - auto cte = - make_unique(op.types, op.union_all, move(left), move(right), op.estimated_cardinality); + auto cte = make_unique(op.types, op.union_all, std::move(left), std::move(right), + op.estimated_cardinality); cte->working_table = working_table; - return move(cte); + return std::move(cte); } unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalCTERef &op) { @@ -99653,10 +105912,59 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalCTERef &op // CreatePlan of a LogicalRecursiveCTE must have happened before. auto cte = recursive_cte_tables.find(op.cte_index); if (cte == recursive_cte_tables.end()) { - throw Exception("Referenced recursive CTE does not exist."); + throw InvalidInputException("Referenced recursive CTE does not exist."); } chunk_scan->collection = cte->second.get(); - return move(chunk_scan); + return std::move(chunk_scan); +} + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/operator/logical_reset.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + + +namespace duckdb { + +class LogicalReset : public LogicalOperator { +public: + LogicalReset(std::string name_p, SetScope scope_p) + : LogicalOperator(LogicalOperatorType::LOGICAL_RESET), name(name_p), scope(scope_p) { + } + + std::string name; + SetScope scope; + +public: + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(LogicalDeserializationState &state, FieldReader &reader); + idx_t EstimateCardinality(ClientContext &context) override; + +protected: + void ResolveTypes() override { + types.emplace_back(LogicalType::BOOLEAN); + } +}; + +} // namespace duckdb + + + +namespace duckdb { + +unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalReset &op) { + return make_unique(op.name, op.scope, op.estimated_cardinality); } } // namespace duckdb @@ -99710,7 +106018,7 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalSample &op unique_ptr sample; switch (op.sample_options->method) { case SampleMethod::RESERVOIR_SAMPLE: - sample = make_unique(op.types, move(op.sample_options), op.estimated_cardinality); + sample = make_unique(op.types, std::move(op.sample_options), op.estimated_cardinality); break; case SampleMethod::SYSTEM_SAMPLE: case SampleMethod::BERNOULLI_SAMPLE: @@ -99726,7 +106034,7 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalSample &op default: throw InternalException("Unimplemented sample method"); } - sample->children.push_back(move(plan)); + sample->children.push_back(std::move(plan)); return sample; } @@ -99810,8 +106118,8 @@ class LogicalSetOperation : public LogicalOperator { : LogicalOperator(type), table_index(table_index), column_count(column_count) { D_ASSERT(type == LogicalOperatorType::LOGICAL_UNION || type == LogicalOperatorType::LOGICAL_EXCEPT || type == LogicalOperatorType::LOGICAL_INTERSECT); - children.push_back(move(top)); - children.push_back(move(bottom)); + children.push_back(std::move(top)); + children.push_back(std::move(bottom)); } idx_t table_index; @@ -99843,13 +106151,13 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalSetOperati auto right = CreatePlan(*op.children[1]); if (left->GetTypes() != right->GetTypes()) { - throw Exception("Type mismatch for SET OPERATION"); + throw InvalidInputException("Type mismatch for SET OPERATION"); } switch (op.type) { case LogicalOperatorType::LOGICAL_UNION: // UNION - return make_unique(op.types, move(left), move(right), op.estimated_cardinality); + return make_unique(op.types, std::move(left), std::move(right), op.estimated_cardinality); default: { // EXCEPT/INTERSECT D_ASSERT(op.type == LogicalOperatorType::LOGICAL_EXCEPT || op.type == LogicalOperatorType::LOGICAL_INTERSECT); @@ -99861,13 +106169,13 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalSetOperati cond.left = make_unique(types[i], i); cond.right = make_unique(types[i], i); cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM; - conditions.push_back(move(cond)); + conditions.push_back(std::move(cond)); } // EXCEPT is ANTI join // INTERSECT is SEMI join PerfectHashJoinStats join_stats; // used in inner joins only JoinType join_type = op.type == LogicalOperatorType::LOGICAL_EXCEPT ? JoinType::ANTI : JoinType::SEMI; - return make_unique(op, move(left), move(right), move(conditions), join_type, + return make_unique(op, std::move(left), std::move(right), std::move(conditions), join_type, op.estimated_cardinality, join_stats); } } @@ -99932,7 +106240,7 @@ class LogicalShow : public LogicalOperator { public: explicit LogicalShow(unique_ptr plan) : LogicalOperator(LogicalOperatorType::LOGICAL_SHOW) { - children.push_back(move(plan)); + children.push_back(std::move(plan)); } vector types_select; @@ -99993,9 +106301,9 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalShow &op) // create a chunk scan to output the result auto chunk_scan = make_unique(op.types, PhysicalOperatorType::COLUMN_DATA_SCAN, op.estimated_cardinality); - chunk_scan->owned_collection = move(collection); + chunk_scan->owned_collection = std::move(collection); chunk_scan->collection = chunk_scan->owned_collection.get(); - return move(chunk_scan); + return std::move(chunk_scan); } } // namespace duckdb @@ -100009,6 +106317,7 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalShow &op) + //===----------------------------------------------------------------------===// // DuckDB // @@ -100028,7 +106337,7 @@ namespace duckdb { //! LogicalSimple represents a simple logical operator that only passes on the parse info class LogicalSimple : public LogicalOperator { public: - LogicalSimple(LogicalOperatorType type, unique_ptr info) : LogicalOperator(type), info(move(info)) { + LogicalSimple(LogicalOperatorType type, unique_ptr info) : LogicalOperator(type), info(std::move(info)) { } unique_ptr info; @@ -100051,24 +106360,29 @@ namespace duckdb { unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalSimple &op) { switch (op.type) { case LogicalOperatorType::LOGICAL_ALTER: - return make_unique(unique_ptr_cast(move(op.info)), + return make_unique(unique_ptr_cast(std::move(op.info)), op.estimated_cardinality); case LogicalOperatorType::LOGICAL_DROP: - return make_unique(unique_ptr_cast(move(op.info)), op.estimated_cardinality); + return make_unique(unique_ptr_cast(std::move(op.info)), + op.estimated_cardinality); case LogicalOperatorType::LOGICAL_TRANSACTION: - return make_unique(unique_ptr_cast(move(op.info)), + return make_unique(unique_ptr_cast(std::move(op.info)), op.estimated_cardinality); case LogicalOperatorType::LOGICAL_VACUUM: { - auto result = make_unique(unique_ptr_cast(move(op.info)), + auto result = make_unique(unique_ptr_cast(std::move(op.info)), op.estimated_cardinality); if (!op.children.empty()) { auto child = CreatePlan(*op.children[0]); - result->children.push_back(move(child)); + result->children.push_back(std::move(child)); } - return move(result); + return std::move(result); } case LogicalOperatorType::LOGICAL_LOAD: - return make_unique(unique_ptr_cast(move(op.info)), op.estimated_cardinality); + return make_unique(unique_ptr_cast(std::move(op.info)), + op.estimated_cardinality); + case LogicalOperatorType::LOGICAL_ATTACH: + return make_unique(unique_ptr_cast(std::move(op.info)), + op.estimated_cardinality); default: throw NotImplementedException("Unimplemented type for logical simple operator"); } @@ -100096,7 +106410,7 @@ namespace duckdb { class LogicalTopN : public LogicalOperator { public: LogicalTopN(vector orders, int64_t limit, int64_t offset) - : LogicalOperator(LogicalOperatorType::LOGICAL_TOP_N), orders(move(orders)), limit(limit), offset(offset) { + : LogicalOperator(LogicalOperatorType::LOGICAL_TOP_N), orders(std::move(orders)), limit(limit), offset(offset) { } vector orders; @@ -100129,9 +106443,9 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalTopN &op) auto plan = CreatePlan(*op.children[0]); auto top_n = - make_unique(op.types, move(op.orders), (idx_t)op.limit, op.offset, op.estimated_cardinality); - top_n->children.push_back(move(plan)); - return move(top_n); + make_unique(op.types, std::move(op.orders), (idx_t)op.limit, op.offset, op.estimated_cardinality); + top_n->children.push_back(std::move(plan)); + return std::move(top_n); } } // namespace duckdb @@ -100151,8 +106465,7 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalTopN &op) namespace duckdb { -//! LogicalAggregate represents an aggregate operation with (optional) GROUP BY -//! operator. +//! LogicalUnnest represents the logical UNNEST operator. class LogicalUnnest : public LogicalOperator { public: explicit LogicalUnnest(idx_t unnest_index) @@ -100178,9 +106491,9 @@ namespace duckdb { unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalUnnest &op) { D_ASSERT(op.children.size() == 1); auto plan = CreatePlan(*op.children[0]); - auto unnest = make_unique(op.types, move(op.expressions), op.estimated_cardinality); - unnest->children.push_back(move(plan)); - return move(unnest); + auto unnest = make_unique(op.types, std::move(op.expressions), op.estimated_cardinality); + unnest->children.push_back(std::move(plan)); + return std::move(unnest); } } // namespace duckdb @@ -100199,14 +106512,12 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalUnnest &op - namespace duckdb { +class TableCatalogEntry; class LogicalUpdate : public LogicalOperator { public: - explicit LogicalUpdate(TableCatalogEntry *table) - : LogicalOperator(LogicalOperatorType::LOGICAL_UPDATE), table(table), table_index(0), return_chunk(false) { - } + explicit LogicalUpdate(TableCatalogEntry *table); //! The base table to update TableCatalogEntry *table; @@ -100224,38 +106535,33 @@ class LogicalUpdate : public LogicalOperator { idx_t EstimateCardinality(ClientContext &context) override; protected: - vector GetColumnBindings() override { - if (return_chunk) { - return GenerateColumnBindings(table_index, table->GetTypes().size()); - } - return {ColumnBinding(0, 0)}; - } - - void ResolveTypes() override { - if (return_chunk) { - types = table->GetTypes(); - } else { - types.emplace_back(LogicalType::BIGINT); - } - } + vector GetColumnBindings() override; + void ResolveTypes() override; }; } // namespace duckdb + namespace duckdb { +unique_ptr DuckCatalog::PlanUpdate(ClientContext &context, LogicalUpdate &op, + unique_ptr plan) { + auto update = + make_unique(op.types, *op.table, op.table->GetStorage(), op.columns, std::move(op.expressions), + std::move(op.bound_defaults), op.estimated_cardinality, op.return_chunk); + + update->update_is_del_and_insert = op.update_is_del_and_insert; + update->children.push_back(std::move(plan)); + return std::move(update); +} + unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalUpdate &op) { D_ASSERT(op.children.size() == 1); auto plan = CreatePlan(*op.children[0]); - dependencies.insert(op.table); - auto update = make_unique(op.types, *op.table, *op.table->storage, op.columns, move(op.expressions), - move(op.bound_defaults), op.estimated_cardinality, op.return_chunk); - - update->update_is_del_and_insert = op.update_is_del_and_insert; - update->children.push_back(move(plan)); - return move(update); + dependencies.AddDependency(op.table); + return op.table->catalog->PlanUpdate(context, op, std::move(plan)); } } // namespace duckdb @@ -100337,6 +106643,8 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalWindow &op } #endif + op.estimated_cardinality = op.EstimateCardinality(context); + // Slice types auto types = op.types; const auto output_idx = types.size() - op.expressions.size(); @@ -100379,19 +106687,19 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalWindow &op // Extract the matching expressions vector> select_list; for (const auto &expr_idx : matching) { - select_list.emplace_back(move(op.expressions[expr_idx])); + select_list.emplace_back(std::move(op.expressions[expr_idx])); types.emplace_back(op.types[output_idx + expr_idx]); } // Chain the new window operator on top of the plan unique_ptr window; if (process_streaming) { - window = make_unique(types, move(select_list), op.estimated_cardinality); + window = make_unique(types, std::move(select_list), op.estimated_cardinality); } else { - window = make_unique(types, move(select_list), op.estimated_cardinality); + window = make_unique(types, std::move(select_list), op.estimated_cardinality); } - window->children.push_back(move(plan)); - plan = move(window); + window->children.push_back(std::move(plan)); + plan = std::move(window); // Remember the projection order if we changed it if (!streaming_windows.empty() || !blocking_windows.empty() || !evaluation_order.empty()) { @@ -100411,9 +106719,9 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalWindow &op const auto expr_idx = evaluation_order[i] + output_idx; select_list[expr_idx] = make_unique(op.types[expr_idx], i + output_idx); } - auto proj = make_unique(op.types, move(select_list), op.estimated_cardinality); - proj->children.push_back(move(plan)); - plan = move(proj); + auto proj = make_unique(op.types, std::move(select_list), op.estimated_cardinality); + proj->children.push_back(std::move(plan)); + plan = std::move(proj); } return plan; @@ -100432,7 +106740,7 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalWindow &op //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/planner/operator/logical_extension.operator.hpp +// duckdb/planner/operator/logical_extension_operator.hpp // // //===----------------------------------------------------------------------===// @@ -100445,11 +106753,10 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalWindow &op namespace duckdb { struct LogicalExtensionOperator : public LogicalOperator { - LogicalExtensionOperator() : LogicalOperator(LogicalOperatorType::LOGICAL_EXTENSION_OPERATOR) { } LogicalExtensionOperator(vector> expressions) - : LogicalOperator(LogicalOperatorType::LOGICAL_EXTENSION_OPERATOR, move(expressions)) { + : LogicalOperator(LogicalOperatorType::LOGICAL_EXTENSION_OPERATOR, std::move(expressions)) { } static unique_ptr Deserialize(LogicalDeserializationState &state, FieldReader &reader); @@ -100463,7 +106770,7 @@ namespace duckdb { class DependencyExtractor : public LogicalOperatorVisitor { public: - explicit DependencyExtractor(unordered_set &dependencies) : dependencies(dependencies) { + explicit DependencyExtractor(DependencyList &dependencies) : dependencies(dependencies) { } protected: @@ -100476,7 +106783,7 @@ class DependencyExtractor : public LogicalOperatorVisitor { } private: - unordered_set &dependencies; + DependencyList &dependencies; }; PhysicalPlanGenerator::PhysicalPlanGenerator(ClientContext &context) : context(context) { @@ -100571,6 +106878,9 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalOperator & case LogicalOperatorType::LOGICAL_CROSS_PRODUCT: plan = CreatePlan((LogicalCrossProduct &)op); break; + case LogicalOperatorType::LOGICAL_POSITIONAL_JOIN: + plan = CreatePlan((LogicalPositionalJoin &)op); + break; case LogicalOperatorType::LOGICAL_UNION: case LogicalOperatorType::LOGICAL_EXCEPT: case LogicalOperatorType::LOGICAL_INTERSECT: @@ -100630,6 +106940,7 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalOperator & case LogicalOperatorType::LOGICAL_DROP: case LogicalOperatorType::LOGICAL_VACUUM: case LogicalOperatorType::LOGICAL_LOAD: + case LogicalOperatorType::LOGICAL_ATTACH: plan = CreatePlan((LogicalSimple &)op); break; case LogicalOperatorType::LOGICAL_RECURSIVE_CTE: @@ -100644,6 +106955,9 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalOperator & case LogicalOperatorType::LOGICAL_SET: plan = CreatePlan((LogicalSet &)op); break; + case LogicalOperatorType::LOGICAL_RESET: + plan = CreatePlan((LogicalReset &)op); + break; case LogicalOperatorType::LOGICAL_EXTENSION_OPERATOR: plan = ((LogicalExtensionOperator &)op).CreatePlan(context, *this); @@ -100651,7 +106965,8 @@ unique_ptr PhysicalPlanGenerator::CreatePlan(LogicalOperator & throw InternalException("Missing PhysicalOperator for Extension Operator"); } break; - default: { + case LogicalOperatorType::LOGICAL_JOIN: + case LogicalOperatorType::LOGICAL_INVALID: { throw NotImplementedException("Unimplemented logical operator type!"); } } @@ -100865,7 +107180,7 @@ void RadixPartitionedHashTable::Combine(ExecutionContext &context, GlobalSinkSta llstate.ht->Finalize(); // at this point we just collect them the PhysicalHashAggregateFinalizeTask (below) will merge them in parallel - gstate.intermediate_hts.push_back(move(llstate.ht)); + gstate.intermediate_hts.push_back(std::move(llstate.ht)); } bool RadixPartitionedHashTable::Finalize(ClientContext &context, GlobalSinkState &gstate_p) const { @@ -100936,7 +107251,7 @@ class RadixAggregateFinalizeTask : public ExecutorTask { public: RadixAggregateFinalizeTask(Executor &executor, shared_ptr event_p, RadixHTGlobalState &state_p, idx_t radix_p) - : ExecutorTask(executor), event(move(event_p)), state(state_p), radix(radix_p) { + : ExecutorTask(executor), event(std::move(event_p)), state(state_p), radix(radix_p) { } static void FinalizeHT(RadixHTGlobalState &gstate, idx_t radix) { @@ -101273,7 +107588,7 @@ void ReservoirSamplePercentage::AddToReservoir(DataChunk &input) { input.Slice(sel, append_to_next_sample); } // now our first sample is filled: append it to the set of finished samples - finished_samples.push_back(move(current_sample)); + finished_samples.push_back(std::move(current_sample)); // allocate a new sample, and potentially add the remainder of the current input to that sample current_sample = make_unique(allocator, reservoir_sample_size, random.NextRandomInteger()); @@ -101317,7 +107632,7 @@ void ReservoirSamplePercentage::Finalize() { } new_sample->AddToReservoir(*chunk); } - finished_samples.push_back(move(new_sample)); + finished_samples.push_back(std::move(new_sample)); } is_finalized = true; } @@ -101478,7 +107793,7 @@ void WindowSegmentTree::ExtractFrame(idx_t begin, idx_t end) { void WindowSegmentTree::WindowSegmentValue(idx_t l_idx, idx_t begin, idx_t end) { D_ASSERT(begin <= end); - if (begin == end) { + if (begin == end || inputs.ColumnCount() == 0) { return; } @@ -101487,6 +107802,7 @@ void WindowSegmentTree::WindowSegmentValue(idx_t l_idx, idx_t begin, idx_t end) if (l_idx == 0) { ExtractFrame(begin, end); AggregateInputData aggr_input_data(bind_info, Allocator::DefaultAllocator()); + D_ASSERT(inputs.data.size() > 0); aggregate.update(&inputs.data[0], aggr_input_data, input_ref->ColumnCount(), s, inputs.size()); } else { // find out where the states begin @@ -101547,23 +107863,6 @@ void WindowSegmentTree::ConstructTree() { void WindowSegmentTree::Compute(Vector &result, idx_t rid, idx_t begin, idx_t end) { D_ASSERT(input_ref); - // No arguments, so just count - if (inputs.ColumnCount() == 0) { - D_ASSERT(GetTypeIdSize(result_type.InternalType()) == sizeof(idx_t)); - auto data = FlatVector::GetData(result); - // Slice to any filtered rows - if (!filter_mask.AllValid()) { - idx_t filtered = 0; - for (idx_t i = begin; i < end; ++i) { - filtered += filter_mask.RowIsValid(i); - } - data[rid] = filtered; - } else { - data[rid] = end - begin; - } - return; - } - // If we have a window function, use that if (aggregate.window && UseWindowAPI()) { // Frame boundaries @@ -101622,6 +107921,7 @@ void WindowSegmentTree::Compute(Vector &result, idx_t rid, idx_t begin, idx_t en + namespace duckdb { struct AvgFun { @@ -102567,8 +108867,8 @@ static void ApproxCountDistinctUpdateFunction(Vector inputs[], AggregateInputDat state_vector.ToUnifiedFormat(count, sdata); auto states = (ApproxDistinctCountState **)sdata.data; - uint64_t *indices; - uint8_t *counts; + uint64_t *indices = nullptr; + uint8_t *counts = nullptr; for (idx_t i = 0; i < count; i++) { auto agg_state = states[sdata.sel->get_index(i)]; if (!agg_state->log) { @@ -102629,33 +108929,54 @@ void ApproxCountDistinctFun::RegisterFunction(BuiltinFunctions &set) { namespace duckdb { -template -struct ArgMinMaxState { - T arg; - T2 value; +struct ArgMinMaxStateBase { + ArgMinMaxStateBase() : is_initialized(false) { + } + + template + static inline void CreateValue(T &value) { + } + + template + static inline void DestroyValue(T &value) { + } + + template + static inline void AssignValue(T &target, T new_value, bool is_initialized) { + target = new_value; + } + + template + static inline void ReadValue(Vector &result, T &arg, T *target, idx_t idx) { + target[idx] = arg; + } + bool is_initialized; }; -template -static void ArgMinMaxDestroyValue(T value) { +// Out-of-line specialisations +template <> +void ArgMinMaxStateBase::CreateValue(Vector *&value) { + value = nullptr; } template <> -void ArgMinMaxDestroyValue(string_t value) { +void ArgMinMaxStateBase::DestroyValue(string_t &value) { if (!value.IsInlined()) { delete[] value.GetDataUnsafe(); } } -template -static void ArgMinMaxAssignValue(T &target, T new_value, bool is_initialized) { - target = new_value; +template <> +void ArgMinMaxStateBase::DestroyValue(Vector *&value) { + delete value; + value = nullptr; } template <> -void ArgMinMaxAssignValue(string_t &target, string_t new_value, bool is_initialized) { +void ArgMinMaxStateBase::AssignValue(string_t &target, string_t new_value, bool is_initialized) { if (is_initialized) { - ArgMinMaxDestroyValue(target); + DestroyValue(target); } if (new_value.IsInlined()) { target = new_value; @@ -102669,27 +108990,51 @@ void ArgMinMaxAssignValue(string_t &target, string_t new_value, bool is_initiali } } +template <> +void ArgMinMaxStateBase::ReadValue(Vector &result, string_t &arg, string_t *target, idx_t idx) { + target[idx] = StringVector::AddStringOrBlob(result, arg); +} + +template +struct ArgMinMaxState : public ArgMinMaxStateBase { + using ARG_TYPE = A; + using BY_TYPE = B; + + ARG_TYPE arg; + BY_TYPE value; + + ArgMinMaxState() { + CreateValue(arg); + CreateValue(value); + } + + ~ArgMinMaxState() { + if (is_initialized) { + DestroyValue(arg); + DestroyValue(value); + is_initialized = false; + } + } +}; + template struct ArgMinMaxBase { template static void Destroy(STATE *state) { - if (state->is_initialized) { - ArgMinMaxDestroyValue(state->arg); - ArgMinMaxDestroyValue(state->value); - } + state->~STATE(); } template static void Initialize(STATE *state) { - state->is_initialized = false; + new (state) STATE; } template static void Operation(STATE *state, AggregateInputData &, A_TYPE *x_data, B_TYPE *y_data, ValidityMask &amask, ValidityMask &bmask, idx_t xidx, idx_t yidx) { if (!state->is_initialized) { - ArgMinMaxAssignValue(state->arg, x_data[xidx], false); - ArgMinMaxAssignValue(state->value, y_data[yidx], false); + STATE::template AssignValue(state->arg, x_data[xidx], false); + STATE::template AssignValue(state->value, y_data[yidx], false); state->is_initialized = true; } else { OP::template Execute(state, x_data[xidx], y_data[yidx]); @@ -102699,8 +109044,8 @@ struct ArgMinMaxBase { template static void Execute(STATE *state, A_TYPE x_data, B_TYPE y_data) { if (COMPARATOR::Operation(y_data, state->value)) { - ArgMinMaxAssignValue(state->arg, x_data, true); - ArgMinMaxAssignValue(state->value, y_data, true); + STATE::template AssignValue(state->arg, x_data, true); + STATE::template AssignValue(state->value, y_data, true); } } @@ -102710,97 +109055,212 @@ struct ArgMinMaxBase { return; } if (!target->is_initialized || COMPARATOR::Operation(source.value, target->value)) { - ArgMinMaxAssignValue(target->arg, source.arg, target->is_initialized); - ArgMinMaxAssignValue(target->value, source.value, target->is_initialized); + STATE::template AssignValue(target->arg, source.arg, target->is_initialized); + STATE::template AssignValue(target->value, source.value, target->is_initialized); target->is_initialized = true; } } - static bool IgnoreNull() { - return true; - } -}; - -template -struct StringArgMinMax : public ArgMinMaxBase { template static void Finalize(Vector &result, AggregateInputData &, STATE *state, T *target, ValidityMask &mask, idx_t idx) { if (!state->is_initialized) { mask.SetInvalid(idx); } else { - target[idx] = StringVector::AddStringOrBlob(result, state->arg); + STATE::template ReadValue(result, state->arg, target, idx); } } + + static bool IgnoreNull() { + return true; + } }; -template -struct NumericArgMinMax : public ArgMinMaxBase { +template +struct VectorArgMinMaxBase : ArgMinMaxBase { + template + static void AssignVector(STATE *state, Vector &arg, const idx_t idx) { + if (!state->is_initialized) { + state->arg = new Vector(arg.GetType()); + state->arg->SetVectorType(VectorType::CONSTANT_VECTOR); + } + sel_t selv = idx; + SelectionVector sel(&selv); + VectorOperations::Copy(arg, *state->arg, sel, 1, 0, 0); + } + + template + static void Update(Vector inputs[], AggregateInputData &, idx_t input_count, Vector &state_vector, idx_t count) { + auto &arg = inputs[0]; + UnifiedVectorFormat adata; + arg.ToUnifiedFormat(count, adata); + + using BY_TYPE = typename STATE::BY_TYPE; + auto &by = inputs[1]; + UnifiedVectorFormat bdata; + by.ToUnifiedFormat(count, bdata); + const auto bys = (BY_TYPE *)bdata.data; + + UnifiedVectorFormat sdata; + state_vector.ToUnifiedFormat(count, sdata); + + auto states = (STATE **)sdata.data; + for (idx_t i = 0; i < count; i++) { + const auto bidx = bdata.sel->get_index(i); + if (!bdata.validity.RowIsValid(bidx)) { + continue; + } + const auto bval = bys[bidx]; + + const auto sidx = sdata.sel->get_index(i); + auto state = states[sidx]; + if (!state->is_initialized) { + STATE::template AssignValue(state->value, bval, false); + AssignVector(state, arg, i); + state->is_initialized = true; + + } else if (COMPARATOR::template Operation(bval, state->value)) { + STATE::template AssignValue(state->value, bval, true); + AssignVector(state, arg, i); + } + } + } + + template + static void Combine(const STATE &source, STATE *target, AggregateInputData &) { + if (!source.is_initialized) { + return; + } + if (!target->is_initialized || COMPARATOR::Operation(source.value, target->value)) { + STATE::template AssignValue(target->value, source.value, target->is_initialized); + AssignVector(target, *source.arg, 0); + target->is_initialized = true; + } + } + template static void Finalize(Vector &result, AggregateInputData &, STATE *state, T *target, ValidityMask &mask, idx_t idx) { if (!state->is_initialized) { - mask.SetInvalid(idx); + // we need to use SetNull here + // since for STRUCT columns only setting the validity mask of the struct is incorrect + // as for a struct column, we need to also set ALL child columns to NULL + switch (result.GetVectorType()) { + case VectorType::FLAT_VECTOR: + FlatVector::SetNull(result, idx, true); + break; + case VectorType::CONSTANT_VECTOR: + ConstantVector::SetNull(result, true); + break; + default: + throw InternalException("Invalid result vector type for nested arg_min/max"); + } } else { - target[idx] = state->arg; + VectorOperations::Copy(*state->arg, result, 1, 0, idx); } } + + static unique_ptr Bind(ClientContext &context, AggregateFunction &function, + vector> &arguments) { + function.arguments[0] = arguments[0]->return_type; + function.return_type = arguments[0]->return_type; + return nullptr; + } }; -using NumericArgMinOperation = NumericArgMinMax; -using NumericArgMaxOperation = NumericArgMinMax; -using StringArgMinOperation = StringArgMinMax; -using StringArgMaxOperation = StringArgMinMax; +template +AggregateFunction GetVectorArgMinMaxFunctionInternal(const LogicalType &by_type, const LogicalType &type) { + using STATE = ArgMinMaxState; + return AggregateFunction({type, by_type}, type, AggregateFunction::StateSize, + AggregateFunction::StateInitialize, OP::template Update, + AggregateFunction::StateCombine, + AggregateFunction::StateFinalize, nullptr, OP::Bind, + AggregateFunction::StateDestroy); +} + +template +AggregateFunction GetVectorArgMinMaxFunctionBy(const LogicalType &by_type, const LogicalType &type) { + switch (by_type.InternalType()) { + case PhysicalType::INT32: + return GetVectorArgMinMaxFunctionInternal(by_type, type); + case PhysicalType::INT64: + return GetVectorArgMinMaxFunctionInternal(by_type, type); + case PhysicalType::DOUBLE: + return GetVectorArgMinMaxFunctionInternal(by_type, type); + case PhysicalType::VARCHAR: + return GetVectorArgMinMaxFunctionInternal(by_type, type); + default: + throw InternalException("Unimplemented arg_min/arg_max aggregate"); + } +} + +template +void AddVectorArgMinMaxFunctionBy(AggregateFunctionSet &fun, const LogicalType &type) { + fun.AddFunction(GetVectorArgMinMaxFunctionBy(LogicalType::INTEGER, type)); + fun.AddFunction(GetVectorArgMinMaxFunctionBy(LogicalType::BIGINT, type)); + fun.AddFunction(GetVectorArgMinMaxFunctionBy(LogicalType::DOUBLE, type)); + fun.AddFunction(GetVectorArgMinMaxFunctionBy(LogicalType::VARCHAR, type)); + fun.AddFunction(GetVectorArgMinMaxFunctionBy(LogicalType::DATE, type)); + fun.AddFunction(GetVectorArgMinMaxFunctionBy(LogicalType::TIMESTAMP, type)); + fun.AddFunction(GetVectorArgMinMaxFunctionBy(LogicalType::TIMESTAMP_TZ, type)); + fun.AddFunction(GetVectorArgMinMaxFunctionBy(LogicalType::BLOB, type)); +} -template -AggregateFunction GetArgMinMaxFunctionInternal(const LogicalType &arg_2, const LogicalType &arg) { - auto function = AggregateFunction::BinaryAggregate, T, T2, T, OP>(arg, arg_2, arg); - if (arg.InternalType() == PhysicalType::VARCHAR || arg_2.InternalType() == PhysicalType::VARCHAR) { - function.destructor = AggregateFunction::StateDestroy, OP>; +template +AggregateFunction GetArgMinMaxFunctionInternal(const LogicalType &by_type, const LogicalType &type) { + using STATE = ArgMinMaxState; + auto function = AggregateFunction::BinaryAggregate(type, by_type, type); + if (type.InternalType() == PhysicalType::VARCHAR || by_type.InternalType() == PhysicalType::VARCHAR) { + function.destructor = AggregateFunction::StateDestroy; } return function; } -template -AggregateFunction GetArgMinMaxFunctionArg2(const LogicalType &arg_2, const LogicalType &arg) { - switch (arg_2.InternalType()) { + +template +AggregateFunction GetArgMinMaxFunctionBy(const LogicalType &by_type, const LogicalType &type) { + switch (by_type.InternalType()) { case PhysicalType::INT32: - return GetArgMinMaxFunctionInternal(arg_2, arg); + return GetArgMinMaxFunctionInternal(by_type, type); case PhysicalType::INT64: - return GetArgMinMaxFunctionInternal(arg_2, arg); + return GetArgMinMaxFunctionInternal(by_type, type); case PhysicalType::DOUBLE: - return GetArgMinMaxFunctionInternal(arg_2, arg); + return GetArgMinMaxFunctionInternal(by_type, type); case PhysicalType::VARCHAR: - return GetArgMinMaxFunctionInternal(arg_2, arg); + return GetArgMinMaxFunctionInternal(by_type, type); default: throw InternalException("Unimplemented arg_min/arg_max aggregate"); } } -template -void AddArgMinMaxFunctionArg2(AggregateFunctionSet &fun, const LogicalType &arg) { - fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalType::INTEGER, arg)); - fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalType::BIGINT, arg)); - fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalType::DOUBLE, arg)); - fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalType::VARCHAR, arg)); - fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalType::DATE, arg)); - fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalType::TIMESTAMP, arg)); - fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalType::TIMESTAMP_TZ, arg)); - fun.AddFunction(GetArgMinMaxFunctionArg2(LogicalType::BLOB, arg)); -} - -template +template +void AddArgMinMaxFunctionBy(AggregateFunctionSet &fun, const LogicalType &type) { + fun.AddFunction(GetArgMinMaxFunctionBy(LogicalType::INTEGER, type)); + fun.AddFunction(GetArgMinMaxFunctionBy(LogicalType::BIGINT, type)); + fun.AddFunction(GetArgMinMaxFunctionBy(LogicalType::DOUBLE, type)); + fun.AddFunction(GetArgMinMaxFunctionBy(LogicalType::VARCHAR, type)); + fun.AddFunction(GetArgMinMaxFunctionBy(LogicalType::DATE, type)); + fun.AddFunction(GetArgMinMaxFunctionBy(LogicalType::TIMESTAMP, type)); + fun.AddFunction(GetArgMinMaxFunctionBy(LogicalType::TIMESTAMP_TZ, type)); + fun.AddFunction(GetArgMinMaxFunctionBy(LogicalType::BLOB, type)); +} + +template static void AddArgMinMaxFunctions(AggregateFunctionSet &fun) { - AddArgMinMaxFunctionArg2(fun, LogicalType::INTEGER); - AddArgMinMaxFunctionArg2(fun, LogicalType::BIGINT); - AddArgMinMaxFunctionArg2(fun, LogicalType::DOUBLE); - AddArgMinMaxFunctionArg2(fun, LogicalType::VARCHAR); - AddArgMinMaxFunctionArg2(fun, LogicalType::DATE); - AddArgMinMaxFunctionArg2(fun, LogicalType::TIMESTAMP); - AddArgMinMaxFunctionArg2(fun, LogicalType::TIMESTAMP_TZ); - AddArgMinMaxFunctionArg2(fun, LogicalType::BLOB); + using OP = ArgMinMaxBase; + AddArgMinMaxFunctionBy(fun, LogicalType::INTEGER); + AddArgMinMaxFunctionBy(fun, LogicalType::BIGINT); + AddArgMinMaxFunctionBy(fun, LogicalType::DOUBLE); + AddArgMinMaxFunctionBy(fun, LogicalType::VARCHAR); + AddArgMinMaxFunctionBy(fun, LogicalType::DATE); + AddArgMinMaxFunctionBy(fun, LogicalType::TIMESTAMP); + AddArgMinMaxFunctionBy(fun, LogicalType::TIMESTAMP_TZ); + AddArgMinMaxFunctionBy(fun, LogicalType::BLOB); + + using VECTOR_OP = VectorArgMinMaxBase; + AddVectorArgMinMaxFunctionBy(fun, LogicalType::ANY); } void ArgMinFun::RegisterFunction(BuiltinFunctions &set) { AggregateFunctionSet fun("argmin"); - AddArgMinMaxFunctions(fun); + AddArgMinMaxFunctions(fun); set.AddFunction(fun); //! Add min_by alias @@ -102814,7 +109274,7 @@ void ArgMinFun::RegisterFunction(BuiltinFunctions &set) { void ArgMaxFun::RegisterFunction(BuiltinFunctions &set) { AggregateFunctionSet fun("argmax"); - AddArgMinMaxFunctions(fun); + AddArgMinMaxFunctions(fun); set.AddFunction(fun); //! Add max_by alias @@ -103206,6 +109666,26 @@ struct CountStarFunction : public BaseCountFunction { static void ConstantOperation(STATE *state, AggregateInputData &, idx_t count) { *state += count; } + + template + static void Window(Vector inputs[], const ValidityMask &filter_mask, AggregateInputData &aggr_input_data, + idx_t input_count, data_ptr_t state, const FrameBounds &frame, const FrameBounds &prev, + Vector &result, idx_t rid, idx_t bias) { + D_ASSERT(input_count == 0); + auto data = FlatVector::GetData(result); + const auto begin = frame.first; + const auto end = frame.second; + // Slice to any filtered rows + if (!filter_mask.AllValid()) { + RESULT_TYPE filtered = 0; + for (auto i = begin; i < end; ++i) { + filtered += filter_mask.RowIsValid(i); + } + data[rid] = filtered; + } else { + data[rid] = end - begin; + } + } }; struct CountFunction : public BaseCountFunction { @@ -103245,6 +109725,7 @@ AggregateFunction CountStarFun::GetFunction() { auto fun = AggregateFunction::NullaryAggregate(LogicalType::BIGINT); fun.name = "count_star"; fun.null_handling = FunctionNullHandling::SPECIAL_HANDLING; + fun.window = CountStarFunction::Window; // TODO is there a better way to set those? fun.serialize = CountStarSerialize; fun.deserialize = CountStarDeserialize; @@ -103271,6 +109752,7 @@ void CountFun::RegisterFunction(BuiltinFunctions &set) { // the count function can also be called without arguments count_function.arguments.clear(); count_function.statistics = nullptr; + count_function.window = CountStarFunction::Window; count.AddFunction(count_function); set.AddFunction(count); } @@ -103785,9 +110267,9 @@ template unique_ptr BindFirst(ClientContext &context, AggregateFunction &function, vector> &arguments) { auto input_type = arguments[0]->return_type; - auto name = move(function.name); + auto name = std::move(function.name); function = GetFirstOperator(input_type); - function.name = move(name); + function.name = std::move(name); if (function.bind) { return function.bind(context, function, arguments); } else { @@ -104186,7 +110668,6 @@ static bool TemplatedOptimumValue(Vector &left, idx_t lidx, idx_t lcount, Vector return TemplatedOptimumType(left, lidx, lcount, right, ridx, rcount); case PhysicalType::LIST: return TemplatedOptimumList(left, lidx, lcount, right, ridx, rcount); - case PhysicalType::MAP: case PhysicalType::STRUCT: return TemplatedOptimumStruct(left, lidx, lcount, right, ridx, rcount); default: @@ -104430,7 +110911,7 @@ unique_ptr BindDecimalMinMax(ClientContext &context, AggregateFunc function = GetUnaryAggregate(LogicalType::HUGEINT); break; } - function.name = move(name); + function.name = std::move(name); function.arguments[0] = decimal_type; function.return_type = decimal_type; return nullptr; @@ -104461,9 +110942,9 @@ template unique_ptr BindMinMax(ClientContext &context, AggregateFunction &function, vector> &arguments) { auto input_type = arguments[0]->return_type; - auto name = move(function.name); + auto name = std::move(function.name); function = GetMinMaxOperator(input_type); - function.name = move(name); + function.name = std::move(name); if (function.bind) { return function.bind(context, function, arguments); } else { @@ -104665,7 +111146,7 @@ struct StringAggState { }; struct StringAggBindData : public FunctionData { - explicit StringAggBindData(string sep_p) : sep(move(sep_p)) { + explicit StringAggBindData(string sep_p) : sep(std::move(sep_p)) { } string sep; @@ -104797,7 +111278,7 @@ static void StringAggSerialize(FieldWriter &writer, const FunctionData *bind_dat unique_ptr StringAggDeserialize(ClientContext &context, FieldReader &reader, AggregateFunction &bound_function) { auto sep = reader.ReadRequired(); - return make_unique(move(sep)); + return make_unique(std::move(sep)); } void StringAggFun::RegisterFunction(BuiltinFunctions &set) { @@ -105088,6 +111569,7 @@ void BuiltinFunctions::RegisterDistributiveAggregates() { + namespace duckdb { struct QuantileFun { @@ -105803,7 +112285,7 @@ struct ApproximateQuantileBindData : public FunctionData { explicit ApproximateQuantileBindData(float quantile_p) : quantiles(1, quantile_p) { } - explicit ApproximateQuantileBindData(vector quantiles_p) : quantiles(move(quantiles_p)) { + explicit ApproximateQuantileBindData(vector quantiles_p) : quantiles(std::move(quantiles_p)) { } unique_ptr Copy() const override { @@ -105828,7 +112310,7 @@ struct ApproximateQuantileBindData : public FunctionData { static unique_ptr Deserialize(ClientContext &context, FieldReader &reader, AggregateFunction &bound_function) { auto quantiles = reader.ReadRequiredList(); - return make_unique(move(quantiles)); + return make_unique(std::move(quantiles)); } vector quantiles; @@ -106593,6 +113075,7 @@ inline interval_t TryAbsOperator::Operation(interval_t input) { + #include #include #include @@ -106606,7 +113089,7 @@ static hugeint_t operator*(const hugeint_t &h, const double &d) { } // Interval arithmetic -static interval_t operator*(const interval_t &i, const double &d) { +static interval_t operator*(const interval_t &i, const double &d) { // NOLINT D_ASSERT(d >= 0 && d <= 1); return Interval::FromMicro(std::llround(Interval::GetMicro(i) * d)); } @@ -106846,28 +113329,33 @@ struct QuantileComposed { // Accessed comparison template -struct QuantileLess { +struct QuantileCompare { using INPUT_TYPE = typename ACCESSOR::INPUT_TYPE; const ACCESSOR &accessor; - explicit QuantileLess(const ACCESSOR &accessor_p) : accessor(accessor_p) { + const bool desc; + explicit QuantileCompare(const ACCESSOR &accessor_p, bool desc_p) : accessor(accessor_p), desc(desc_p) { } inline bool operator()(const INPUT_TYPE &lhs, const INPUT_TYPE &rhs) const { - return accessor(lhs) < accessor(rhs); + const auto lval = accessor(lhs); + const auto rval = accessor(rhs); + + return desc ? (rval < lval) : (lval < rval); } }; // Continuous interpolation template struct Interpolator { - Interpolator(const double q, const idx_t n_p) - : n(n_p), RN((double)(n_p - 1) * q), FRN(floor(RN)), CRN(ceil(RN)), begin(0), end(n_p) { + Interpolator(const Value &q, const idx_t n_p, const bool desc_p) + : desc(desc_p), RN((double)(n_p - 1) * q.GetValue()), FRN(floor(RN)), CRN(ceil(RN)), begin(0), + end(n_p) { } template > TARGET_TYPE Operation(INPUT_TYPE *v_t, Vector &result, const ACCESSOR &accessor = ACCESSOR()) const { using ACCESS_TYPE = typename ACCESSOR::RESULT_TYPE; - QuantileLess comp(accessor); + QuantileCompare comp(accessor, desc); if (CRN == FRN) { std::nth_element(v_t + begin, v_t + FRN, v_t + end, comp); return CastInterpolation::Cast(accessor(v_t[FRN]), result); @@ -106892,7 +113380,7 @@ struct Interpolator { } } - const idx_t n; + const bool desc; const double RN; const idx_t FRN; const idx_t CRN; @@ -106904,15 +113392,36 @@ struct Interpolator { // Discrete "interpolation" template <> struct Interpolator { - Interpolator(const double q, const idx_t n_p) - : n(n_p), RN((double)(n_p * q)), FRN(MaxValue(1, n_p - floor(n_p - RN)) - 1), CRN(FRN), begin(0), - end(n_p) { + static inline idx_t Index(const Value &q, const idx_t n) { + idx_t floored; + const auto &type = q.type(); + switch (type.id()) { + case LogicalTypeId::DECIMAL: { + // Integer arithmetic for accuracy + const auto integral = IntegralValue::Get(q); + const auto scaling = Hugeint::POWERS_OF_TEN[DecimalType::GetScale(type)]; + const auto scaled_q = DecimalMultiplyOverflowCheck::Operation(n, integral); + const auto scaled_n = DecimalMultiplyOverflowCheck::Operation(n, scaling); + floored = Cast::Operation((scaled_n - scaled_q) / scaling); + break; + } + default: + const auto scaled_q = (double)(n * q.GetValue()); + floored = floor(n - scaled_q); + break; + } + + return MaxValue(1, n - floored) - 1; + } + + Interpolator(const Value &q, const idx_t n_p, bool desc_p) + : desc(desc_p), FRN(Index(q, n_p)), CRN(FRN), begin(0), end(n_p) { } template > TARGET_TYPE Operation(INPUT_TYPE *v_t, Vector &result, const ACCESSOR &accessor = ACCESSOR()) const { using ACCESS_TYPE = typename ACCESSOR::RESULT_TYPE; - QuantileLess comp(accessor); + QuantileCompare comp(accessor, desc); std::nth_element(v_t + begin, v_t + FRN, v_t + end, comp); return CastInterpolation::Cast(accessor(v_t[FRN]), result); } @@ -106923,8 +113432,7 @@ struct Interpolator { return CastInterpolation::Cast(accessor(v_t[FRN]), result); } - const idx_t n; - const double RN; + const bool desc; const idx_t FRN; const idx_t CRN; @@ -106932,30 +113440,80 @@ struct Interpolator { idx_t end; }; +template +static inline T QuantileAbs(const T &t) { + return AbsOperator::Operation(t); +} + +template <> +inline Value QuantileAbs(const Value &v) { + const auto &type = v.type(); + switch (type.id()) { + case LogicalTypeId::DECIMAL: { + const auto integral = IntegralValue::Get(v); + const auto width = DecimalType::GetWidth(type); + const auto scale = DecimalType::GetScale(type); + switch (type.InternalType()) { + case PhysicalType::INT16: + return Value::DECIMAL(QuantileAbs(Cast::Operation(integral)), width, scale); + case PhysicalType::INT32: + return Value::DECIMAL(QuantileAbs(Cast::Operation(integral)), width, scale); + case PhysicalType::INT64: + return Value::DECIMAL(QuantileAbs(Cast::Operation(integral)), width, scale); + case PhysicalType::INT128: + return Value::DECIMAL(QuantileAbs(integral), width, scale); + default: + throw InternalException("Unknown DECIMAL type"); + } + } + default: + return Value::DOUBLE(QuantileAbs(v.GetValue())); + } +} + struct QuantileBindData : public FunctionData { - explicit QuantileBindData(double quantile_p) : quantiles(1, quantile_p), order(1, 0) { + + explicit QuantileBindData(const Value &quantile_p) + : quantiles(1, QuantileAbs(quantile_p)), order(1, 0), desc(quantile_p < 0) { } - explicit QuantileBindData(const vector &quantiles_p) : quantiles(quantiles_p) { - for (idx_t i = 0; i < quantiles.size(); ++i) { + explicit QuantileBindData(const vector &quantiles_p) { + size_t pos = 0; + size_t neg = 0; + for (idx_t i = 0; i < quantiles_p.size(); ++i) { + const auto q = quantiles_p[i]; + pos += (q > 0); + neg += (q < 0); + quantiles.emplace_back(QuantileAbs(q)); order.push_back(i); } + if (pos && neg) { + throw BinderException("QUANTILE parameters must have consistent signs"); + } + desc = (neg > 0); - IndirectLess lt(quantiles.data()); + IndirectLess lt(quantiles.data()); std::sort(order.begin(), order.end(), lt); } + QuantileBindData(const QuantileBindData &other) : order(other.order), desc(other.desc) { + for (const auto &q : other.quantiles) { + quantiles.emplace_back(q); + } + } + unique_ptr Copy() const override { - return make_unique(quantiles); + return make_unique(*this); } bool Equals(const FunctionData &other_p) const override { auto &other = (QuantileBindData &)other_p; - return quantiles == other.quantiles && order == other.order; + return desc == other.desc && quantiles == other.quantiles && order == other.order; } - vector quantiles; + vector quantiles; vector order; + bool desc; }; struct QuantileOperation { @@ -107051,7 +113609,7 @@ struct QuantileScalarOperation : public QuantileOperation { D_ASSERT(aggr_input_data.bind_data); auto bind_data = (QuantileBindData *)aggr_input_data.bind_data; D_ASSERT(bind_data->quantiles.size() == 1); - Interpolator interp(bind_data->quantiles[0], state->v.size()); + Interpolator interp(bind_data->quantiles[0], state->v.size(), bind_data->desc); target[idx] = interp.template Operation(state->v.data(), result); } @@ -107083,7 +113641,7 @@ struct QuantileScalarOperation : public QuantileOperation { const auto j = ReplaceIndex(index, frame, prev); // We can only replace if the number of NULLs has not changed if (included.AllValid() || included(prev.first) == included(prev.second)) { - Interpolator interp(q, prev_pos); + Interpolator interp(q, prev_pos, false); replace = CanReplace(index, data, j, interp.FRN, interp.CRN, included); if (replace) { state->pos = prev_pos; @@ -107098,7 +113656,7 @@ struct QuantileScalarOperation : public QuantileOperation { state->pos = std::partition(index, index + state->pos, included) - index; } if (state->pos) { - Interpolator interp(q, state->pos); + Interpolator interp(q, state->pos, false); using ID = QuantileIndirect; ID indirect(data); @@ -107194,7 +113752,7 @@ struct QuantileListOperation : public QuantileOperation { idx_t lower = 0; for (const auto &q : bind_data->order) { const auto &quantile = bind_data->quantiles[q]; - Interpolator interp(quantile, state->v.size()); + Interpolator interp(quantile, state->v.size(), bind_data->desc); interp.begin = lower; rdata[ridx + q] = interp.template Operation(v_t, result); lower = interp.FRN; @@ -107245,7 +113803,7 @@ struct QuantileListOperation : public QuantileOperation { if (included.AllValid() || included(prev.first) == included(prev.second)) { for (const auto &q : bind_data->order) { const auto &quantile = bind_data->quantiles[q]; - Interpolator interp(quantile, prev_pos); + Interpolator interp(quantile, prev_pos, false); const auto replace = CanReplace(index, data, j, interp.FRN, interp.CRN, included); if (replace < 0) { // Replacement is before this quantile, so the rest will be replaceable too. @@ -107276,7 +113834,7 @@ struct QuantileListOperation : public QuantileOperation { ID indirect(data); for (const auto &q : bind_data->order) { const auto &quantile = bind_data->quantiles[q]; - Interpolator interp(quantile, state->pos); + Interpolator interp(quantile, state->pos, false); if (replaceable.first <= interp.FRN && interp.CRN <= replaceable.second) { rdata[lentry.offset + q] = interp.template Replace(index, result, indirect); } else { @@ -107549,7 +114107,7 @@ struct MedianAbsoluteDeviationOperation : public QuantileOperation { return; } using SAVE_TYPE = typename STATE::SaveType; - Interpolator interp(0.5, state->v.size()); + Interpolator interp(0.5, state->v.size(), false); const auto med = interp.template Operation(state->v.data(), result); MadAccessor accessor(med); @@ -107595,7 +114153,7 @@ struct MedianAbsoluteDeviationOperation : public QuantileOperation { const auto j = ReplaceIndex(index, frame, prev); // We can only replace if the number of NULLs has not changed if (included.AllValid() || included(prev.first) == included(prev.second)) { - Interpolator interp(q, prev_pos); + Interpolator interp(q, prev_pos, false); replace = CanReplace(index, data, j, interp.FRN, interp.CRN, included); if (replace) { state->pos = prev_pos; @@ -107611,7 +114169,7 @@ struct MedianAbsoluteDeviationOperation : public QuantileOperation { } if (state->pos) { - Interpolator interp(q, state->pos); + Interpolator interp(q, state->pos, false); // Compute or replace median from the first index using ID = QuantileIndirect; @@ -107685,18 +114243,18 @@ static void QuantileSerialize(FieldWriter &writer, const FunctionData *bind_data throw NotImplementedException("FIXME: serializing quantiles is not supported right now"); // // auto bind_data = (QuantileBindData *)bind_data_p; - // writer.WriteList(bind_data->quantiles); + // writer.WriteList(bind_data->quantiles); } unique_ptr QuantileDeserialize(ClientContext &context, FieldReader &reader, AggregateFunction &bound_function) { - auto quantiles = reader.ReadRequiredList(); - return make_unique(move(quantiles)); + auto quantiles = reader.ReadRequiredList(); + return make_unique(std::move(quantiles)); } unique_ptr BindMedian(ClientContext &context, AggregateFunction &function, vector> &arguments) { - return make_unique(0.5); + return make_unique(Value::DECIMAL(int16_t(5), 2, 1)); } unique_ptr BindMedianDecimal(ClientContext &context, AggregateFunction &function, @@ -107717,16 +114275,19 @@ unique_ptr BindMedianAbsoluteDeviationDecimal(ClientContext &conte return nullptr; } -static double CheckQuantile(const Value &quantile_val) { +static const Value &CheckQuantile(const Value &quantile_val) { if (quantile_val.IsNull()) { throw BinderException("QUANTILE parameter cannot be NULL"); } auto quantile = quantile_val.GetValue(); - if (quantile < 0 || quantile > 1) { - throw BinderException("QUANTILE can only take parameters in the range [0, 1]"); + if (quantile < -1 || quantile > 1) { + throw BinderException("QUANTILE can only take parameters in the range [-1, 1]"); + } + if (Value::IsNan(quantile)) { + throw BinderException("QUANTILE parameter cannot be NaN"); } - return quantile; + return quantile_val; } unique_ptr BindQuantile(ClientContext &context, AggregateFunction &function, @@ -107738,7 +114299,7 @@ unique_ptr BindQuantile(ClientContext &context, AggregateFunction throw BinderException("QUANTILE can only take constant parameters"); } Value quantile_val = ExpressionExecutor::EvaluateScalar(context, *arguments[1]); - vector quantiles; + vector quantiles; if (quantile_val.type().id() != LogicalTypeId::LIST) { quantiles.push_back(CheckQuantile(quantile_val)); } else { @@ -107976,7 +114537,7 @@ struct ReservoirQuantileBindData : public FunctionData { } ReservoirQuantileBindData(vector quantiles_p, int32_t sample_size_p) - : quantiles(move(quantiles_p)), sample_size(sample_size_p) { + : quantiles(std::move(quantiles_p)), sample_size(sample_size_p) { } unique_ptr Copy() const override { @@ -107999,7 +114560,7 @@ struct ReservoirQuantileBindData : public FunctionData { AggregateFunction &bound_function) { auto quantiles = reader.ReadRequiredList(); auto sample_size = reader.ReadRequired(); - return make_unique(move(quantiles), sample_size); + return make_unique(std::move(quantiles), sample_size); } vector quantiles; @@ -108424,6 +114985,7 @@ void BuiltinFunctions::RegisterHolisticAggregates() { + namespace duckdb { struct HistogramFun { @@ -108558,40 +115120,26 @@ static void HistogramFinalizeFunction(Vector &state_vector, AggregateInputData & auto states = (HistogramAggState **)sdata.data; auto &mask = FlatVector::Validity(result); - - auto &child_entries = StructVector::GetEntries(result); - auto &bucket_list = child_entries[0]; - auto &count_list = child_entries[1]; - - auto old_len = ListVector::GetListSize(*bucket_list); - - auto &bucket_validity = FlatVector::Validity(*bucket_list); - auto &count_validity = FlatVector::Validity(*count_list); + auto old_len = ListVector::GetListSize(result); for (idx_t i = 0; i < count; i++) { - const auto rid = i + offset; auto state = states[sdata.sel->get_index(i)]; if (!state->hist) { mask.SetInvalid(rid); - bucket_validity.SetInvalid(rid); - count_validity.SetInvalid(rid); continue; } for (auto &entry : *state->hist) { Value bucket_value = OP::template HistogramFinalize(entry.first); - ListVector::PushBack(*bucket_list, bucket_value); auto count_value = Value::CreateValue(entry.second); - ListVector::PushBack(*count_list, count_value); + auto struct_value = + Value::STRUCT({std::make_pair("key", bucket_value), std::make_pair("value", count_value)}); + ListVector::PushBack(result, struct_value); } - auto list_struct_data = FlatVector::GetData(*bucket_list); - list_struct_data[rid].length = ListVector::GetListSize(*bucket_list) - old_len; - list_struct_data[rid].offset = old_len; - - list_struct_data = FlatVector::GetData(*count_list); - list_struct_data[rid].length = ListVector::GetListSize(*count_list) - old_len; + auto list_struct_data = ListVector::GetData(result); + list_struct_data[rid].length = ListVector::GetListSize(result) - old_len; list_struct_data[rid].offset = old_len; old_len += list_struct_data[rid].length; } @@ -108608,10 +115156,7 @@ unique_ptr HistogramBindFunction(ClientContext &context, Aggregate throw NotImplementedException("Unimplemented type for histogram %s", arguments[0]->return_type.ToString()); } - child_list_t struct_children; - struct_children.push_back({"key", LogicalType::LIST(arguments[0]->return_type)}); - struct_children.push_back({"value", LogicalType::LIST(LogicalType::UBIGINT)}); - auto struct_type = LogicalType::MAP(move(struct_children)); + auto struct_type = LogicalType::MAP(arguments[0]->return_type, LogicalType::UBIGINT); function.return_type = struct_type; return make_unique(function.return_type); @@ -109700,6 +116245,7 @@ void BuiltinFunctions::RegisterNestedAggregates() { + namespace duckdb { struct RegrAvgxFun { static void RegisterFunction(BuiltinFunctions &set); @@ -110266,47 +116812,36 @@ void BuiltinFunctions::RegisterRegressiveAggregates() { -namespace duckdb { - -struct SortedAggregateBindData : public FunctionData { - // TODO: Collection sorting does not handle OrderByNullType correctly - // so this is the third hack around it... - static OrderByNullType NormaliseNullOrder(OrderType sense, OrderByNullType null_order) { - if (sense != OrderType::DESCENDING) { - return null_order; - } - switch (null_order) { - case OrderByNullType::NULLS_FIRST: - return OrderByNullType::NULLS_LAST; - case OrderByNullType::NULLS_LAST: - return OrderByNullType::NULLS_FIRST; - default: - throw InternalException("Unknown NULL order sense"); - } - } +namespace duckdb { - SortedAggregateBindData(const AggregateFunction &function_p, vector> &children, - unique_ptr bind_info_p, const BoundOrderModifier &order_bys) - : function(function_p), bind_info(move(bind_info_p)) { +struct SortedAggregateBindData : public FunctionData { + SortedAggregateBindData(ClientContext &context, const AggregateFunction &function_p, + vector> &children, unique_ptr bind_info_p, + const BoundOrderModifier &order_bys) + : buffer_manager(BufferManager::GetBufferManager(context)), function(function_p), + bind_info(std::move(bind_info_p)) { arg_types.reserve(children.size()); for (const auto &child : children) { arg_types.emplace_back(child->return_type); } + sort_types.reserve(order_bys.orders.size()); for (auto &order : order_bys.orders) { - order_sense.emplace_back(order.type); - null_order.emplace_back(NormaliseNullOrder(order.type, order.null_order)); + orders.emplace_back(order.Copy()); sort_types.emplace_back(order.expression->return_type); } } SortedAggregateBindData(const SortedAggregateBindData &other) - : function(other.function), arg_types(other.arg_types), order_sense(other.order_sense), - null_order(other.null_order), sort_types(other.sort_types) { + : buffer_manager(other.buffer_manager), function(other.function), arg_types(other.arg_types), + sort_types(other.sort_types) { if (other.bind_info) { bind_info = other.bind_info->Copy(); } + for (auto &order : other.orders) { + orders.emplace_back(order.Copy()); + } } unique_ptr Copy() const override { @@ -110322,26 +116857,130 @@ struct SortedAggregateBindData : public FunctionData { } else if (bind_info || other.bind_info) { return false; } - return function == other.function && order_sense == other.order_sense && null_order == other.null_order && - sort_types == other.sort_types; + if (function != other.function) { + return false; + } + if (orders.size() != other.orders.size()) { + return false; + } + for (size_t i = 0; i < orders.size(); ++i) { + if (!orders[i].Equals(other.orders[i])) { + return false; + } + } + return true; } + BufferManager &buffer_manager; AggregateFunction function; vector arg_types; unique_ptr bind_info; - vector order_sense; - vector null_order; + vector orders; vector sort_types; }; struct SortedAggregateState { - SortedAggregateState() - : arguments(Allocator::DefaultAllocator()), ordering(Allocator::DefaultAllocator()), nsel(0) { + static const idx_t BUFFER_CAPACITY = STANDARD_VECTOR_SIZE; + + SortedAggregateState() : nsel(0) { + } + + static inline void InitializeBuffer(DataChunk &chunk, const vector &types) { + if (!chunk.ColumnCount() && !types.empty()) { + chunk.Initialize(Allocator::DefaultAllocator(), types); + } + } + + void Flush(SortedAggregateBindData &order_bind) { + if (ordering) { + return; + } + + ordering = make_unique(order_bind.buffer_manager, order_bind.sort_types); + InitializeBuffer(sort_buffer, order_bind.sort_types); + ordering->Append(sort_buffer); + + arguments = make_unique(order_bind.buffer_manager, order_bind.arg_types); + InitializeBuffer(arg_buffer, order_bind.arg_types); + arguments->Append(arg_buffer); + } + + void Update(SortedAggregateBindData &order_bind, DataChunk &sort_chunk, DataChunk &arg_chunk) { + // Lazy instantiation of the buffer chunks + InitializeBuffer(sort_buffer, order_bind.sort_types); + InitializeBuffer(arg_buffer, order_bind.arg_types); + + if (sort_chunk.size() + sort_buffer.size() > BUFFER_CAPACITY) { + Flush(order_bind); + } + if (ordering) { + ordering->Append(sort_chunk); + arguments->Append(arg_chunk); + } else { + sort_buffer.Append(sort_chunk, true); + arg_buffer.Append(arg_chunk, true); + } } - ChunkCollection arguments; - ChunkCollection ordering; + void UpdateSlice(SortedAggregateBindData &order_bind, DataChunk &sort_inputs, DataChunk &arg_inputs) { + // Lazy instantiation of the buffer chunks + InitializeBuffer(sort_buffer, order_bind.sort_types); + InitializeBuffer(arg_buffer, order_bind.arg_types); + + if (nsel + sort_buffer.size() > BUFFER_CAPACITY) { + Flush(order_bind); + } + if (ordering) { + sort_buffer.Reset(); + sort_buffer.Slice(sort_inputs, sel, nsel); + ordering->Append(sort_buffer); + + arg_buffer.Reset(); + arg_buffer.Slice(arg_inputs, sel, nsel); + arguments->Append(arg_buffer); + } else { + sort_buffer.Append(sort_inputs, true, &sel, nsel); + arg_buffer.Append(arg_inputs, true, &sel, nsel); + } + + nsel = 0; + } + + void Combine(SortedAggregateBindData &order_bind, SortedAggregateState &other) { + if (other.ordering) { + // Force CDC if the other hash it + Flush(order_bind); + ordering->Combine(*other.ordering); + arguments->Combine(*other.arguments); + } else if (other.sort_buffer.size()) { + Update(order_bind, other.sort_buffer, other.arg_buffer); + } + } + + void Finalize(LocalSortState &local_sort) { + if (ordering) { + ColumnDataScanState sort_state; + ordering->InitializeScan(sort_state); + ColumnDataScanState arg_state; + arguments->InitializeScan(arg_state); + for (sort_buffer.Reset(); ordering->Scan(sort_state, sort_buffer); sort_buffer.Reset()) { + arg_buffer.Reset(); + arguments->Scan(arg_state, arg_buffer); + local_sort.SinkChunk(sort_buffer, arg_buffer); + } + ordering->Reset(); + arguments->Reset(); + } else { + local_sort.SinkChunk(sort_buffer, arg_buffer); + } + } + + unique_ptr arguments; + unique_ptr ordering; + + DataChunk sort_buffer; + DataChunk arg_buffer; // Selection for scattering SelectionVector sel; @@ -110384,8 +117023,7 @@ struct SortedAggregateFunction { ProjectInputs(inputs, order_bind, input_count, count, arg_chunk, sort_chunk); const auto order_state = (SortedAggregateState *)state; - order_state->arguments.Append(arg_chunk); - order_state->ordering.Append(sort_chunk); + order_state->Update(*order_bind, sort_chunk, arg_chunk); } static void ScatterUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, Vector &states, @@ -110424,41 +117062,35 @@ struct SortedAggregateFunction { continue; } - DataChunk arg_chunk; - arg_chunk.InitializeEmpty(arg_inputs.GetTypes()); - arg_chunk.Slice(arg_inputs, order_state->sel, order_state->nsel); - order_state->arguments.Append(arg_chunk); - - DataChunk sort_chunk; - sort_chunk.InitializeEmpty(sort_inputs.GetTypes()); - sort_chunk.Slice(sort_inputs, order_state->sel, order_state->nsel); - order_state->ordering.Append(sort_chunk); - - // Mark the slice as empty now we have consumed it. - order_state->nsel = 0; + order_state->UpdateSlice(*order_bind, sort_inputs, arg_inputs); } } template - static void Combine(const STATE &source, STATE *target, AggregateInputData &) { - if (source.arguments.Count() == 0) { - return; - } - target->arguments.Append(const_cast(source.arguments)); - target->ordering.Append(const_cast(source.ordering)); + static void Combine(const STATE &source, STATE *target, AggregateInputData &aggr_input_data) { + const auto order_bind = (SortedAggregateBindData *)aggr_input_data.bind_data; + auto &other = const_cast(source); + target->Combine(*order_bind, other); + } + + static void Window(Vector inputs[], const ValidityMask &filter_mask, AggregateInputData &aggr_input_data, + idx_t input_count, data_ptr_t state, const FrameBounds &frame, const FrameBounds &prev, + Vector &result, idx_t rid, idx_t bias) { + throw InternalException("Sorted aggregates should not be generated for window clauses"); } static void Finalize(Vector &states, AggregateInputData &aggr_input_data, Vector &result, idx_t count, idx_t offset) { const auto order_bind = (SortedAggregateBindData *)aggr_input_data.bind_data; + auto &buffer_manager = order_bind->buffer_manager; + auto &orders = order_bind->orders; + RowLayout payload_layout; + payload_layout.Initialize(order_bind->arg_types); // Reusable inner state vector agg_state(order_bind->function.state_size()); Vector agg_state_vec(Value::POINTER((idx_t)agg_state.data())); - // Sorting buffer - vector reordering; - // State variables const auto input_count = order_bind->function.arguments.size(); auto bind_info = order_bind->bind_info.get(); @@ -110477,21 +117109,37 @@ struct SortedAggregateFunction { auto state = sdata[i]; // Apply the sort before delegating the chunks - const auto agg_count = state->ordering.Count(); - if (agg_count > 0) { - reordering.resize(agg_count); - state->ordering.Sort(order_bind->order_sense, order_bind->null_order, reordering.data()); - state->arguments.Reorder(reordering.data()); - } + auto global_sort = make_unique(buffer_manager, orders, payload_layout); + LocalSortState local_sort; + local_sort.Initialize(*global_sort, global_sort->buffer_manager); + state->Finalize(local_sort); + global_sort->AddLocalState(local_sort); + + if (!global_sort->sorted_blocks.empty()) { + global_sort->PrepareMergePhase(); + while (global_sort->sorted_blocks.size() > 1) { + global_sort->InitializeMergeRound(); + MergeSorter merge_sorter(*global_sort, global_sort->buffer_manager); + merge_sorter.PerformInMergeRound(); + global_sort->CompleteMergeRound(false); + } - for (auto &chunk : state->arguments.Chunks()) { - // These are all simple updates, so use it if available - if (simple_update) { - simple_update(chunk->data.data(), aggr_bind_info, input_count, agg_state.data(), chunk->size()); - } else { - // We are only updating a constant state - agg_state_vec.SetVectorType(VectorType::CONSTANT_VECTOR); - update(chunk->data.data(), aggr_bind_info, input_count, agg_state_vec, chunk->size()); + auto &chunk = state->arg_buffer; + PayloadScanner scanner(*global_sort); + for (;;) { + chunk.Reset(); + scanner.Scan(chunk); + if (chunk.size() == 0) { + break; + } + // These are all simple updates, so use it if available + if (simple_update) { + simple_update(chunk.data.data(), aggr_bind_info, input_count, agg_state.data(), chunk.size()); + } else { + // We are only updating a constant state + agg_state_vec.SetVectorType(VectorType::CONSTANT_VECTOR); + update(chunk.data.data(), aggr_bind_info, input_count, agg_state_vec, chunk.size()); + } } } @@ -110519,11 +117167,12 @@ unique_ptr FunctionBinder::BindSortedAggregate(AggregateFunction & unique_ptr bind_info, unique_ptr order_bys) { - auto sorted_bind = make_unique(bound_function, children, move(bind_info), *order_bys); + auto sorted_bind = + make_unique(context, bound_function, children, std::move(bind_info), *order_bys); // The arguments are the children plus the sort columns. for (auto &order : order_bys->orders) { - children.emplace_back(move(order.expression)); + children.emplace_back(std::move(order.expression)); } vector arguments; @@ -110538,15 +117187,101 @@ unique_ptr FunctionBinder::BindSortedAggregate(AggregateFunction & AggregateFunction::StateInitialize, SortedAggregateFunction::ScatterUpdate, AggregateFunction::StateCombine, - SortedAggregateFunction::Finalize, SortedAggregateFunction::SimpleUpdate, nullptr, - AggregateFunction::StateDestroy); - ordered_aggregate.serialize = SortedAggregateFunction::Serialize; - ordered_aggregate.deserialize = SortedAggregateFunction::Deserialize; - ordered_aggregate.null_handling = bound_function.null_handling; + SortedAggregateFunction::Finalize, bound_function.null_handling, SortedAggregateFunction::SimpleUpdate, nullptr, + AggregateFunction::StateDestroy, nullptr, + SortedAggregateFunction::Window, SortedAggregateFunction::Serialize, SortedAggregateFunction::Deserialize); + + bound_function = std::move(ordered_aggregate); + + return std::move(sorted_bind); +} + +} // namespace duckdb + + + + + + + + + + +namespace duckdb { + +BuiltinFunctions::BuiltinFunctions(CatalogTransaction transaction, Catalog &catalog) + : transaction(transaction), catalog(catalog) { +} + +BuiltinFunctions::~BuiltinFunctions() { +} + +void BuiltinFunctions::AddCollation(string name, ScalarFunction function, bool combinable, + bool not_required_for_equality) { + CreateCollationInfo info(std::move(name), std::move(function), combinable, not_required_for_equality); + info.internal = true; + catalog.CreateCollation(transaction, &info); +} + +void BuiltinFunctions::AddFunction(AggregateFunctionSet set) { + CreateAggregateFunctionInfo info(std::move(set)); + info.internal = true; + catalog.CreateFunction(transaction, &info); +} + +void BuiltinFunctions::AddFunction(AggregateFunction function) { + CreateAggregateFunctionInfo info(std::move(function)); + info.internal = true; + catalog.CreateFunction(transaction, &info); +} + +void BuiltinFunctions::AddFunction(PragmaFunction function) { + CreatePragmaFunctionInfo info(std::move(function)); + info.internal = true; + catalog.CreatePragmaFunction(transaction, &info); +} + +void BuiltinFunctions::AddFunction(const string &name, PragmaFunctionSet functions) { + CreatePragmaFunctionInfo info(name, std::move(functions)); + info.internal = true; + catalog.CreatePragmaFunction(transaction, &info); +} + +void BuiltinFunctions::AddFunction(ScalarFunction function) { + CreateScalarFunctionInfo info(std::move(function)); + info.internal = true; + catalog.CreateFunction(transaction, &info); +} + +void BuiltinFunctions::AddFunction(const vector &names, ScalarFunction function) { // NOLINT: false positive + for (auto &name : names) { + function.name = name; + AddFunction(function); + } +} + +void BuiltinFunctions::AddFunction(ScalarFunctionSet set) { + CreateScalarFunctionInfo info(std::move(set)); + info.internal = true; + catalog.CreateFunction(transaction, &info); +} + +void BuiltinFunctions::AddFunction(TableFunction function) { + CreateTableFunctionInfo info(std::move(function)); + info.internal = true; + catalog.CreateTableFunction(transaction, &info); +} - bound_function = move(ordered_aggregate); +void BuiltinFunctions::AddFunction(TableFunctionSet set) { + CreateTableFunctionInfo info(std::move(set)); + info.internal = true; + catalog.CreateTableFunction(transaction, &info); +} - return move(sorted_bind); +void BuiltinFunctions::AddFunction(CopyFunction function) { + CreateCopyFunctionInfo info(std::move(function)); + info.internal = true; + catalog.CreateCopyFunction(transaction, &info); } } // namespace duckdb @@ -110779,8 +117514,8 @@ struct VectorCastHelpers { }; struct VectorStringToList { - static idx_t CountParts(const string_t &input); - static bool SplitStringifiedList(const string_t &input, string_t *child_data, idx_t &child_start, Vector &child); + static idx_t CountPartsList(const string_t &input); + static bool SplitStringList(const string_t &input, string_t *child_data, idx_t &child_start, Vector &child); static bool StringToNestedTypeCastLoop(string_t *source_data, ValidityMask &source_mask, Vector &result, ValidityMask &result_mask, idx_t count, CastParameters ¶meters, const SelectionVector *sel); @@ -110794,9 +117529,37 @@ struct VectorStringToStruct { const SelectionVector *sel); }; +struct VectorStringToMap { + static idx_t CountPartsMap(const string_t &input); + static bool SplitStringMap(const string_t &input, string_t *child_key_data, string_t *child_val_data, + idx_t &child_start, Vector &varchar_key, Vector &varchar_val); + static bool StringToNestedTypeCastLoop(string_t *source_data, ValidityMask &source_mask, Vector &result, + ValidityMask &result_mask, idx_t count, CastParameters ¶meters, + const SelectionVector *sel); +}; + +} // namespace duckdb + + +namespace duckdb { + +BoundCastInfo DefaultCasts::BitCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target) { + // now switch on the result type + switch (target.id()) { + case LogicalTypeId::VARCHAR: + // bit to varchar + return BoundCastInfo(&VectorCastHelpers::StringCast); + case LogicalTypeId::BLOB: + return DefaultCasts::ReinterpretCast; + default: + return DefaultCasts::TryVectorNullCast; + } +} + } // namespace duckdb + namespace duckdb { BoundCastInfo DefaultCasts::BlobCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target) { @@ -110806,6 +117569,7 @@ BoundCastInfo DefaultCasts::BlobCastSwitch(BindCastInput &input, const LogicalTy // blob to varchar return BoundCastInfo(&VectorCastHelpers::StringCast); case LogicalTypeId::AGGREGATE_STATE: + case LogicalTypeId::BIT: return DefaultCasts::ReinterpretCast; default: return DefaultCasts::TryVectorNullCast; @@ -110865,7 +117629,7 @@ BoundCastInfo BindCastInput::GetCastFunction(const LogicalType &source, const Lo } BindCastFunction::BindCastFunction(bind_cast_function_t function_p, unique_ptr info_p) - : function(function_p), info(move(info_p)) { + : function(function_p), info(std::move(info_p)) { } CastFunctionSet::CastFunctionSet() : map_info(nullptr) { @@ -110902,7 +117666,7 @@ BoundCastInfo CastFunctionSet::GetCastFunction(const LogicalType &source, const struct MapCastNode { MapCastNode(BoundCastInfo info, int64_t implicit_cast_cost) - : cast_info(move(info)), bind_function(nullptr), implicit_cast_cost(implicit_cast_cost) { + : cast_info(std::move(info)), bind_function(nullptr), implicit_cast_cost(implicit_cast_cost) { } MapCastNode(bind_cast_function_t func, int64_t implicit_cast_cost) : cast_info(nullptr), bind_function(func), implicit_cast_cost(implicit_cast_cost) { @@ -110955,7 +117719,7 @@ BoundCastInfo MapCastFunction(BindCastInput &input, const LogicalType &source, c void CastFunctionSet::RegisterCastFunction(const LogicalType &source, const LogicalType &target, BoundCastInfo function, int64_t implicit_cast_cost) { - RegisterCastFunction(source, target, MapCastNode(move(function), implicit_cast_cost)); + RegisterCastFunction(source, target, MapCastNode(std::move(function), implicit_cast_cost)); } void CastFunctionSet::RegisterCastFunction(const LogicalType &source, const LogicalType &target, @@ -110968,9 +117732,9 @@ void CastFunctionSet::RegisterCastFunction(const LogicalType &source, const Logi // create the cast map and the cast map function auto info = make_unique(); map_info = info.get(); - bind_functions.emplace_back(MapCastFunction, move(info)); + bind_functions.emplace_back(MapCastFunction, std::move(info)); } - map_info->casts[source].insert(make_pair(target, move(node))); + map_info->casts[source].insert(make_pair(target, std::move(node))); } } // namespace duckdb @@ -111042,7 +117806,7 @@ struct DecimalScaleUpCheckOperator { auto error = StringUtil::Format("Casting value \"%s\" to type %s failed: value is out of range!", Decimal::ToString(input, data->source_width, data->source_scale), data->result.GetType().ToString()); - return HandleVectorCastError::Operation(move(error), mask, idx, data->error_message, + return HandleVectorCastError::Operation(std::move(error), mask, idx, data->error_message, data->all_converted); } return Cast::Operation(input) * data->factor; @@ -111091,7 +117855,7 @@ struct DecimalScaleDownCheckOperator { auto error = StringUtil::Format("Casting value \"%s\" to type %s failed: value is out of range!", Decimal::ToString(input, data->source_width, data->source_scale), data->result.GetType().ToString()); - return HandleVectorCastError::Operation(move(error), mask, idx, data->error_message, + return HandleVectorCastError::Operation(std::move(error), mask, idx, data->error_message, data->all_converted); } return Cast::Operation(input / data->factor); @@ -111274,6 +118038,7 @@ BoundCastInfo DefaultCasts::DecimalCastSwitch(BindCastInput &input, const Logica + namespace duckdb { BindCastInfo::~BindCastInfo() { @@ -111282,12 +118047,13 @@ BindCastInfo::~BindCastInfo() { BoundCastData::~BoundCastData() { } -BoundCastInfo::BoundCastInfo(cast_function_t function_p, unique_ptr cast_data_p) - : function(function_p), cast_data(move(cast_data_p)) { +BoundCastInfo::BoundCastInfo(cast_function_t function_p, unique_ptr cast_data_p, + init_cast_local_state_t init_local_state_p) + : function(function_p), init_local_state(init_local_state_p), cast_data(std::move(cast_data_p)) { } BoundCastInfo BoundCastInfo::Copy() const { - return BoundCastInfo(function, cast_data ? cast_data->Copy() : nullptr); + return BoundCastInfo(function, cast_data ? cast_data->Copy() : nullptr, init_local_state); } bool DefaultCasts::NopCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters) { @@ -111382,11 +118148,12 @@ BoundCastInfo DefaultCasts::GetDefaultCastFunction(BindCastInput &input, const L return TimestampSecCastSwitch(input, source, target); case LogicalTypeId::INTERVAL: return IntervalCastSwitch(input, source, target); - case LogicalTypeId::JSON: case LogicalTypeId::VARCHAR: return StringCastSwitch(input, source, target); case LogicalTypeId::BLOB: return BlobCastSwitch(input, source, target); + case LogicalTypeId::BIT: + return BitCastSwitch(input, source, target); case LogicalTypeId::SQLNULL: return NullTypeCast; case LogicalTypeId::MAP: @@ -111500,7 +118267,7 @@ static bool EnumToVarcharCast(Vector &source, Vector &result, idx_t count, CastP struct EnumBoundCastData : public BoundCastData { EnumBoundCastData(BoundCastInfo to_varchar_cast, BoundCastInfo from_varchar_cast) - : to_varchar_cast(move(to_varchar_cast)), from_varchar_cast(move(from_varchar_cast)) { + : to_varchar_cast(std::move(to_varchar_cast)), from_varchar_cast(std::move(from_varchar_cast)) { } BoundCastInfo to_varchar_cast; @@ -111515,7 +118282,7 @@ struct EnumBoundCastData : public BoundCastData { unique_ptr BindEnumCast(BindCastInput &input, const LogicalType &source, const LogicalType &target) { auto to_varchar_cast = input.GetCastFunction(source, LogicalType::VARCHAR); auto from_varchar_cast = input.GetCastFunction(LogicalType::VARCHAR, target); - return make_unique(move(to_varchar_cast), move(from_varchar_cast)); + return make_unique(std::move(to_varchar_cast), std::move(from_varchar_cast)); } static bool EnumToAnyCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters) { @@ -111549,7 +118316,6 @@ BoundCastInfo DefaultCasts::EnumCastSwitch(BindCastInput &input, const LogicalTy throw InternalException("ENUM can only have unsigned integers (except UINT64) as physical types"); } } - case LogicalTypeId::JSON: case LogicalTypeId::VARCHAR: switch (enum_physical_type) { case PhysicalType::UINT8: @@ -111579,10 +118345,10 @@ unique_ptr ListBoundCastData::BindListToListCast(BindCastInput &i auto &source_child_type = ListType::GetChildType(source); auto &result_child_type = ListType::GetChildType(target); auto child_cast = input.GetCastFunction(source_child_type, result_child_type); - return make_unique(move(child_cast)); + return make_unique(std::move(child_cast)); } -static bool ListToListCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters) { +bool ListCast::ListToListCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters) { auto &cast_data = (ListBoundCastData &)*parameters.cast_data; // only handle constant and flat vectors here for now @@ -111623,7 +118389,7 @@ static bool ListToVarcharCast(Vector &source, Vector &result, idx_t count, CastP auto constant = source.GetVectorType() == VectorType::CONSTANT_VECTOR; // first cast the child vector to varchar Vector varchar_list(LogicalType::LIST(LogicalType::VARCHAR), count); - ListToListCast(source, varchar_list, count, parameters); + ListCast::ListToListCast(source, varchar_list, count, parameters); // now construct the actual varchar vector varchar_list.Flatten(count); @@ -111686,9 +118452,8 @@ static bool ListToVarcharCast(Vector &source, Vector &result, idx_t count, CastP BoundCastInfo DefaultCasts::ListCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target) { switch (target.id()) { case LogicalTypeId::LIST: - return BoundCastInfo(ListToListCast, ListBoundCastData::BindListToListCast(input, source, target)); + return BoundCastInfo(ListCast::ListToListCast, ListBoundCastData::BindListToListCast(input, source, target)); case LogicalTypeId::VARCHAR: - case LogicalTypeId::JSON: return BoundCastInfo(ListToVarcharCast, ListBoundCastData::BindListToListCast( input, source, LogicalType::LIST(LogicalType::VARCHAR))); default: @@ -111702,75 +118467,40 @@ BoundCastInfo DefaultCasts::ListCastSwitch(BindCastInput &input, const LogicalTy namespace duckdb { -struct MapBoundCastData : public BoundCastData { - MapBoundCastData(BoundCastInfo key_cast, BoundCastInfo value_cast) - : key_cast(move(key_cast)), value_cast(move(value_cast)) { - } - - BoundCastInfo key_cast; - BoundCastInfo value_cast; - -public: - unique_ptr Copy() const override { - return make_unique(key_cast.Copy(), value_cast.Copy()); - } -}; - -unique_ptr BindMapToMapCast(BindCastInput &input, const LogicalType &source, const LogicalType &target) { +unique_ptr MapBoundCastData::BindMapToMapCast(BindCastInput &input, const LogicalType &source, + const LogicalType &target) { vector child_cast_info; - auto source_key = LogicalType::LIST(MapType::KeyType(source)); - auto target_key = LogicalType::LIST(MapType::KeyType(target)); - auto source_val = LogicalType::LIST(MapType::ValueType(source)); - auto target_val = LogicalType::LIST(MapType::ValueType(target)); + auto source_key = MapType::KeyType(source); + auto target_key = MapType::KeyType(target); + auto source_val = MapType::ValueType(source); + auto target_val = MapType::ValueType(target); auto key_cast = input.GetCastFunction(source_key, target_key); auto value_cast = input.GetCastFunction(source_val, target_val); - return make_unique(move(key_cast), move(value_cast)); -} - -static bool MapToMapCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters) { - auto &cast_data = (MapBoundCastData &)*parameters.cast_data; - CastParameters key_params(parameters, cast_data.key_cast.cast_data.get()); - if (!cast_data.key_cast.function(MapVector::GetKeys(source), MapVector::GetKeys(result), count, key_params)) { - return false; - } - CastParameters val_params(parameters, cast_data.value_cast.cast_data.get()); - if (!cast_data.value_cast.function(MapVector::GetValues(source), MapVector::GetValues(result), count, val_params)) { - return false; - } - if (source.GetVectorType() == VectorType::CONSTANT_VECTOR) { - result.SetVectorType(VectorType::CONSTANT_VECTOR); - ConstantVector::SetNull(result, ConstantVector::IsNull(source)); - } else { - source.Flatten(count); - FlatVector::Validity(result) = FlatVector::Validity(source); - } - return true; + return make_unique(std::move(key_cast), std::move(value_cast)); } static bool MapToVarcharCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters) { auto constant = source.GetVectorType() == VectorType::CONSTANT_VECTOR; - // first cast the child elements to varchar auto varchar_type = LogicalType::MAP(LogicalType::VARCHAR, LogicalType::VARCHAR); Vector varchar_map(varchar_type, count); - MapToMapCast(source, varchar_map, count, parameters); - // now construct the actual varchar vector - varchar_map.Flatten(count); + // since map's physical type is a list, the ListCast can be utilized + ListCast::ListToListCast(source, varchar_map, count, parameters); + varchar_map.Flatten(count); auto &validity = FlatVector::Validity(varchar_map); - auto &key_lists = MapVector::GetKeys(varchar_map); - auto &val_lists = MapVector::GetValues(varchar_map); - auto &key_str = ListVector::GetEntry(key_lists); - auto &val_str = ListVector::GetEntry(val_lists); + auto &key_str = MapVector::GetKeys(varchar_map); + auto &val_str = MapVector::GetValues(varchar_map); - key_str.Flatten(ListVector::GetListSize(key_lists)); - val_str.Flatten(ListVector::GetListSize(val_lists)); + key_str.Flatten(ListVector::GetListSize(source)); + val_str.Flatten(ListVector::GetListSize(source)); - auto list_data = FlatVector::GetData(key_lists); + auto list_data = ListVector::GetData(varchar_map); auto key_data = FlatVector::GetData(key_str); auto val_data = FlatVector::GetData(val_str); auto &key_validity = FlatVector::Validity(key_str); auto &val_validity = FlatVector::Validity(val_str); + auto &struct_validity = FlatVector::Validity(ListVector::GetEntry(varchar_map)); auto result_data = FlatVector::GetData(result); for (idx_t i = 0; i < count; i++) { @@ -111785,8 +118515,15 @@ static bool MapToVarcharCast(Vector &source, Vector &result, idx_t count, CastPa ret += ", "; } auto idx = list.offset + list_idx; + + if (!struct_validity.RowIsValid(idx)) { + ret += "NULL"; + continue; + } if (!key_validity.RowIsValid(idx)) { - throw InternalException("Error in map: key validity invalid?!"); + // throw InternalException("Error in map: key validity invalid?!"); + ret += "invalid"; + continue; } ret += key_data[idx].GetString(); ret += "="; @@ -111805,12 +118542,10 @@ static bool MapToVarcharCast(Vector &source, Vector &result, idx_t count, CastPa BoundCastInfo DefaultCasts::MapCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target) { switch (target.id()) { case LogicalTypeId::MAP: - return BoundCastInfo(MapToMapCast, BindMapToMapCast(input, source, target)); - case LogicalTypeId::JSON: + return BoundCastInfo(ListCast::ListToListCast, ListBoundCastData::BindListToListCast(input, source, target)); case LogicalTypeId::VARCHAR: { - // bind a cast in which we convert the key/value to VARCHAR entries auto varchar_type = LogicalType::MAP(LogicalType::VARCHAR, LogicalType::VARCHAR); - return BoundCastInfo(MapToVarcharCast, BindMapToMapCast(input, source, varchar_type)); + return BoundCastInfo(MapToVarcharCast, ListBoundCastData::BindListToListCast(input, source, varchar_type)); } default: return TryVectorNullCast; @@ -111855,7 +118590,6 @@ static BoundCastInfo InternalNumericCastSwitch(const LogicalType &source, const return BoundCastInfo(&VectorCastHelpers::TryCastLoop); case LogicalTypeId::DECIMAL: return BoundCastInfo(&VectorCastHelpers::ToDecimalCast); - case LogicalTypeId::JSON: case LogicalTypeId::VARCHAR: return BoundCastInfo(&VectorCastHelpers::StringCast); default: @@ -111919,6 +118653,7 @@ BoundCastInfo DefaultCasts::PointerCastSwitch(BindCastInput &input, const Logica + namespace duckdb { template @@ -112030,10 +118765,10 @@ static BoundCastInfo VectorStringCastNumericSwitch(BindCastInput &input, const L } } +// string -> list casting bool VectorStringToList::StringToNestedTypeCastLoop(string_t *source_data, ValidityMask &source_mask, Vector &result, ValidityMask &result_mask, idx_t count, CastParameters ¶meters, const SelectionVector *sel) { - idx_t total_list_size = 0; for (idx_t i = 0; i < count; i++) { idx_t idx = i; @@ -112043,7 +118778,7 @@ bool VectorStringToList::StringToNestedTypeCastLoop(string_t *source_data, Valid if (!source_mask.RowIsValid(idx)) { continue; } - total_list_size += VectorStringToList::CountParts(source_data[idx]); + total_list_size += VectorStringToList::CountPartsList(source_data[idx]); } Vector varchar_vector(LogicalType::VARCHAR, total_list_size); @@ -112067,7 +118802,7 @@ bool VectorStringToList::StringToNestedTypeCastLoop(string_t *source_data, Valid } list_data[i].offset = total; - if (!VectorStringToList::SplitStringifiedList(source_data[idx], child_data, total, varchar_vector)) { + if (!VectorStringToList::SplitStringList(source_data[idx], child_data, total, varchar_vector)) { string text = "Type VARCHAR with value '" + source_data[idx].GetString() + "' can't be cast to the destination type LIST"; HandleVectorCastError::Operation(text, result_mask, idx, parameters.error_message, all_converted); @@ -112092,6 +118827,7 @@ static LogicalType InitVarcharStructType(const LogicalType &target) { return LogicalType::STRUCT(child_types); } +// string -> struct casting bool VectorStringToStruct::StringToNestedTypeCastLoop(string_t *source_data, ValidityMask &source_mask, Vector &result, ValidityMask &result_mask, idx_t count, CastParameters ¶meters, const SelectionVector *sel) { @@ -112136,8 +118872,6 @@ bool VectorStringToStruct::StringToNestedTypeCastLoop(string_t *source_data, Val auto &varchar_vector = *child_vectors[child_idx]; auto &result_child_vector = *result_children[child_idx]; auto &child_cast_info = cast_data.child_cast_info[child_idx]; - // get the correct casting function (VARCHAR -> result_child_type) from cast_data - // casting functions are determined by BindStructtoStructCast CastParameters child_parameters(parameters, child_cast_info.cast_data.get()); if (!child_cast_info.function(varchar_vector, result_child_vector, count, child_parameters)) { all_converted = false; @@ -112146,6 +118880,87 @@ bool VectorStringToStruct::StringToNestedTypeCastLoop(string_t *source_data, Val return all_converted; } +// string -> map casting +bool VectorStringToMap::StringToNestedTypeCastLoop(string_t *source_data, ValidityMask &source_mask, Vector &result, + ValidityMask &result_mask, idx_t count, CastParameters ¶meters, + const SelectionVector *sel) { + idx_t total_elements = 0; + for (idx_t i = 0; i < count; i++) { + idx_t idx = i; + if (sel) { + idx = sel->get_index(i); + } + if (!source_mask.RowIsValid(idx)) { + continue; + } + total_elements += (VectorStringToMap::CountPartsMap(source_data[idx]) + 1) / 2; + } + + Vector varchar_key_vector(LogicalType::VARCHAR, total_elements); + Vector varchar_val_vector(LogicalType::VARCHAR, total_elements); + auto child_key_data = FlatVector::GetData(varchar_key_vector); + auto child_val_data = FlatVector::GetData(varchar_val_vector); + + ListVector::Reserve(result, total_elements); + ListVector::SetListSize(result, total_elements); + auto list_data = ListVector::GetData(result); + + bool all_converted = true; + idx_t total = 0; + for (idx_t i = 0; i < count; i++) { + idx_t idx = i; + if (sel) { + idx = sel->get_index(i); + } + if (!source_mask.RowIsValid(idx)) { + result_mask.SetInvalid(idx); + continue; + } + + list_data[i].offset = total; + if (!VectorStringToMap::SplitStringMap(source_data[idx], child_key_data, child_val_data, total, + varchar_key_vector, varchar_val_vector)) { + string text = "Type VARCHAR with value '" + source_data[idx].GetString() + + "' can't be cast to the destination type MAP"; + FlatVector::SetNull(result, idx, true); + HandleVectorCastError::Operation(text, result_mask, idx, parameters.error_message, all_converted); + } + list_data[i].length = total - list_data[i].offset; + } + D_ASSERT(total_elements == total); + + auto &result_key_child = MapVector::GetKeys(result); + auto &result_val_child = MapVector::GetValues(result); + auto &cast_data = (MapBoundCastData &)*parameters.cast_data; + + CastParameters key_params(parameters, cast_data.key_cast.cast_data.get()); + if (!cast_data.key_cast.function(varchar_key_vector, result_key_child, total_elements, key_params)) { + all_converted = false; + } + CastParameters val_params(parameters, cast_data.value_cast.cast_data.get()); + if (!cast_data.value_cast.function(varchar_val_vector, result_val_child, total_elements, val_params)) { + all_converted = false; + } + + auto &key_validity = FlatVector::Validity(result_key_child); + if (!all_converted) { + for (idx_t row_idx = 0; row_idx < count; row_idx++) { + if (!result_mask.RowIsValid(row_idx)) { + continue; + } + auto list = list_data[row_idx]; + for (idx_t list_idx = 0; list_idx < list.length; list_idx++) { + auto idx = list.offset + list_idx; + if (!key_validity.RowIsValid(idx)) { + result_mask.SetInvalid(row_idx); + } + } + } + } + MapConversionVerify(result, count); + return all_converted; +} + template bool StringToNestedTypeCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters) { D_ASSERT(source.GetType().id() == LogicalTypeId::VARCHAR); @@ -112155,7 +118970,6 @@ bool StringToNestedTypeCast(Vector &source, Vector &result, idx_t count, CastPar auto source_data = ConstantVector::GetData(source); auto &source_mask = ConstantVector::Validity(source); auto &result_mask = FlatVector::Validity(result); - auto ret = T::StringToNestedTypeCastLoop(source_data, source_mask, result, result_mask, 1, parameters, nullptr); result.SetVectorType(VectorType::CONSTANT_VECTOR); return ret; @@ -112197,12 +119011,13 @@ BoundCastInfo DefaultCasts::StringCastSwitch(BindCastInput &input, const Logical &VectorCastHelpers::TryCastStrictLoop); case LogicalTypeId::BLOB: return BoundCastInfo(&VectorCastHelpers::TryCastStringLoop); + case LogicalTypeId::BIT: + return BoundCastInfo(&VectorCastHelpers::TryCastStringLoop); case LogicalTypeId::UUID: return BoundCastInfo(&VectorCastHelpers::TryCastStringLoop); case LogicalTypeId::SQLNULL: return &DefaultCasts::TryVectorNullCast; case LogicalTypeId::VARCHAR: - case LogicalTypeId::JSON: return &DefaultCasts::ReinterpretCast; case LogicalTypeId::LIST: // the second argument allows for a secondary casting function to be passed in the CastParameters @@ -112212,6 +119027,10 @@ BoundCastInfo DefaultCasts::StringCastSwitch(BindCastInput &input, const Logical case LogicalTypeId::STRUCT: return BoundCastInfo(&StringToNestedTypeCast, StructBoundCastData::BindStructToStructCast(input, InitVarcharStructType(target), target)); + case LogicalTypeId::MAP: + return BoundCastInfo(&StringToNestedTypeCast, + MapBoundCastData::BindMapToMapCast( + input, LogicalType::MAP(LogicalType::VARCHAR, LogicalType::VARCHAR), target)); default: return VectorStringCastNumericSwitch(input, source, target); } @@ -112233,9 +119052,9 @@ unique_ptr StructBoundCastData::BindStructToStructCast(BindCastIn } for (idx_t i = 0; i < source_child_types.size(); i++) { auto child_cast = input.GetCastFunction(source_child_types[i].second, result_child_types[i].second); - child_cast_info.push_back(move(child_cast)); + child_cast_info.push_back(std::move(child_cast)); } - return make_unique(move(child_cast_info), target); + return make_unique(std::move(child_cast_info), target); } static bool StructToStructCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters) { @@ -112342,7 +119161,6 @@ BoundCastInfo DefaultCasts::StructCastSwitch(BindCastInput &input, const Logical switch (target.id()) { case LogicalTypeId::STRUCT: return BoundCastInfo(StructToStructCast, StructBoundCastData::BindStructToStructCast(input, source, target)); - case LogicalTypeId::JSON: case LogicalTypeId::VARCHAR: { // bind a cast in which we convert all child entries to VARCHAR entries auto &struct_children = StructType::GetChildTypes(source); @@ -112350,7 +119168,7 @@ BoundCastInfo DefaultCasts::StructCastSwitch(BindCastInput &input, const Logical for (auto &child_entry : struct_children) { varchar_children.push_back(make_pair(child_entry.first, LogicalType::VARCHAR)); } - auto varchar_type = LogicalType::STRUCT(move(varchar_children)); + auto varchar_type = LogicalType::STRUCT(std::move(varchar_children)); return BoundCastInfo(StructToVarcharCast, StructBoundCastData::BindStructToStructCast(input, source, varchar_type)); } @@ -112369,7 +119187,6 @@ BoundCastInfo DefaultCasts::DateCastSwitch(BindCastInput &input, const LogicalTy // now switch on the result type switch (target.id()) { case LogicalTypeId::VARCHAR: - case LogicalTypeId::JSON: // date to varchar return BoundCastInfo(&VectorCastHelpers::StringCast); case LogicalTypeId::TIMESTAMP: @@ -112391,7 +119208,6 @@ BoundCastInfo DefaultCasts::TimeCastSwitch(BindCastInput &input, const LogicalTy // now switch on the result type switch (target.id()) { case LogicalTypeId::VARCHAR: - case LogicalTypeId::JSON: // time to varchar return BoundCastInfo(&VectorCastHelpers::StringCast); case LogicalTypeId::TIME_TZ: @@ -112407,7 +119223,6 @@ BoundCastInfo DefaultCasts::TimeTzCastSwitch(BindCastInput &input, const Logical // now switch on the result type switch (target.id()) { case LogicalTypeId::VARCHAR: - case LogicalTypeId::JSON: // time with time zone to varchar return BoundCastInfo(&VectorCastHelpers::StringCast); case LogicalTypeId::TIME: @@ -112423,7 +119238,6 @@ BoundCastInfo DefaultCasts::TimestampCastSwitch(BindCastInput &input, const Logi // now switch on the result type switch (target.id()) { case LogicalTypeId::VARCHAR: - case LogicalTypeId::JSON: // timestamp to varchar return BoundCastInfo(&VectorCastHelpers::StringCast); case LogicalTypeId::DATE: @@ -112458,7 +119272,6 @@ BoundCastInfo DefaultCasts::TimestampTzCastSwitch(BindCastInput &input, const Lo // now switch on the result type switch (target.id()) { case LogicalTypeId::VARCHAR: - case LogicalTypeId::JSON: // timestamp with time zone to varchar return BoundCastInfo(&VectorCastHelpers::StringCast); case LogicalTypeId::TIME_TZ: @@ -112478,7 +119291,6 @@ BoundCastInfo DefaultCasts::TimestampNsCastSwitch(BindCastInput &input, const Lo // now switch on the result type switch (target.id()) { case LogicalTypeId::VARCHAR: - case LogicalTypeId::JSON: // timestamp (ns) to varchar return BoundCastInfo(&VectorCastHelpers::StringCast); case LogicalTypeId::TIMESTAMP: @@ -112495,7 +119307,6 @@ BoundCastInfo DefaultCasts::TimestampMsCastSwitch(BindCastInput &input, const Lo // now switch on the result type switch (target.id()) { case LogicalTypeId::VARCHAR: - case LogicalTypeId::JSON: // timestamp (ms) to varchar return BoundCastInfo(&VectorCastHelpers::StringCast); case LogicalTypeId::TIMESTAMP: @@ -112512,7 +119323,6 @@ BoundCastInfo DefaultCasts::TimestampSecCastSwitch(BindCastInput &input, const L // now switch on the result type switch (target.id()) { case LogicalTypeId::VARCHAR: - case LogicalTypeId::JSON: // timestamp (sec) to varchar return BoundCastInfo(&VectorCastHelpers::StringCast); case LogicalTypeId::TIMESTAMP: @@ -112528,7 +119338,6 @@ BoundCastInfo DefaultCasts::IntervalCastSwitch(BindCastInput &input, const Logic // now switch on the result type switch (target.id()) { case LogicalTypeId::VARCHAR: - case LogicalTypeId::JSON: // time to varchar return BoundCastInfo(&VectorCastHelpers::StringCast); default: @@ -112540,6 +119349,7 @@ BoundCastInfo DefaultCasts::IntervalCastSwitch(BindCastInput &input, const Logic + #include // for std::sort namespace duckdb { @@ -112552,7 +119362,8 @@ namespace duckdb { struct ToUnionBoundCastData : public BoundCastData { ToUnionBoundCastData(union_tag_t member_idx, string name, LogicalType type, int64_t cost, BoundCastInfo member_cast_info) - : tag(member_idx), name(move(name)), type(move(type)), cost(cost), member_cast_info(move(member_cast_info)) { + : tag(member_idx), name(std::move(name)), type(std::move(type)), cost(cost), + member_cast_info(std::move(member_cast_info)) { } union_tag_t tag; @@ -112582,7 +119393,8 @@ unique_ptr BindToUnionCast(BindCastInput &input, const LogicalTyp auto member_cast_cost = input.function_set.ImplicitCastCost(source, member_type); if (member_cast_cost != -1) { auto member_cast_info = input.GetCastFunction(source, member_type); - candidates.emplace_back(member_idx, member_name, member_type, member_cast_cost, move(member_cast_info)); + candidates.emplace_back(member_idx, member_name, member_type, member_cast_cost, + std::move(member_cast_info)); } }; @@ -112631,7 +119443,7 @@ unique_ptr BindToUnionCast(BindCastInput &input, const LogicalTyp } // otherwise, return the selected cast - return make_unique(move(selected_cast)); + return make_unique(std::move(selected_cast)); } static bool ToUnionCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters) { @@ -112681,7 +119493,7 @@ struct UnionToUnionBoundCastData : public BoundCastData { LogicalType target_type; UnionToUnionBoundCastData(vector tag_map, vector member_casts, LogicalType target_type) - : tag_map(move(tag_map)), member_casts(move(member_casts)), target_type(move(target_type)) { + : tag_map(std::move(tag_map)), member_casts(std::move(member_casts)), target_type(std::move(target_type)) { } public: @@ -112690,7 +119502,7 @@ struct UnionToUnionBoundCastData : public BoundCastData { for (auto &member_cast : member_casts) { member_casts_copy.push_back(member_cast.Copy()); } - return make_unique(tag_map, move(member_casts_copy), target_type); + return make_unique(tag_map, std::move(member_casts_copy), target_type); } }; @@ -112712,18 +119524,9 @@ unique_ptr BindUnionToUnionCast(BindCastInput &input, const Logic for (idx_t target_idx = 0; target_idx < UnionType::GetMemberCount(target); target_idx++) { auto &target_member_name = UnionType::GetMemberName(target, target_idx); - // found a matching member, check if the types are castable + // found a matching member if (source_member_name == target_member_name) { auto &target_member_type = UnionType::GetMemberType(target, target_idx); - - if (input.function_set.ImplicitCastCost(source_member_type, target_member_type) < 0) { - auto message = StringUtil::Format( - "Type %s can't be cast as %s. The member '%s' can't be implicitly cast from %s to %s", - source.ToString(), target.ToString(), source_member_name, source_member_type.ToString(), - target_member_type.ToString()); - throw CastException(message); - } - tag_map[source_idx] = target_idx; member_casts.push_back(input.GetCastFunction(source_member_type, target_member_type)); found = true; @@ -112739,7 +119542,7 @@ unique_ptr BindUnionToUnionCast(BindCastInput &input, const Logic } } - return make_unique(tag_map, move(member_casts), target); + return make_unique(tag_map, std::move(member_casts), target); } static bool UnionToUnionCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters) { @@ -112797,6 +119600,14 @@ static bool UnionToUnionCast(Vector &source, Vector &result, idx_t count, CastPa } } else { // Otherwise, use the unified vector format to access the source vector. + + // Ensure that all the result members are flat vectors + // This is not always the case, e.g. when a member is cast using the default TryNullCast function + // the resulting member vector will be a constant null vector. + for (idx_t target_member_idx = 0; target_member_idx < target_member_count; target_member_idx++) { + UnionVector::GetMember(result, target_member_idx).Flatten(count); + } + // We assume that a union tag vector validity matches the union vector validity. UnifiedVectorFormat source_tag_format; source_tag_vector.ToUnifiedFormat(count, source_tag_format); @@ -112809,6 +119620,9 @@ static bool UnionToUnionCast(Vector &source, Vector &result, idx_t count, CastPa auto target_tag = cast_data.tag_map[source_tag]; FlatVector::GetData(result_tag_vector)[row_idx] = target_tag; } else { + + // Issue: The members of the result is not always flatvectors + // In the case of TryNullCast, the result member is constant. FlatVector::SetNull(result, row_idx, true); } } @@ -112866,14 +119680,13 @@ static bool UnionToVarcharCast(Vector &source, Vector &result, idx_t count, Cast BoundCastInfo DefaultCasts::UnionCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target) { switch (target.id()) { - case LogicalTypeId::JSON: case LogicalTypeId::VARCHAR: { // bind a cast in which we convert all members to VARCHAR first child_list_t varchar_members; for (idx_t member_idx = 0; member_idx < UnionType::GetMemberCount(source); member_idx++) { varchar_members.push_back(make_pair(UnionType::GetMemberName(source, member_idx), LogicalType::VARCHAR)); } - auto varchar_type = LogicalType::UNION(move(varchar_members)); + auto varchar_type = LogicalType::UNION(std::move(varchar_members)); return BoundCastInfo(UnionToVarcharCast, BindUnionToUnionCast(input, source, varchar_type)); } break; case LogicalTypeId::UNION: @@ -112894,7 +119707,6 @@ BoundCastInfo DefaultCasts::UUIDCastSwitch(BindCastInput &input, const LogicalTy // now switch on the result type switch (target.id()) { case LogicalTypeId::VARCHAR: - case LogicalTypeId::JSON: // uuid to varchar return BoundCastInfo(&VectorCastHelpers::StringCast); default: @@ -112907,6 +119719,7 @@ BoundCastInfo DefaultCasts::UUIDCastSwitch(BindCastInput &input, const LogicalTy namespace duckdb { +// ------- Helper functions for splitting string nested types ------- static bool IsNull(const char *buf, idx_t start_pos, Vector &child, idx_t row_idx) { if (buf[start_pos] == 'N' && buf[start_pos + 1] == 'U' && buf[start_pos + 2] == 'L' && buf[start_pos + 3] == 'L') { FlatVector::SetNull(child, row_idx, true); @@ -112921,46 +119734,6 @@ inline static void SkipWhitespace(const char *buf, idx_t &pos, idx_t len) { } } -static idx_t StringTrim(const char *buf, idx_t &start_pos, idx_t pos) { - idx_t trailing_whitespace = 0; - while (StringUtil::CharacterIsSpace(buf[pos - trailing_whitespace - 1])) { - trailing_whitespace++; - } - if ((buf[start_pos] == '"' && buf[pos - trailing_whitespace - 1] == '"') || - (buf[start_pos] == '\'' && buf[pos - trailing_whitespace - 1] == '\'')) { - start_pos++; - trailing_whitespace++; - } - return (pos - trailing_whitespace); -} - -struct CountPartOperation { - idx_t count = 0; - - void HandleValue(const char *buf, idx_t start_pos, idx_t pos) { - count++; - } -}; - -struct SplitStringOperation { - SplitStringOperation(string_t *child_data, idx_t &child_start, Vector &child) - : child_data(child_data), child_start(child_start), child(child) { - } - - string_t *child_data; - idx_t &child_start; - Vector &child; - - void HandleValue(const char *buf, idx_t start_pos, idx_t pos) { - if ((pos - start_pos) == 4 && IsNull(buf, start_pos, child, child_start)) { - child_start++; - return; - } - child_data[child_start] = StringVector::AddString(child, buf + start_pos, pos - start_pos); - child_start++; - } -}; - static bool SkipToCloseQuotes(idx_t &pos, const char *buf, idx_t &len) { char quote = buf[pos]; pos++; @@ -113002,8 +119775,53 @@ static bool SkipToClose(idx_t &idx, const char *buf, idx_t &len, idx_t &lvl, cha return false; } +static idx_t StringTrim(const char *buf, idx_t &start_pos, idx_t pos) { + idx_t trailing_whitespace = 0; + while (StringUtil::CharacterIsSpace(buf[pos - trailing_whitespace - 1])) { + trailing_whitespace++; + } + if ((buf[start_pos] == '"' && buf[pos - trailing_whitespace - 1] == '"') || + (buf[start_pos] == '\'' && buf[pos - trailing_whitespace - 1] == '\'')) { + start_pos++; + trailing_whitespace++; + } + return (pos - trailing_whitespace); +} + +struct CountPartOperation { + idx_t count = 0; + + bool HandleKey(const char *buf, idx_t start_pos, idx_t pos) { + count++; + return true; + } + void HandleValue(const char *buf, idx_t start_pos, idx_t pos) { + count++; + } +}; + +// ------- LIST SPLIT ------- +struct SplitStringListOperation { + SplitStringListOperation(string_t *child_data, idx_t &child_start, Vector &child) + : child_data(child_data), child_start(child_start), child(child) { + } + + string_t *child_data; + idx_t &child_start; + Vector &child; + + void HandleValue(const char *buf, idx_t start_pos, idx_t pos) { + if ((pos - start_pos) == 4 && IsNull(buf, start_pos, child, child_start)) { + child_start++; + return; + } + child_data[child_start] = StringVector::AddString(child, buf + start_pos, pos - start_pos); + child_start++; + } +}; + template -static bool SplitStringifiedListInternal(const string_t &input, OP &state) { +static bool SplitStringListInternal(const string_t &input, OP &state) { const char *buf = input.GetDataUnsafe(); idx_t len = input.GetSize(); idx_t lvl = 1; @@ -113021,7 +119839,7 @@ static bool SplitStringifiedListInternal(const string_t &input, OP &state) { if (!SkipToClose(pos, buf, len, ++lvl, ']')) { return false; } - } else if (buf[pos] == '"' || buf[pos] == '\'') { + } else if ((buf[pos] == '"' || buf[pos] == '\'') && pos == start_pos) { SkipToCloseQuotes(pos, buf, len); } else if (buf[pos] == '{') { idx_t struct_lvl = 0; @@ -113048,19 +119866,121 @@ static bool SplitStringifiedListInternal(const string_t &input, OP &state) { return (pos == len && lvl == 0); } -bool VectorStringToList::SplitStringifiedList(const string_t &input, string_t *child_data, idx_t &child_start, - Vector &child) { - SplitStringOperation state(child_data, child_start, child); - return SplitStringifiedListInternal(input, state); +bool VectorStringToList::SplitStringList(const string_t &input, string_t *child_data, idx_t &child_start, + Vector &child) { + SplitStringListOperation state(child_data, child_start, child); + return SplitStringListInternal(input, state); } -idx_t VectorStringToList::CountParts(const string_t &input) { +idx_t VectorStringToList::CountPartsList(const string_t &input) { CountPartOperation state; - SplitStringifiedListInternal(input, state); + SplitStringListInternal(input, state); return state.count; } -static bool FindKey(const char *buf, idx_t len, idx_t &pos) { +// ------- MAP SPLIT ------- +struct SplitStringMapOperation { + SplitStringMapOperation(string_t *child_key_data, string_t *child_val_data, idx_t &child_start, Vector &varchar_key, + Vector &varchar_val) + : child_key_data(child_key_data), child_val_data(child_val_data), child_start(child_start), + varchar_key(varchar_key), varchar_val(varchar_val) { + } + + string_t *child_key_data; + string_t *child_val_data; + idx_t &child_start; + Vector &varchar_key; + Vector &varchar_val; + + bool HandleKey(const char *buf, idx_t start_pos, idx_t pos) { + if ((pos - start_pos) == 4 && IsNull(buf, start_pos, varchar_key, child_start)) { + FlatVector::SetNull(varchar_val, child_start, true); + child_start++; + return false; + } + child_key_data[child_start] = StringVector::AddString(varchar_key, buf + start_pos, pos - start_pos); + return true; + } + + void HandleValue(const char *buf, idx_t start_pos, idx_t pos) { + if ((pos - start_pos) == 4 && IsNull(buf, start_pos, varchar_val, child_start)) { + child_start++; + return; + } + child_val_data[child_start] = StringVector::AddString(varchar_val, buf + start_pos, pos - start_pos); + child_start++; + } +}; + +template +static bool FindKeyOrValueMap(const char *buf, idx_t len, idx_t &pos, OP &state, bool key) { + auto start_pos = pos; + idx_t lvl = 0; + while (pos < len) { + if (buf[pos] == '"' || buf[pos] == '\'') { + SkipToCloseQuotes(pos, buf, len); + } else if (buf[pos] == '{') { + SkipToClose(pos, buf, len, lvl, '}'); + } else if (buf[pos] == '[') { + SkipToClose(pos, buf, len, lvl, ']'); + } else if (key && buf[pos] == '=') { + idx_t end_pos = StringTrim(buf, start_pos, pos); + return state.HandleKey(buf, start_pos, end_pos); // put string in KEY_child_vector + } else if (!key && (buf[pos] == ',' || buf[pos] == '}')) { + idx_t end_pos = StringTrim(buf, start_pos, pos); + state.HandleValue(buf, start_pos, end_pos); // put string in VALUE_child_vector + return true; + } + pos++; + } + return false; +} + +template +static bool SplitStringMapInternal(const string_t &input, OP &state) { + const char *buf = input.GetDataUnsafe(); + idx_t len = input.GetSize(); + idx_t pos = 0; + + SkipWhitespace(buf, pos, len); + if (pos == len || buf[pos] != '{') { + return false; + } + SkipWhitespace(buf, ++pos, len); + if (pos == len) { + return false; + } + if (buf[pos] == '}') { + SkipWhitespace(buf, ++pos, len); + return (pos == len); + } + while (pos < len) { + if (!FindKeyOrValueMap(buf, len, pos, state, true)) { + return false; + } + SkipWhitespace(buf, ++pos, len); + if (!FindKeyOrValueMap(buf, len, pos, state, false)) { + return false; + } + SkipWhitespace(buf, ++pos, len); + } + return true; +} + +bool VectorStringToMap::SplitStringMap(const string_t &input, string_t *child_key_data, string_t *child_val_data, + idx_t &child_start, Vector &varchar_key, Vector &varchar_val) { + SplitStringMapOperation state(child_key_data, child_val_data, child_start, varchar_key, varchar_val); + return SplitStringMapInternal(input, state); +} + +idx_t VectorStringToMap::CountPartsMap(const string_t &input) { + CountPartOperation state; + SplitStringMapInternal(input, state); + return state.count; +} + +// ------- STRUCT SPLIT ------- +static bool FindKeyStruct(const char *buf, idx_t len, idx_t &pos) { while (pos < len) { if (buf[pos] == ':') { return true; @@ -113070,8 +119990,8 @@ static bool FindKey(const char *buf, idx_t len, idx_t &pos) { return false; } -static bool FindValue(const char *buf, idx_t len, idx_t &pos, Vector &varchar_child, idx_t &row_idx, - ValidityMask *child_mask) { +static bool FindValueStruct(const char *buf, idx_t len, idx_t &pos, Vector &varchar_child, idx_t &row_idx, + ValidityMask *child_mask) { auto start_pos = pos; idx_t lvl = 0; while (pos < len) { @@ -113114,7 +120034,7 @@ bool VectorStringToStruct::SplitStruct(string_t &input, std::vectorsecond; SkipWhitespace(buf, ++pos, len); - if (!FindValue(buf, len, pos, *varchar_vectors[child_idx], row_idx, child_masks[child_idx])) { + if (!FindValueStruct(buf, len, pos, *varchar_vectors[child_idx], row_idx, child_masks[child_idx])) { return false; } SkipWhitespace(buf, ++pos, len); @@ -113354,13 +120274,8 @@ int64_t CastRules::ImplicitCast(const LogicalType &from, const LogicalType &to) // Implicit cast not allowed from BLOB to VARCHAR return -1; } - if ((from.id() == LogicalTypeId::VARCHAR && to.id() == LogicalTypeId::JSON) || - (from.id() == LogicalTypeId::JSON && to.id() == LogicalTypeId::VARCHAR)) { - // Virtually no cost, just a different tag - return 1; - } - if (to.id() == LogicalTypeId::VARCHAR || to.id() == LogicalTypeId::JSON) { - // everything can be cast to VARCHAR/JSON, but this cast has a high cost + if (to.id() == LogicalTypeId::VARCHAR) { + // everything can be cast to VARCHAR, but this cast has a high cost return TargetTypeCost(to); } if (from.id() == LogicalTypeId::LIST && to.id() == LogicalTypeId::LIST) { @@ -113617,14 +120532,6 @@ CompressionFunction *DBConfig::GetCompressionFunction(CompressionType type, Phys - - - - - - - - namespace duckdb { FunctionData::~FunctionData() { @@ -113651,13 +120558,13 @@ bool TableFunctionData::Equals(const FunctionData &other) const { return false; } -Function::Function(string name_p) : name(move(name_p)) { +Function::Function(string name_p) : name(std::move(name_p)) { } Function::~Function() { } SimpleFunction::SimpleFunction(string name_p, vector arguments_p, LogicalType varargs_p) - : Function(move(name_p)), arguments(move(arguments_p)), varargs(move(varargs_p)) { + : Function(std::move(name_p)), arguments(std::move(arguments_p)), varargs(std::move(varargs_p)) { } SimpleFunction::~SimpleFunction() { @@ -113673,7 +120580,7 @@ bool SimpleFunction::HasVarArgs() const { SimpleNamedParameterFunction::SimpleNamedParameterFunction(string name_p, vector arguments_p, LogicalType varargs_p) - : SimpleFunction(move(name_p), move(arguments_p), move(varargs_p)) { + : SimpleFunction(std::move(name_p), std::move(arguments_p), std::move(varargs_p)) { } SimpleNamedParameterFunction::~SimpleNamedParameterFunction() { @@ -113690,8 +120597,8 @@ bool SimpleNamedParameterFunction::HasNamedParameters() { BaseScalarFunction::BaseScalarFunction(string name_p, vector arguments_p, LogicalType return_type_p, FunctionSideEffects side_effects, LogicalType varargs_p, FunctionNullHandling null_handling) - : SimpleFunction(move(name_p), move(arguments_p), move(varargs_p)), return_type(move(return_type_p)), - side_effects(side_effects), null_handling(null_handling) { + : SimpleFunction(std::move(name_p), std::move(arguments_p), std::move(varargs_p)), + return_type(std::move(return_type_p)), side_effects(side_effects), null_handling(null_handling) { } BaseScalarFunction::~BaseScalarFunction() { @@ -113733,67 +120640,6 @@ void BuiltinFunctions::Initialize() { AddCollation("nfc", NFCNormalizeFun::GetFunction()); } -BuiltinFunctions::BuiltinFunctions(ClientContext &context, Catalog &catalog) : context(context), catalog(catalog) { -} - -void BuiltinFunctions::AddCollation(string name, ScalarFunction function, bool combinable, - bool not_required_for_equality) { - CreateCollationInfo info(move(name), move(function), combinable, not_required_for_equality); - catalog.CreateCollation(context, &info); -} - -void BuiltinFunctions::AddFunction(AggregateFunctionSet set) { - CreateAggregateFunctionInfo info(move(set)); - catalog.CreateFunction(context, &info); -} - -void BuiltinFunctions::AddFunction(AggregateFunction function) { - CreateAggregateFunctionInfo info(move(function)); - catalog.CreateFunction(context, &info); -} - -void BuiltinFunctions::AddFunction(PragmaFunction function) { - CreatePragmaFunctionInfo info(move(function)); - catalog.CreatePragmaFunction(context, &info); -} - -void BuiltinFunctions::AddFunction(const string &name, PragmaFunctionSet functions) { - CreatePragmaFunctionInfo info(name, move(functions)); - catalog.CreatePragmaFunction(context, &info); -} - -void BuiltinFunctions::AddFunction(ScalarFunction function) { - CreateScalarFunctionInfo info(move(function)); - catalog.CreateFunction(context, &info); -} - -void BuiltinFunctions::AddFunction(const vector &names, ScalarFunction function) { // NOLINT: false positive - for (auto &name : names) { - function.name = name; - AddFunction(function); - } -} - -void BuiltinFunctions::AddFunction(ScalarFunctionSet set) { - CreateScalarFunctionInfo info(move(set)); - catalog.CreateFunction(context, &info); -} - -void BuiltinFunctions::AddFunction(TableFunction function) { - CreateTableFunctionInfo info(move(function)); - catalog.CreateTableFunction(context, &info); -} - -void BuiltinFunctions::AddFunction(TableFunctionSet set) { - CreateTableFunctionInfo info(move(set)); - catalog.CreateTableFunction(context, &info); -} - -void BuiltinFunctions::AddFunction(CopyFunction function) { - CreateCopyFunctionInfo info(move(function)); - catalog.CreateCopyFunction(context, &info); -} - hash_t BaseScalarFunction::Hash() const { hash_t hash = return_type.Hash(); for (auto &arg : arguments) { @@ -113854,6 +120700,7 @@ void Function::EraseArgument(SimpleFunction &bound_function, vector FunctionBinder::BindScalarFunction(const string &schema, vector> children, string &error, bool is_operator, Binder *binder) { // bind the function - auto function = Catalog::GetCatalog(context).GetEntry(context, CatalogType::SCALAR_FUNCTION_ENTRY, schema, name); + auto function = + Catalog::GetSystemCatalog(context).GetEntry(context, CatalogType::SCALAR_FUNCTION_ENTRY, schema, name); D_ASSERT(function && function->type == CatalogType::SCALAR_FUNCTION_ENTRY); - return BindScalarFunction((ScalarFunctionCatalogEntry &)*function, move(children), error, is_operator, binder); + return BindScalarFunction((ScalarFunctionCatalogEntry &)*function, std::move(children), error, is_operator, binder); } unique_ptr FunctionBinder::BindScalarFunction(ScalarFunctionCatalogEntry &func, @@ -114113,7 +120961,7 @@ unique_ptr FunctionBinder::BindScalarFunction(ScalarFunctionCatalogE } } } - return BindScalarFunction(bound_function, move(children), is_operator); + return BindScalarFunction(bound_function, std::move(children), is_operator); } unique_ptr FunctionBinder::BindScalarFunction(ScalarFunction bound_function, @@ -114128,8 +120976,8 @@ unique_ptr FunctionBinder::BindScalarFunction(ScalarFun // now create the function auto return_type = bound_function.return_type; - return make_unique(move(return_type), move(bound_function), move(children), - move(bind_info), is_operator); + return make_unique(std::move(return_type), std::move(bound_function), std::move(children), + std::move(bind_info), is_operator); } unique_ptr FunctionBinder::BindAggregateFunction(AggregateFunction bound_function, @@ -114150,11 +120998,11 @@ unique_ptr FunctionBinder::BindAggregateFunction(Aggre // Special case: for ORDER BY aggregates, we wrap the aggregate function in a SortedAggregateFunction // The children are the sort clauses and the binding contains the ordering data. if (order_bys && !order_bys->orders.empty()) { - bind_info = BindSortedAggregate(bound_function, children, move(bind_info), move(order_bys)); + bind_info = BindSortedAggregate(bound_function, children, std::move(bind_info), std::move(order_bys)); } - return make_unique(move(bound_function), move(children), move(filter), move(bind_info), - aggr_type); + return make_unique(std::move(bound_function), std::move(children), std::move(filter), + std::move(bind_info), aggr_type); } } // namespace duckdb @@ -114163,7 +121011,7 @@ unique_ptr FunctionBinder::BindAggregateFunction(Aggre namespace duckdb { -ScalarFunctionSet::ScalarFunctionSet(string name) : FunctionSet(move(name)) { +ScalarFunctionSet::ScalarFunctionSet(string name) : FunctionSet(std::move(name)) { } ScalarFunction ScalarFunctionSet::GetFunctionByArguments(ClientContext &context, const vector &arguments) { @@ -114177,7 +121025,7 @@ ScalarFunction ScalarFunctionSet::GetFunctionByArguments(ClientContext &context, return GetFunctionByOffset(index); } -AggregateFunctionSet::AggregateFunctionSet(string name) : FunctionSet(move(name)) { +AggregateFunctionSet::AggregateFunctionSet(string name) : FunctionSet(std::move(name)) { } AggregateFunction AggregateFunctionSet::GetFunctionByArguments(ClientContext &context, @@ -114210,7 +121058,7 @@ AggregateFunction AggregateFunctionSet::GetFunctionByArguments(ClientContext &co return GetFunctionByOffset(index); } -TableFunctionSet::TableFunctionSet(string name) : FunctionSet(move(name)) { +TableFunctionSet::TableFunctionSet(string name) : FunctionSet(std::move(name)) { } TableFunction TableFunctionSet::GetFunctionByArguments(ClientContext &context, const vector &arguments) { @@ -114238,7 +121086,7 @@ TableFunction TableFunctionSet::GetFunctionByArguments(ClientContext &context, c namespace duckdb { -// MacroFunction::MacroFunction(unique_ptr expression) : expression(move(expression)) {} +// MacroFunction::MacroFunction(unique_ptr expression) : expression(std::move(expression)) {} MacroFunction::MacroFunction(MacroType type) : type(type) { } @@ -114249,20 +121097,19 @@ string MacroFunction::ValidateArguments(MacroFunction ¯o_def, const string & // separate positional and default arguments for (auto &arg : function_expr.children) { - if ((arg->type == ExpressionType::VALUE_CONSTANT || arg->type == ExpressionType::VALUE_PARAMETER) && - !arg->alias.empty()) { + if (!arg->alias.empty()) { // default argument - if (macro_def.default_parameters.find(arg->alias) == macro_def.default_parameters.end()) { + if (!macro_def.default_parameters.count(arg->alias)) { return StringUtil::Format("Macro %s does not have default parameter %s!", name, arg->alias); - } else if (defaults.find(arg->alias) != defaults.end()) { + } else if (defaults.count(arg->alias)) { return StringUtil::Format("Duplicate default parameters %s!", arg->alias); } - defaults[arg->alias] = move(arg); + defaults[arg->alias] = std::move(arg); } else if (!defaults.empty()) { return "Positional parameters cannot come after parameters with a default value!"; } else { // positional argument - positionals.push_back(move(arg)); + positionals.push_back(std::move(arg)); } } @@ -114284,10 +121131,13 @@ string MacroFunction::ValidateArguments(MacroFunction ¯o_def, const string & return error; } - // fill in default value where this was not supplied + // Add the default values for parameters that have defaults, that were not explicitly assigned to for (auto it = macro_def.default_parameters.begin(); it != macro_def.default_parameters.end(); it++) { - if (defaults.find(it->first) == defaults.end()) { - defaults[it->first] = it->second->Copy(); + auto ¶meter_name = it->first; + auto ¶meter_default = it->second; + if (!defaults.count(parameter_name)) { + // This parameter was not set yet, set it with the default value + defaults[parameter_name] = parameter_default->Copy(); } } @@ -114329,6 +121179,7 @@ string MacroFunction::ToSQL(const string &schema, const string &name) { + namespace duckdb { struct PragmaQueries { @@ -114354,6 +121205,7 @@ string PragmaShow(ClientContext &context, const FunctionParameters ¶meters); + #include namespace duckdb { @@ -114501,6 +121353,40 @@ void PragmaFunctions::RegisterFunction(BuiltinFunctions &set) { +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/statement/export_statement.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + +namespace duckdb { + +class ExportStatement : public SQLStatement { +public: + explicit ExportStatement(unique_ptr info); + + unique_ptr info; + string database; + +protected: + ExportStatement(const ExportStatement &other); + +public: + unique_ptr Copy() const override; +}; + +} // namespace duckdb + + + namespace duckdb { @@ -114528,13 +121414,17 @@ string PragmaShowTablesExpanded(ClientContext &context, const FunctionParameters )"; } +string PragmaShowDatabases(ClientContext &context, const FunctionParameters ¶meters) { + return "SELECT database_name FROM duckdb_databases() WHERE NOT internal ORDER BY database_name;"; +} + string PragmaAllProfiling(ClientContext &context, const FunctionParameters ¶meters) { return "SELECT * FROM pragma_last_profiling_output() JOIN pragma_detailed_profiling_output() ON " "(pragma_last_profiling_output.operator_id);"; } string PragmaDatabaseList(ClientContext &context, const FunctionParameters ¶meters) { - return "SELECT * FROM pragma_database_list() ORDER BY 1;"; + return "SELECT * FROM pragma_database_list;"; } string PragmaCollations(ClientContext &context, const FunctionParameters ¶meters) { @@ -114542,7 +121432,11 @@ string PragmaCollations(ClientContext &context, const FunctionParameters ¶me } string PragmaFunctionsQuery(ClientContext &context, const FunctionParameters ¶meters) { - return "SELECT * FROM pragma_functions() ORDER BY 1;"; + return "SELECT function_name AS name, upper(function_type) AS type, parameter_types AS parameters, varargs, " + "return_type, has_side_effects AS side_effects" + " FROM duckdb_functions()" + " WHERE function_type IN ('scalar', 'aggregate')" + " ORDER BY 1;"; } string PragmaShow(ClientContext &context, const FunctionParameters ¶meters) { @@ -114565,7 +121459,7 @@ string PragmaImportDatabase(ClientContext &context, const FunctionParameters &pa auto &fs = FileSystem::GetFileSystem(context); auto *opener = FileSystem::GetFileOpener(context); - string query; + string final_query; // read the "shema.sql" and "load.sql" files vector files = {"schema.sql", "load.sql"}; for (auto &file : files) { @@ -114575,10 +121469,25 @@ string PragmaImportDatabase(ClientContext &context, const FunctionParameters &pa auto fsize = fs.GetFileSize(*handle); auto buffer = unique_ptr(new char[fsize]); fs.Read(*handle, buffer.get(), fsize); - - query += string(buffer.get(), fsize); + auto query = string(buffer.get(), fsize); + // Replace the placeholder with the path provided to IMPORT + if (file == "load.sql") { + Parser parser; + parser.ParseQuery(query); + auto copy_statements = std::move(parser.statements); + query.clear(); + for (auto &statement_p : copy_statements) { + D_ASSERT(statement_p->type == StatementType::COPY_STATEMENT); + auto &statement = (CopyStatement &)*statement_p; + auto &info = *statement.info; + auto file_name = fs.ExtractName(info.file_path); + info.file_path = fs.JoinPath(parameters.values[0].ToString(), file_name); + query += statement.ToString() + ";"; + } + } + final_query += query; } - return query; + return final_query; } string PragmaDatabaseSize(ClientContext &context, const FunctionParameters ¶meters) { @@ -114594,6 +121503,7 @@ void PragmaQueries::RegisterFunction(BuiltinFunctions &set) { set.AddFunction(PragmaFunction::PragmaCall("storage_info", PragmaStorageInfo, {LogicalType::VARCHAR})); set.AddFunction(PragmaFunction::PragmaStatement("show_tables", PragmaShowTables)); set.AddFunction(PragmaFunction::PragmaStatement("show_tables_expanded", PragmaShowTablesExpanded)); + set.AddFunction(PragmaFunction::PragmaStatement("show_databases", PragmaShowDatabases)); set.AddFunction(PragmaFunction::PragmaStatement("database_list", PragmaDatabaseList)); set.AddFunction(PragmaFunction::PragmaStatement("collations", PragmaCollations)); set.AddFunction(PragmaFunction::PragmaCall("show", PragmaShow, {LogicalType::VARCHAR})); @@ -114612,28 +121522,29 @@ namespace duckdb { PragmaFunction::PragmaFunction(string name, PragmaType pragma_type, pragma_query_t query, pragma_function_t function, vector arguments, LogicalType varargs) - : SimpleNamedParameterFunction(move(name), move(arguments), move(varargs)), type(pragma_type), query(query), - function(function) { + : SimpleNamedParameterFunction(std::move(name), std::move(arguments), std::move(varargs)), type(pragma_type), + query(query), function(function) { } PragmaFunction PragmaFunction::PragmaCall(const string &name, pragma_query_t query, vector arguments, LogicalType varargs) { - return PragmaFunction(name, PragmaType::PRAGMA_CALL, query, nullptr, move(arguments), move(varargs)); + return PragmaFunction(name, PragmaType::PRAGMA_CALL, query, nullptr, std::move(arguments), std::move(varargs)); } PragmaFunction PragmaFunction::PragmaCall(const string &name, pragma_function_t function, vector arguments, LogicalType varargs) { - return PragmaFunction(name, PragmaType::PRAGMA_CALL, nullptr, function, move(arguments), move(varargs)); + return PragmaFunction(name, PragmaType::PRAGMA_CALL, nullptr, function, std::move(arguments), std::move(varargs)); } PragmaFunction PragmaFunction::PragmaStatement(const string &name, pragma_query_t query) { vector types; - return PragmaFunction(name, PragmaType::PRAGMA_STATEMENT, query, nullptr, move(types), LogicalType::INVALID); + return PragmaFunction(name, PragmaType::PRAGMA_STATEMENT, query, nullptr, std::move(types), LogicalType::INVALID); } PragmaFunction PragmaFunction::PragmaStatement(const string &name, pragma_function_t function) { vector types; - return PragmaFunction(name, PragmaType::PRAGMA_STATEMENT, nullptr, function, move(types), LogicalType::INVALID); + return PragmaFunction(name, PragmaType::PRAGMA_STATEMENT, nullptr, function, std::move(types), + LogicalType::INVALID); } string PragmaFunction::ToString() { @@ -114661,6 +121572,7 @@ string PragmaFunction::ToString() { + namespace duckdb { struct Base64Fun { @@ -114768,6 +121680,7 @@ void EncodeFun::RegisterFunction(BuiltinFunctions &set) { + namespace duckdb { struct AgeFun { @@ -114818,6 +121731,10 @@ struct StrpTimeFun { static void RegisterFunction(BuiltinFunctions &set); }; +struct TimeBucketFun { + static void RegisterFunction(BuiltinFunctions &set); +}; + struct ToIntervalFun { static void RegisterFunction(BuiltinFunctions &set); }; @@ -114879,12 +121796,79 @@ void AgeFun::RegisterFunction(BuiltinFunctions &set) { +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/transaction/meta_transaction.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + + + +namespace duckdb { +class AttachedDatabase; +class ClientContext; +class Transaction; + +//! The MetaTransaction manages multiple transactions for different attached databases +class MetaTransaction { +public: + DUCKDB_API MetaTransaction(ClientContext &context, timestamp_t start_timestamp, idx_t catalog_version); + + ClientContext &context; + //! The timestamp when the transaction started + timestamp_t start_timestamp; + //! The catalog version when the transaction was started + idx_t catalog_version; + //! The validity checker of the transaction + ValidChecker transaction_validity; + //! Whether or not any transaction have made modifications + bool read_only; + //! The active query number + transaction_t active_query; + +public: + DUCKDB_API static MetaTransaction &Get(ClientContext &context); + timestamp_t GetCurrentTransactionStartTimestamp() { + return start_timestamp; + } + + Transaction &GetTransaction(AttachedDatabase *db); + + string Commit(); + void Rollback(); + + idx_t GetActiveQuery(); + void SetActiveQuery(transaction_t query_number); + + void ModifyDatabase(AttachedDatabase *db); + AttachedDatabase *ModifiedDatabase() { + return modified_database; + } + +private: + //! The set of active transactions for each database + unordered_map transactions; + //! The set of transactions in order of when they were started + vector all_transactions; + //! The database we are modifying - we can only modify one database per transaction + AttachedDatabase *modified_database; +}; + +} // namespace duckdb namespace duckdb { static timestamp_t GetTransactionTimestamp(ExpressionState &state) { - return state.GetContext().ActiveTransaction().start_timestamp; + return MetaTransaction::Get(state.GetContext()).start_timestamp; } static void CurrentTimeFunction(DataChunk &input, ExpressionState &state, Vector &result) { @@ -115388,28 +122372,33 @@ namespace duckdb { bool TryGetDatePartSpecifier(const string &specifier_p, DatePartSpecifier &result) { auto specifier = StringUtil::Lower(specifier_p); - if (specifier == "year" || specifier == "y" || specifier == "years") { + if (specifier == "year" || specifier == "yr" || specifier == "y" || specifier == "years" || specifier == "yrs") { result = DatePartSpecifier::YEAR; } else if (specifier == "month" || specifier == "mon" || specifier == "months" || specifier == "mons") { result = DatePartSpecifier::MONTH; } else if (specifier == "day" || specifier == "days" || specifier == "d" || specifier == "dayofmonth") { result = DatePartSpecifier::DAY; - } else if (specifier == "decade" || specifier == "decades") { + } else if (specifier == "decade" || specifier == "dec" || specifier == "decades" || specifier == "decs") { result = DatePartSpecifier::DECADE; - } else if (specifier == "century" || specifier == "centuries") { + } else if (specifier == "century" || specifier == "cent" || specifier == "centuries" || specifier == "c") { result = DatePartSpecifier::CENTURY; - } else if (specifier == "millennium" || specifier == "millennia" || specifier == "millenium") { + } else if (specifier == "millennium" || specifier == "mil" || specifier == "millenniums" || + specifier == "millennia" || specifier == "mils" || specifier == "millenium") { result = DatePartSpecifier::MILLENNIUM; - } else if (specifier == "microseconds" || specifier == "microsecond") { + } else if (specifier == "microseconds" || specifier == "microsecond" || specifier == "us" || specifier == "usec" || + specifier == "usecs" || specifier == "usecond" || specifier == "useconds") { result = DatePartSpecifier::MICROSECONDS; } else if (specifier == "milliseconds" || specifier == "millisecond" || specifier == "ms" || specifier == "msec" || - specifier == "msecs") { + specifier == "msecs" || specifier == "msecond" || specifier == "mseconds") { result = DatePartSpecifier::MILLISECONDS; - } else if (specifier == "second" || specifier == "seconds" || specifier == "s") { + } else if (specifier == "second" || specifier == "sec" || specifier == "seconds" || specifier == "secs" || + specifier == "s") { result = DatePartSpecifier::SECOND; - } else if (specifier == "minute" || specifier == "minutes" || specifier == "m") { + } else if (specifier == "minute" || specifier == "min" || specifier == "minutes" || specifier == "mins" || + specifier == "m") { result = DatePartSpecifier::MINUTE; - } else if (specifier == "hour" || specifier == "hours" || specifier == "h") { + } else if (specifier == "hour" || specifier == "hr" || specifier == "hours" || specifier == "hrs" || + specifier == "h") { result = DatePartSpecifier::HOUR; } else if (specifier == "epoch") { // seconds since 1970-01-01 @@ -115539,7 +122528,7 @@ static unique_ptr PropagateSimpleDatePartStatistics(vectorvalidity_stats) { result->validity_stats = child_stats[0]->validity_stats->Copy(); } - return move(result); + return std::move(result); } struct DatePart { @@ -115570,7 +122559,7 @@ struct DatePart { if (child_stats[0]->validity_stats) { result->validity_stats = child_stats[0]->validity_stats->Copy(); } - return move(result); + return std::move(result); } template @@ -116584,10 +123573,10 @@ void AddGenericDatePartOperator(BuiltinFunctions &set, const string &name, scala function_statistics_t date_stats, function_statistics_t ts_stats) { ScalarFunctionSet operator_set(name); operator_set.AddFunction( - ScalarFunction({LogicalType::DATE}, LogicalType::BIGINT, move(date_func), nullptr, nullptr, date_stats)); + ScalarFunction({LogicalType::DATE}, LogicalType::BIGINT, std::move(date_func), nullptr, nullptr, date_stats)); operator_set.AddFunction( - ScalarFunction({LogicalType::TIMESTAMP}, LogicalType::BIGINT, move(ts_func), nullptr, nullptr, ts_stats)); - operator_set.AddFunction(ScalarFunction({LogicalType::INTERVAL}, LogicalType::BIGINT, move(interval_func))); + ScalarFunction({LogicalType::TIMESTAMP}, LogicalType::BIGINT, std::move(ts_func), nullptr, nullptr, ts_stats)); + operator_set.AddFunction(ScalarFunction({LogicalType::INTERVAL}, LogicalType::BIGINT, std::move(interval_func))); set.AddFunction(operator_set); } @@ -116605,12 +123594,12 @@ void AddGenericTimePartOperator(BuiltinFunctions &set, const string &name, scala function_statistics_t time_stats) { ScalarFunctionSet operator_set(name); operator_set.AddFunction( - ScalarFunction({LogicalType::DATE}, LogicalType::BIGINT, move(date_func), nullptr, nullptr, date_stats)); + ScalarFunction({LogicalType::DATE}, LogicalType::BIGINT, std::move(date_func), nullptr, nullptr, date_stats)); operator_set.AddFunction( - ScalarFunction({LogicalType::TIMESTAMP}, LogicalType::BIGINT, move(ts_func), nullptr, nullptr, ts_stats)); - operator_set.AddFunction(ScalarFunction({LogicalType::INTERVAL}, LogicalType::BIGINT, move(interval_func))); + ScalarFunction({LogicalType::TIMESTAMP}, LogicalType::BIGINT, std::move(ts_func), nullptr, nullptr, ts_stats)); + operator_set.AddFunction(ScalarFunction({LogicalType::INTERVAL}, LogicalType::BIGINT, std::move(interval_func))); operator_set.AddFunction( - ScalarFunction({LogicalType::TIME}, LogicalType::BIGINT, move(time_func), nullptr, nullptr, time_stats)); + ScalarFunction({LogicalType::TIME}, LogicalType::BIGINT, std::move(time_func), nullptr, nullptr, time_stats)); set.AddFunction(operator_set); } @@ -116707,7 +123696,7 @@ struct StructDatePart { } Function::EraseArgument(bound_function, arguments, 0); - bound_function.return_type = LogicalType::STRUCT(move(struct_children)); + bound_function.return_type = LogicalType::STRUCT(std::move(struct_children)); return make_unique(bound_function.return_type, part_codes); } @@ -116831,7 +123820,7 @@ struct StructDatePart { ScalarFunction &bound_function) { auto stype = reader.ReadRequiredSerializable(); auto part_codes = reader.ReadRequiredList(); - return make_unique(move(stype), move(part_codes)); + return make_unique(std::move(stype), std::move(part_codes)); } template @@ -118000,7 +124989,7 @@ static unique_ptr DateTruncStatistics(vectorvalidity_stats) { result->validity_stats = child_stats[1]->validity_stats->Copy(); } - return move(result); + return std::move(result); } template @@ -118423,11 +125412,11 @@ idx_t StrfTimepecifierSize(StrTimeSpecifier specifier) { void StrTimeFormat::AddLiteral(string literal) { constant_size += literal.size(); - literals.push_back(move(literal)); + literals.push_back(std::move(literal)); } void StrTimeFormat::AddFormatSpecifier(string preceding_literal, StrTimeSpecifier specifier) { - AddLiteral(move(preceding_literal)); + AddLiteral(std::move(preceding_literal)); specifiers.push_back(specifier); } @@ -118441,7 +125430,7 @@ void StrfTimeFormat::AddFormatSpecifier(string preceding_literal, StrTimeSpecifi // constant size specifier constant_size += specifier_size; } - StrTimeFormat::AddFormatSpecifier(move(preceding_literal), specifier); + StrTimeFormat::AddFormatSpecifier(std::move(preceding_literal), specifier); } idx_t StrfTimeFormat::GetSpecifierLength(StrTimeSpecifier specifier, date_t date, dtime_t time, int32_t utc_offset, @@ -118635,7 +125624,7 @@ char *StrfTimeFormat::WriteDateSpecifier(StrTimeSpecifier specifier, date_t date } char *StrfTimeFormat::WriteStandardSpecifier(StrTimeSpecifier specifier, int32_t data[], const char *tz_name, - char *target) { + size_t tz_len, char *target) { // data contains [0] year, [1] month, [2] day, [3] hour, [4] minute, [5] second, [6] msec, [7] utc switch (specifier) { case StrTimeSpecifier::DAY_OF_MONTH_PADDED: @@ -118714,7 +125703,7 @@ char *StrfTimeFormat::WriteStandardSpecifier(StrTimeSpecifier specifier, int32_t } case StrTimeSpecifier::TZ_NAME: if (tz_name) { - strcpy(target, tz_name); + memcpy(target, tz_name, tz_len); target += strlen(tz_name); } break; @@ -118767,7 +125756,8 @@ void StrfTimeFormat::FormatString(date_t date, int32_t data[8], const char *tz_n if (is_date_specifier[i]) { target = WriteDateSpecifier(specifiers[i], date, target); } else { - target = WriteStandardSpecifier(specifiers[i], data, tz_name, target); + auto tz_len = tz_name ? strlen(tz_name) : 0; + target = WriteStandardSpecifier(specifiers[i], data, tz_name, tz_len, target); } } // copy the final literal into the target @@ -118942,11 +125932,11 @@ string StrTimeFormat::ParseFormatSpecifier(const string &format_string, StrTimeF string error = StrTimeFormat::ParseFormatSpecifier(subformat, locale_format); D_ASSERT(error.empty()); // add the previous literal to the first literal of the subformat - locale_format.literals[0] = move(current_literal) + locale_format.literals[0]; + locale_format.literals[0] = std::move(current_literal) + locale_format.literals[0]; current_literal = ""; // now push the subformat into the current format specifier for (idx_t i = 0; i < locale_format.specifiers.size(); i++) { - format.AddFormatSpecifier(move(locale_format.literals[i]), locale_format.specifiers[i]); + format.AddFormatSpecifier(std::move(locale_format.literals[i]), locale_format.specifiers[i]); } pos = i + 1; continue; @@ -118955,7 +125945,7 @@ string StrTimeFormat::ParseFormatSpecifier(const string &format_string, StrTimeF return "Unrecognized format for strftime/strptime: %" + string(1, format_char); } } - format.AddFormatSpecifier(move(current_literal), specifier); + format.AddFormatSpecifier(std::move(current_literal), specifier); current_literal = ""; pos = i + 1; } @@ -118964,13 +125954,13 @@ string StrTimeFormat::ParseFormatSpecifier(const string &format_string, StrTimeF if (pos < format_string.size()) { current_literal += format_string.substr(pos, format_string.size() - pos); } - format.AddLiteral(move(current_literal)); + format.AddLiteral(std::move(current_literal)); return string(); } struct StrfTimeBindData : public FunctionData { explicit StrfTimeBindData(StrfTimeFormat format_p, string format_string_p, bool is_null) - : format(move(format_p)), format_string(move(format_string_p)), is_null(is_null) { + : format(std::move(format_p)), format_string(std::move(format_string_p)), is_null(is_null) { } StrfTimeFormat format; @@ -119097,7 +126087,7 @@ void StrfTimeFun::RegisterFunction(BuiltinFunctions &set) { void StrpTimeFormat::AddFormatSpecifier(string preceding_literal, StrTimeSpecifier specifier) { numeric_width.push_back(NumericSpecifierWidth(specifier)); - StrTimeFormat::AddFormatSpecifier(move(preceding_literal), specifier); + StrTimeFormat::AddFormatSpecifier(std::move(preceding_literal), specifier); } int StrpTimeFormat::NumericSpecifierWidth(StrTimeSpecifier specifier) { @@ -119477,8 +126467,8 @@ bool StrpTimeFormat::Parse(string_t str, ParseResult &result) { pos++; } const auto tz_begin = data + pos; - // stop when we encounter a space or the end of the string - while (pos < size && !StringUtil::CharacterIsSpace(data[pos])) { + // stop when we encounter a non-tz character + while (pos < size && Timestamp::CharacterIsTimeZone(data[pos])) { pos++; } const auto tz_end = data + pos; @@ -119563,7 +126553,7 @@ bool StrpTimeFormat::Parse(string_t str, ParseResult &result) { struct StrpTimeBindData : public FunctionData { explicit StrpTimeBindData(StrpTimeFormat format_p, string format_string_p) - : format(move(format_p)), format_string(move(format_string_p)) { + : format(std::move(format_p)), format_string(std::move(format_string_p)) { } StrpTimeFormat format; @@ -119710,6 +126700,377 @@ void StrpTimeFun::RegisterFunction(BuiltinFunctions &set) { + + + + + + + + + +namespace duckdb { + +struct TimeBucket { + + // Use 2000-01-03 00:00:00 (Monday) as origin when bucket_width is days, hours, ... for TimescaleDB compatibility + // There are 10959 days between 1970-01-01 and 2000-01-03 + constexpr static const int64_t DEFAULT_ORIGIN_MICROS = 10959 * Interval::MICROS_PER_DAY; + // Use 2000-01-01 as origin when bucket_width is months, years, ... for TimescaleDB compatibility + // There are 360 months between 1970-01-01 and 2000-01-01 + constexpr static const int32_t DEFAULT_ORIGIN_MONTHS = 360; + + enum struct BucketWidthType { CONVERTIBLE_TO_MICROS, CONVERTIBLE_TO_MONTHS, UNCLASSIFIED }; + + static inline BucketWidthType ClassifyBucketWidth(const interval_t bucket_width) { + if (bucket_width.months == 0 && Interval::GetMicro(bucket_width) > 0) { + return BucketWidthType::CONVERTIBLE_TO_MICROS; + } else if (bucket_width.months > 0 && bucket_width.days == 0 && bucket_width.micros == 0) { + return BucketWidthType::CONVERTIBLE_TO_MONTHS; + } else { + return BucketWidthType::UNCLASSIFIED; + } + } + + static inline BucketWidthType ClassifyBucketWidthErrorThrow(const interval_t bucket_width) { + if (bucket_width.months == 0) { + int64_t bucket_width_micros = Interval::GetMicro(bucket_width); + if (bucket_width_micros <= 0) { + throw NotImplementedException("Period must be greater than 0"); + } + return BucketWidthType::CONVERTIBLE_TO_MICROS; + } else if (bucket_width.months != 0 && bucket_width.days == 0 && bucket_width.micros == 0) { + if (bucket_width.months < 0) { + throw NotImplementedException("Period must be greater than 0"); + } + return BucketWidthType::CONVERTIBLE_TO_MONTHS; + } else { + throw NotImplementedException("Month intervals cannot have day or time component"); + } + } + + template + static inline int32_t EpochMonths(T ts) { + date_t ts_date = Cast::template Operation(ts); + return (Date::ExtractYear(ts_date) - 1970) * 12 + Date::ExtractMonth(ts_date) - 1; + } + + static inline timestamp_t WidthConvertibleToMicrosCommon(int64_t bucket_width_micros, int64_t ts_micros, + int64_t origin_micros) { + origin_micros %= bucket_width_micros; + ts_micros = SubtractOperatorOverflowCheck::Operation(ts_micros, origin_micros); + + int64_t result_micros = (ts_micros / bucket_width_micros) * bucket_width_micros; + if (ts_micros < 0 && ts_micros % bucket_width_micros != 0) { + result_micros = + SubtractOperatorOverflowCheck::Operation(result_micros, bucket_width_micros); + } + result_micros += origin_micros; + + return Timestamp::FromEpochMicroSeconds(result_micros); + } + + static inline date_t WidthConvertibleToMonthsCommon(int32_t bucket_width_months, int32_t ts_months, + int32_t origin_months) { + origin_months %= bucket_width_months; + ts_months = SubtractOperatorOverflowCheck::Operation(ts_months, origin_months); + + int32_t result_months = (ts_months / bucket_width_months) * bucket_width_months; + if (ts_months < 0 && ts_months % bucket_width_months != 0) { + result_months = + SubtractOperatorOverflowCheck::Operation(result_months, bucket_width_months); + } + result_months += origin_months; + + int32_t year = + (result_months < 0 && result_months % 12 != 0) ? 1970 + result_months / 12 - 1 : 1970 + result_months / 12; + int32_t month = + (result_months < 0 && result_months % 12 != 0) ? result_months % 12 + 13 : result_months % 12 + 1; + + return Date::FromDate(year, month, 1); + } + + struct WidthConvertibleToMicrosBinaryOperator { + template + static inline TR Operation(TA bucket_width, TB ts) { + if (!Value::IsFinite(ts)) { + return Cast::template Operation(ts); + } + int64_t bucket_width_micros = Interval::GetMicro(bucket_width); + int64_t ts_micros = Timestamp::GetEpochMicroSeconds(Cast::template Operation(ts)); + return Cast::template Operation( + WidthConvertibleToMicrosCommon(bucket_width_micros, ts_micros, DEFAULT_ORIGIN_MICROS)); + } + }; + + struct WidthConvertibleToMonthsBinaryOperator { + template + static inline TR Operation(TA bucket_width, TB ts) { + if (!Value::IsFinite(ts)) { + return Cast::template Operation(ts); + } + int32_t ts_months = EpochMonths(ts); + return Cast::template Operation( + WidthConvertibleToMonthsCommon(bucket_width.months, ts_months, DEFAULT_ORIGIN_MONTHS)); + } + }; + + struct BinaryOperator { + template + static inline TR Operation(TA bucket_width, TB ts) { + BucketWidthType bucket_width_type = ClassifyBucketWidthErrorThrow(bucket_width); + switch (bucket_width_type) { + case BucketWidthType::CONVERTIBLE_TO_MICROS: + return WidthConvertibleToMicrosBinaryOperator::Operation(bucket_width, ts); + case BucketWidthType::CONVERTIBLE_TO_MONTHS: + return WidthConvertibleToMonthsBinaryOperator::Operation(bucket_width, ts); + default: + throw NotImplementedException("Bucket type not implemented for TIME_BUCKET"); + } + } + }; + + struct OffsetWidthConvertibleToMicrosTernaryOperator { + template + static inline TR Operation(TA bucket_width, TB ts, TC offset) { + if (!Value::IsFinite(ts)) { + return Cast::template Operation(ts); + } + int64_t bucket_width_micros = Interval::GetMicro(bucket_width); + int64_t ts_micros = Timestamp::GetEpochMicroSeconds( + Interval::Add(Cast::template Operation(ts), Interval::Invert(offset))); + return Cast::template Operation(Interval::Add( + WidthConvertibleToMicrosCommon(bucket_width_micros, ts_micros, DEFAULT_ORIGIN_MICROS), offset)); + } + }; + + struct OffsetWidthConvertibleToMonthsTernaryOperator { + template + static inline TR Operation(TA bucket_width, TB ts, TC offset) { + if (!Value::IsFinite(ts)) { + return Cast::template Operation(ts); + } + int32_t ts_months = EpochMonths(Interval::Add(ts, Interval::Invert(offset))); + return Interval::Add(Cast::template Operation(WidthConvertibleToMonthsCommon( + bucket_width.months, ts_months, DEFAULT_ORIGIN_MONTHS)), + offset); + } + }; + + struct OffsetTernaryOperator { + template + static inline TR Operation(TA bucket_width, TB ts, TC offset) { + BucketWidthType bucket_width_type = ClassifyBucketWidthErrorThrow(bucket_width); + switch (bucket_width_type) { + case BucketWidthType::CONVERTIBLE_TO_MICROS: + return OffsetWidthConvertibleToMicrosTernaryOperator::Operation(bucket_width, ts, + offset); + case BucketWidthType::CONVERTIBLE_TO_MONTHS: + return OffsetWidthConvertibleToMonthsTernaryOperator::Operation(bucket_width, ts, + offset); + default: + throw NotImplementedException("Bucket type not implemented for TIME_BUCKET"); + } + } + }; + + struct OriginWidthConvertibleToMicrosTernaryOperator { + template + static inline TR Operation(TA bucket_width, TB ts, TC origin) { + if (!Value::IsFinite(ts)) { + return Cast::template Operation(ts); + } + int64_t bucket_width_micros = Interval::GetMicro(bucket_width); + int64_t ts_micros = Timestamp::GetEpochMicroSeconds(Cast::template Operation(ts)); + int64_t origin_micros = Timestamp::GetEpochMicroSeconds(Cast::template Operation(origin)); + return Cast::template Operation( + WidthConvertibleToMicrosCommon(bucket_width_micros, ts_micros, origin_micros)); + } + }; + + struct OriginWidthConvertibleToMonthsTernaryOperator { + template + static inline TR Operation(TA bucket_width, TB ts, TC origin) { + if (!Value::IsFinite(ts)) { + return Cast::template Operation(ts); + } + int32_t ts_months = EpochMonths(ts); + int32_t origin_months = EpochMonths(origin); + return Cast::template Operation( + WidthConvertibleToMonthsCommon(bucket_width.months, ts_months, origin_months)); + } + }; + + struct OriginTernaryOperator { + template + static inline TR Operation(TA bucket_width, TB ts, TC origin, ValidityMask &mask, idx_t idx) { + if (!Value::IsFinite(origin)) { + mask.SetInvalid(idx); + return TR(); + } + BucketWidthType bucket_width_type = ClassifyBucketWidthErrorThrow(bucket_width); + switch (bucket_width_type) { + case BucketWidthType::CONVERTIBLE_TO_MICROS: + return OriginWidthConvertibleToMicrosTernaryOperator::Operation(bucket_width, ts, + origin); + case BucketWidthType::CONVERTIBLE_TO_MONTHS: + return OriginWidthConvertibleToMonthsTernaryOperator::Operation(bucket_width, ts, + origin); + default: + throw NotImplementedException("Bucket type not implemented for TIME_BUCKET"); + } + } + }; +}; + +template +static void TimeBucketFunction(DataChunk &args, ExpressionState &state, Vector &result) { + D_ASSERT(args.ColumnCount() == 2); + + auto &bucket_width_arg = args.data[0]; + auto &ts_arg = args.data[1]; + + if (bucket_width_arg.GetVectorType() == VectorType::CONSTANT_VECTOR) { + if (ConstantVector::IsNull(bucket_width_arg)) { + result.SetVectorType(VectorType::CONSTANT_VECTOR); + ConstantVector::SetNull(result, true); + } else { + interval_t bucket_width = *ConstantVector::GetData(bucket_width_arg); + TimeBucket::BucketWidthType bucket_width_type = TimeBucket::ClassifyBucketWidth(bucket_width); + switch (bucket_width_type) { + case TimeBucket::BucketWidthType::CONVERTIBLE_TO_MICROS: + BinaryExecutor::Execute( + bucket_width_arg, ts_arg, result, args.size(), + TimeBucket::WidthConvertibleToMicrosBinaryOperator::Operation); + break; + case TimeBucket::BucketWidthType::CONVERTIBLE_TO_MONTHS: + BinaryExecutor::Execute( + bucket_width_arg, ts_arg, result, args.size(), + TimeBucket::WidthConvertibleToMonthsBinaryOperator::Operation); + break; + case TimeBucket::BucketWidthType::UNCLASSIFIED: + BinaryExecutor::Execute(bucket_width_arg, ts_arg, result, args.size(), + TimeBucket::BinaryOperator::Operation); + break; + default: + throw NotImplementedException("Bucket type not implemented for TIME_BUCKET"); + } + } + } else { + BinaryExecutor::Execute(bucket_width_arg, ts_arg, result, args.size(), + TimeBucket::BinaryOperator::Operation); + } +} + +template +static void TimeBucketOffsetFunction(DataChunk &args, ExpressionState &state, Vector &result) { + D_ASSERT(args.ColumnCount() == 3); + + auto &bucket_width_arg = args.data[0]; + auto &ts_arg = args.data[1]; + auto &offset_arg = args.data[2]; + + if (bucket_width_arg.GetVectorType() == VectorType::CONSTANT_VECTOR) { + if (ConstantVector::IsNull(bucket_width_arg)) { + result.SetVectorType(VectorType::CONSTANT_VECTOR); + ConstantVector::SetNull(result, true); + } else { + interval_t bucket_width = *ConstantVector::GetData(bucket_width_arg); + TimeBucket::BucketWidthType bucket_width_type = TimeBucket::ClassifyBucketWidth(bucket_width); + switch (bucket_width_type) { + case TimeBucket::BucketWidthType::CONVERTIBLE_TO_MICROS: + TernaryExecutor::Execute( + bucket_width_arg, ts_arg, offset_arg, result, args.size(), + TimeBucket::OffsetWidthConvertibleToMicrosTernaryOperator::Operation); + break; + case TimeBucket::BucketWidthType::CONVERTIBLE_TO_MONTHS: + TernaryExecutor::Execute( + bucket_width_arg, ts_arg, offset_arg, result, args.size(), + TimeBucket::OffsetWidthConvertibleToMonthsTernaryOperator::Operation); + break; + case TimeBucket::BucketWidthType::UNCLASSIFIED: + TernaryExecutor::Execute( + bucket_width_arg, ts_arg, offset_arg, result, args.size(), + TimeBucket::OffsetTernaryOperator::Operation); + break; + default: + throw NotImplementedException("Bucket type not implemented for TIME_BUCKET"); + } + } + } else { + TernaryExecutor::Execute( + bucket_width_arg, ts_arg, offset_arg, result, args.size(), + TimeBucket::OffsetTernaryOperator::Operation); + } +} + +template +static void TimeBucketOriginFunction(DataChunk &args, ExpressionState &state, Vector &result) { + D_ASSERT(args.ColumnCount() == 3); + + auto &bucket_width_arg = args.data[0]; + auto &ts_arg = args.data[1]; + auto &origin_arg = args.data[2]; + + if (bucket_width_arg.GetVectorType() == VectorType::CONSTANT_VECTOR && + origin_arg.GetVectorType() == VectorType::CONSTANT_VECTOR) { + if (ConstantVector::IsNull(bucket_width_arg) || ConstantVector::IsNull(origin_arg) || + !Value::IsFinite(*ConstantVector::GetData(origin_arg))) { + result.SetVectorType(VectorType::CONSTANT_VECTOR); + ConstantVector::SetNull(result, true); + } else { + interval_t bucket_width = *ConstantVector::GetData(bucket_width_arg); + TimeBucket::BucketWidthType bucket_width_type = TimeBucket::ClassifyBucketWidth(bucket_width); + switch (bucket_width_type) { + case TimeBucket::BucketWidthType::CONVERTIBLE_TO_MICROS: + TernaryExecutor::Execute( + bucket_width_arg, ts_arg, origin_arg, result, args.size(), + TimeBucket::OriginWidthConvertibleToMicrosTernaryOperator::Operation); + break; + case TimeBucket::BucketWidthType::CONVERTIBLE_TO_MONTHS: + TernaryExecutor::Execute( + bucket_width_arg, ts_arg, origin_arg, result, args.size(), + TimeBucket::OriginWidthConvertibleToMonthsTernaryOperator::Operation); + break; + case TimeBucket::BucketWidthType::UNCLASSIFIED: + TernaryExecutor::ExecuteWithNulls( + bucket_width_arg, ts_arg, origin_arg, result, args.size(), + TimeBucket::OriginTernaryOperator::Operation); + break; + default: + throw NotImplementedException("Bucket type not implemented for TIME_BUCKET"); + } + } + } else { + TernaryExecutor::ExecuteWithNulls( + bucket_width_arg, ts_arg, origin_arg, result, args.size(), + TimeBucket::OriginTernaryOperator::Operation); + } +} + +void TimeBucketFun::RegisterFunction(BuiltinFunctions &set) { + ScalarFunctionSet time_bucket("time_bucket"); + time_bucket.AddFunction( + ScalarFunction({LogicalType::INTERVAL, LogicalType::DATE}, LogicalType::DATE, TimeBucketFunction)); + time_bucket.AddFunction(ScalarFunction({LogicalType::INTERVAL, LogicalType::TIMESTAMP}, LogicalType::TIMESTAMP, + TimeBucketFunction)); + time_bucket.AddFunction(ScalarFunction({LogicalType::INTERVAL, LogicalType::DATE, LogicalType::INTERVAL}, + LogicalType::DATE, TimeBucketOffsetFunction)); + time_bucket.AddFunction(ScalarFunction({LogicalType::INTERVAL, LogicalType::TIMESTAMP, LogicalType::INTERVAL}, + LogicalType::TIMESTAMP, TimeBucketOffsetFunction)); + time_bucket.AddFunction(ScalarFunction({LogicalType::INTERVAL, LogicalType::DATE, LogicalType::DATE}, + LogicalType::DATE, TimeBucketOriginFunction)); + time_bucket.AddFunction(ScalarFunction({LogicalType::INTERVAL, LogicalType::TIMESTAMP, LogicalType::TIMESTAMP}, + LogicalType::TIMESTAMP, TimeBucketOriginFunction)); + + set.AddFunction(time_bucket); +} + +} // namespace duckdb + + + + namespace duckdb { struct ToYearsOperator { @@ -119853,6 +127214,7 @@ void BuiltinFunctions::RegisterDateFunctions() { Register(); Register(); Register(); + Register(); Register(); } @@ -119870,6 +127232,7 @@ void BuiltinFunctions::RegisterDateFunctions() { + namespace duckdb { struct EnumFirst { @@ -119880,6 +127243,10 @@ struct EnumLast { static void RegisterFunction(BuiltinFunctions &set); }; +struct EnumCode { + static void RegisterFunction(BuiltinFunctions &set); +}; + struct EnumRange { static void RegisterFunction(BuiltinFunctions &set); }; @@ -119952,6 +127319,11 @@ static void EnumRangeBoundaryFunction(DataChunk &input, ExpressionState &state, result.Reference(val); } +static void EnumCodeFunction(DataChunk &input, ExpressionState &state, Vector &result) { + D_ASSERT(input.GetTypes().size() == 1); + result.Reinterpret(input.data[0]); +} + static void CheckEnumParameter(const Expression &expr) { if (expr.HasParameter()) { throw ParameterNotResolvedException(); @@ -119967,6 +127339,34 @@ unique_ptr BindEnumFunction(ClientContext &context, ScalarFunction return nullptr; } +unique_ptr BindEnumCodeFunction(ClientContext &context, ScalarFunction &bound_function, + vector> &arguments) { + CheckEnumParameter(*arguments[0]); + if (arguments[0]->return_type.id() != LogicalTypeId::ENUM) { + throw BinderException("This function needs an ENUM as an argument"); + } + + auto phy_type = EnumType::GetPhysicalType(arguments[0]->return_type); + switch (phy_type) { + case PhysicalType::UINT8: + bound_function.return_type = LogicalType(LogicalTypeId::UTINYINT); + break; + case PhysicalType::UINT16: + bound_function.return_type = LogicalType(LogicalTypeId::USMALLINT); + break; + case PhysicalType::UINT32: + bound_function.return_type = LogicalType(LogicalTypeId::UINTEGER); + break; + case PhysicalType::UINT64: + bound_function.return_type = LogicalType(LogicalTypeId::UBIGINT); + break; + default: + throw InternalException("Unsupported Enum Internal Type"); + } + + return nullptr; +} + unique_ptr BindEnumRangeBoundaryFunction(ClientContext &context, ScalarFunction &bound_function, vector> &arguments) { CheckEnumParameter(*arguments[0]); @@ -120002,6 +127402,13 @@ void EnumLast::RegisterFunction(BuiltinFunctions &set) { set.AddFunction(fun); } +void EnumCode::RegisterFunction(BuiltinFunctions &set) { + auto fun = + ScalarFunction("enum_code", {LogicalType::ANY}, LogicalType::ANY, EnumCodeFunction, BindEnumCodeFunction); + fun.null_handling = FunctionNullHandling::SPECIAL_HANDLING; + set.AddFunction(fun); +} + void EnumRange::RegisterFunction(BuiltinFunctions &set) { auto fun = ScalarFunction("enum_range", {LogicalType::ANY}, LogicalType::LIST(LogicalType::VARCHAR), EnumRangeFunction, BindEnumFunction); @@ -120025,6 +127432,7 @@ namespace duckdb { void BuiltinFunctions::RegisterEnumFunctions() { Register(); Register(); + Register(); Register(); Register(); } @@ -120043,6 +127451,7 @@ void BuiltinFunctions::RegisterEnumFunctions() { + namespace duckdb { class BoundFunctionExpression; @@ -120125,7 +127534,7 @@ void AliasFun::RegisterFunction(BuiltinFunctions &set) { namespace duckdb { struct ConstantOrNullBindData : public FunctionData { - explicit ConstantOrNullBindData(Value val) : value(move(val)) { + explicit ConstantOrNullBindData(Value val) : value(std::move(val)) { } Value value; @@ -120189,7 +127598,7 @@ ScalarFunction ConstantOrNull::GetFunction(const LogicalType &return_type) { } unique_ptr ConstantOrNull::Bind(Value value) { - return make_unique(move(value)); + return make_unique(std::move(value)); } bool ConstantOrNull::IsConstantOrNull(BoundFunctionExpression &expr, const Value &val) { @@ -120213,7 +127622,7 @@ unique_ptr ConstantOrNullBind(ClientContext &context, ScalarFuncti D_ASSERT(arguments.size() >= 2); auto value = ExpressionExecutor::EvaluateScalar(context, *arguments[0]); bound_function.return_type = arguments[0]->return_type; - return make_unique(move(value)); + return make_unique(std::move(value)); } void ConstantOrNull::RegisterFunction(BuiltinFunctions &set) { @@ -120234,7 +127643,7 @@ void ConstantOrNull::RegisterFunction(BuiltinFunctions &set) { namespace duckdb { struct CurrentSettingBindData : public FunctionData { - explicit CurrentSettingBindData(Value value_p) : value(move(value_p)) { + explicit CurrentSettingBindData(Value value_p) : value(std::move(value_p)) { } Value value; @@ -120452,7 +127861,7 @@ void GreatestFun::RegisterFunction(BuiltinFunctions &set) { namespace duckdb { struct StatsBindData : public FunctionData { - explicit StatsBindData(string stats_p = string()) : stats(move(stats_p)) { + explicit StatsBindData(string stats_p = string()) : stats(std::move(stats_p)) { } string stats; @@ -120880,7 +128289,6 @@ static void ListContainsOrPosition(DataChunk &args, ExpressionState &state, Vect case PhysicalType::VARCHAR: TemplatedContainsOrPosition(args, state, result); break; - case PhysicalType::MAP: case PhysicalType::STRUCT: case PhysicalType::LIST: TemplatedContainsOrPosition(args, state, result, true); @@ -121182,7 +128590,7 @@ struct ListAggregatesBindData : public FunctionData { }; ListAggregatesBindData::ListAggregatesBindData(const LogicalType &stype_p, unique_ptr aggr_expr_p) - : stype(stype_p), aggr_expr(move(aggr_expr_p)) { + : stype(stype_p), aggr_expr(std::move(aggr_expr_p)) { } ListAggregatesBindData::~ListAggregatesBindData() { @@ -121190,7 +128598,7 @@ ListAggregatesBindData::~ListAggregatesBindData() { struct StateVector { StateVector(idx_t count_p, unique_ptr aggr_expr_p) - : count(count_p), aggr_expr(move(aggr_expr_p)), state_vector(Vector(LogicalType::POINTER, count_p)) { + : count(count_p), aggr_expr(std::move(aggr_expr_p)), state_vector(Vector(LogicalType::POINTER, count_p)) { } ~StateVector() { @@ -121287,7 +128695,6 @@ struct UniqueFunctor { template static void ListAggregatesFunction(DataChunk &args, ExpressionState &state, Vector &result) { - auto count = args.size(); Vector &lists = args.data[0]; @@ -121310,6 +128717,7 @@ static void ListAggregatesFunction(DataChunk &args, ExpressionState &state, Vect auto lists_size = ListVector::GetListSize(lists); auto &child_vector = ListVector::GetEntry(lists); + child_vector.Flatten(lists_size); UnifiedVectorFormat child_data; child_vector.ToUnifiedFormat(lists_size, child_data); @@ -121359,7 +128767,7 @@ static void ListAggregatesFunction(DataChunk &args, ExpressionState &state, Vect // states vector is full, update if (states_idx == STANDARD_VECTOR_SIZE) { // update the aggregate state(s) - Vector slice = Vector(child_vector, sel_vector, states_idx); + Vector slice(child_vector, sel_vector, states_idx); aggr.function.update(&slice, aggr_input_data, 1, state_vector_update, states_idx); // reset values @@ -121375,7 +128783,7 @@ static void ListAggregatesFunction(DataChunk &args, ExpressionState &state, Vect // update the remaining elements of the last list(s) if (states_idx != 0) { - Vector slice = Vector(child_vector, sel_vector, states_idx); + Vector slice(child_vector, sel_vector, states_idx); aggr.function.update(&slice, aggr_input_data, 1, state_vector_update, states_idx); } @@ -121510,17 +128918,17 @@ ListAggregatesBindFunction(ClientContext &context, ScalarFunction &bound_functio // create the child expression and its type vector> children; auto expr = make_unique(Value(list_child_type)); - children.push_back(move(expr)); + children.push_back(std::move(expr)); // push any extra arguments into the list aggregate bind if (arguments.size() > 2) { for (idx_t i = 2; i < arguments.size(); i++) { - children.push_back(move(arguments[i])); + children.push_back(std::move(arguments[i])); } arguments.resize(2); } FunctionBinder function_binder(context); - auto bound_aggr_function = function_binder.BindAggregateFunction(aggr_function, move(children)); + auto bound_aggr_function = function_binder.BindAggregateFunction(aggr_function, std::move(children)); bound_function.arguments[0] = LogicalType::LIST(bound_aggr_function->function.arguments[0]); if (IS_AGGR) { @@ -121533,7 +128941,7 @@ ListAggregatesBindFunction(ClientContext &context, ScalarFunction &bound_functio bound_aggr_function->ToString()); } - return make_unique(bound_function.return_type, move(bound_aggr_function)); + return make_unique(bound_function.return_type, std::move(bound_aggr_function)); } template @@ -121560,8 +128968,9 @@ static unique_ptr ListAggregatesBind(ClientContext &context, Scala // look up the aggregate function in the catalog QueryErrorContext error_context(nullptr, 0); - auto func = (AggregateFunctionCatalogEntry *)Catalog::GetCatalog(context).GetEntry( - context, DEFAULT_SCHEMA, function_name, false, error_context); + auto func = + (AggregateFunctionCatalogEntry *)Catalog::GetSystemCatalog(context).GetEntry( + context, DEFAULT_SCHEMA, function_name, false, error_context); D_ASSERT(func->type == CatalogType::AGGREGATE_FUNCTION_ENTRY); if (is_parameter) { @@ -121759,7 +129168,7 @@ static unique_ptr ListConcatBind(ClientContext &context, ScalarFun for (const auto &argument : arguments) { child_type = LogicalType::MaxLogicalType(child_type, ListType::GetChildType(argument->return_type)); } - auto list_type = LogicalType::LIST(move(child_type)); + auto list_type = LogicalType::LIST(std::move(child_type)); bound_function.arguments[0] = list_type; bound_function.arguments[1] = list_type; @@ -122058,6 +129467,8 @@ void ListExtractFun::RegisterFunction(BuiltinFunctions &set) { + + namespace duckdb { struct ListLambdaBindData : public FunctionData { @@ -122080,7 +129491,7 @@ struct ListLambdaBindData : public FunctionData { }; ListLambdaBindData::ListLambdaBindData(const LogicalType &stype_p, unique_ptr lambda_expr_p) - : stype(stype_p), lambda_expr(move(lambda_expr_p)) { + : stype(stype_p), lambda_expr(std::move(lambda_expr_p)) { } unique_ptr ListLambdaBindData::Copy() const { @@ -122164,15 +129575,19 @@ static void ExecuteExpression(vector &types, vector &r // set the list child vector Vector slice(child_vector, sel, elem_cnt); + Vector second_slice(child_vector, sel, elem_cnt); slice.Flatten(elem_cnt); + second_slice.Flatten(elem_cnt); + input_chunk.data[0].Reference(slice); + input_chunk.data[1].Reference(second_slice); // set the other vectors vector slices; for (idx_t col_idx = 0; col_idx < args.ColumnCount() - 1; col_idx++) { slices.emplace_back(Vector(args.data[col_idx + 1], sel_vectors[col_idx], elem_cnt)); slices[col_idx].Flatten(elem_cnt); - input_chunk.data[col_idx + 1].Reference(slices[col_idx]); + input_chunk.data[col_idx + 2].Reference(slices[col_idx]); } // execute the lambda expression @@ -122237,6 +129652,7 @@ static void ListLambdaFunction(DataChunk &args, ExpressionState &state, Vector & vector types; types.push_back(child_vector.GetType()); + types.push_back(child_vector.GetType()); // skip the list column for (idx_t i = 1; i < args.ColumnCount(); i++) { @@ -122383,8 +129799,8 @@ static unique_ptr ListLambdaBind(ClientContext &context, ScalarFun D_ASSERT(arguments[0]->return_type.id() == LogicalTypeId::LIST); // get the lambda expression and put it in the bind info - auto lambda_expr = move(bound_lambda_expr.lambda_expr); - return make_unique(bound_function.return_type, move(lambda_expr)); + auto lambda_expr = std::move(bound_lambda_expr.lambda_expr); + return make_unique(bound_function.return_type, std::move(lambda_expr)); } static unique_ptr ListTransformBind(ClientContext &context, ScalarFunction &bound_function, @@ -122409,6 +129825,15 @@ static unique_ptr ListFilterBind(ClientContext &context, ScalarFun if (arguments[1]->expression_class != ExpressionClass::BOUND_LAMBDA) { throw BinderException("Invalid lambda expression!"); } + + // try to cast to boolean, if the return type of the lambda filter expression is not already boolean + auto &bound_lambda_expr = (BoundLambdaExpression &)*arguments[1]; + if (bound_lambda_expr.lambda_expr->return_type != LogicalType::BOOLEAN) { + auto cast_lambda_expr = + BoundCastExpression::AddCastToType(context, std::move(bound_lambda_expr.lambda_expr), LogicalType::BOOLEAN); + bound_lambda_expr.lambda_expr = std::move(cast_lambda_expr); + } + bound_function.return_type = arguments[0]->return_type; return ListLambdaBind<1>(context, bound_function, arguments); } @@ -122469,7 +129894,6 @@ struct ListSortBindData : public FunctionData { vector payload_types; ClientContext &context; - unique_ptr global_sort_state; RowLayout payload_layout; vector orders; @@ -122499,8 +129923,8 @@ ListSortBindData::ListSortBindData(OrderType order_type_p, OrderByNullType null_ // get the BoundOrderByNode auto idx_col_expr = make_unique_base(LogicalType::USMALLINT, 0); auto lists_col_expr = make_unique_base(child_type, 1); - orders.emplace_back(OrderType::ASCENDING, OrderByNullType::ORDER_DEFAULT, move(idx_col_expr)); - orders.emplace_back(order_type, null_order, move(lists_col_expr)); + orders.emplace_back(OrderType::ASCENDING, OrderByNullType::ORDER_DEFAULT, std::move(idx_col_expr)); + orders.emplace_back(order_type, null_order, std::move(lists_col_expr)); } unique_ptr ListSortBindData::Copy() const { @@ -122540,6 +129964,7 @@ void SinkDataChunk(Vector *child_vector, SelectionVector &sel, idx_t offset_list payload_chunk.Verify(); // sink + key_chunk.Flatten(); local_sort_state.SinkChunk(key_chunk, payload_chunk); data_to_sort = true; } @@ -122562,8 +129987,7 @@ static void ListSortFunction(DataChunk &args, ExpressionState &state, Vector &re // initialize the global and local sorting state auto &buffer_manager = BufferManager::GetBufferManager(info.context); - info.global_sort_state = make_unique(buffer_manager, info.orders, info.payload_layout); - auto &global_sort_state = *info.global_sort_state; + GlobalSortState global_sort_state(buffer_manager, info.orders, info.payload_layout); LocalSortState local_sort_state; local_sort_state.Initialize(global_sort_state, buffer_manager); @@ -122858,7 +130282,7 @@ static unique_ptr ListValueBind(ClientContext &context, ScalarFunc // this is more for completeness reasons bound_function.varargs = child_type; - bound_function.return_type = LogicalType::LIST(move(child_type)); + bound_function.return_type = LogicalType::LIST(std::move(child_type)); return make_unique(bound_function.return_type); } @@ -122871,10 +130295,10 @@ unique_ptr ListValueStats(ClientContext &context, FunctionStatis list_stats->child_stats->Merge(*child_stats[i]); } else { list_stats->child_stats.reset(); - return move(list_stats); + return std::move(list_stats); } } - return move(list_stats); + return std::move(list_stats); } void ListValueFun::RegisterFunction(BuiltinFunctions &set) { @@ -123172,17 +130596,14 @@ namespace duckdb { static void CardinalityFunction(DataChunk &args, ExpressionState &state, Vector &result) { auto &map = args.data[0]; - UnifiedVectorFormat list_data; UnifiedVectorFormat map_data; result.SetVectorType(VectorType::FLAT_VECTOR); auto result_data = FlatVector::GetData(result); auto &result_validity = FlatVector::Validity(result); map.ToUnifiedFormat(args.size(), map_data); - auto &children = StructVector::GetEntries(map); - children[0]->ToUnifiedFormat(args.size(), list_data); for (idx_t row = 0; row < args.size(); row++) { - auto list_entry = ((list_entry_t *)list_data.data)[list_data.sel->get_index(row)]; + auto list_entry = ((list_entry_t *)map_data.data)[map_data.sel->get_index(row)]; result_data[row] = list_entry.length; result_validity.Set(row, map_data.validity.RowIsValid(map_data.sel->get_index(row))); } @@ -123220,7 +130641,6 @@ void CardinalityFun::RegisterFunction(BuiltinFunctions &set) { - //===----------------------------------------------------------------------===// // DuckDB // @@ -123259,24 +130679,19 @@ using value_set_t = unordered_set; namespace duckdb { -// TODO: this doesn't recursively verify maps if maps are nested MapInvalidReason CheckMapValidity(Vector &map, idx_t count, const SelectionVector &sel) { D_ASSERT(map.GetType().id() == LogicalTypeId::MAP); UnifiedVectorFormat map_vdata; + map.ToUnifiedFormat(count, map_vdata); auto &map_validity = map_vdata.validity; - auto &key_vector = *(StructVector::GetEntries(map)[0]); + auto list_data = ListVector::GetData(map); + auto &keys = MapVector::GetKeys(map); UnifiedVectorFormat key_vdata; - key_vector.ToUnifiedFormat(count, key_vdata); - auto key_data = (list_entry_t *)key_vdata.data; + keys.ToUnifiedFormat(count, key_vdata); auto &key_validity = key_vdata.validity; - auto &key_entries = ListVector::GetEntry(key_vector); - UnifiedVectorFormat key_entry_vdata; - key_entries.ToUnifiedFormat(count, key_entry_vdata); - auto &entry_validity = key_entry_vdata.validity; - for (idx_t row = 0; row < count; row++) { auto mapped_row = sel.get_index(row); auto row_idx = map_vdata.sel->get_index(mapped_row); @@ -123285,17 +130700,14 @@ MapInvalidReason CheckMapValidity(Vector &map, idx_t count, const SelectionVecto continue; } row_idx = key_vdata.sel->get_index(row); - if (!key_validity.RowIsValid(row_idx)) { - return MapInvalidReason::NULL_KEY_LIST; - } value_set_t unique_keys; - for (idx_t i = 0; i < key_data[row_idx].length; i++) { - auto index = key_data[row_idx].offset + i; - index = key_entry_vdata.sel->get_index(index); - if (!entry_validity.RowIsValid(index)) { + for (idx_t i = 0; i < list_data[row_idx].length; i++) { + auto index = list_data[row_idx].offset + i; + index = key_vdata.sel->get_index(index); + if (!key_validity.RowIsValid(index)) { return MapInvalidReason::NULL_KEY; } - auto value = key_entries.GetValue(index); + auto value = keys.GetValue(index); auto result = unique_keys.insert(value); if (!result.second) { return MapInvalidReason::DUPLICATE_KEY; @@ -123336,28 +130748,19 @@ static void MapFunction(DataChunk &args, ExpressionState &state, Vector &result) } } - auto &child_entries = StructVector::GetEntries(result); - D_ASSERT(child_entries.size() == 2); - auto &key_vector = *child_entries[0]; - auto &value_vector = *child_entries[1]; - if (args.data.empty()) { - // no arguments: construct an empty map - ListVector::SetListSize(key_vector, 0); - key_vector.SetVectorType(VectorType::CONSTANT_VECTOR); - auto list_data = ConstantVector::GetData(key_vector); - list_data->offset = 0; - list_data->length = 0; + auto &key_vector = MapVector::GetKeys(result); + auto &value_vector = MapVector::GetValues(result); + auto list_data = ListVector::GetData(result); - ListVector::SetListSize(value_vector, 0); - value_vector.SetVectorType(VectorType::CONSTANT_VECTOR); - list_data = ConstantVector::GetData(value_vector); + if (args.data.empty()) { + ListVector::SetListSize(result, 0); list_data->offset = 0; list_data->length = 0; - result.Verify(args.size()); return; } + auto args_data = ListVector::GetData(args.data[0]); auto key_count = ListVector::GetListSize(args.data[0]); auto value_count = ListVector::GetListSize(args.data[1]); if (key_count != value_count) { @@ -123365,11 +130768,16 @@ static void MapFunction(DataChunk &args, ExpressionState &state, Vector &result) "Error in MAP creation: key list has a different size from value list (%lld keys, %lld values)", key_count, value_count); } + ListVector::Reserve(result, key_count); + ListVector::SetListSize(result, key_count); - key_vector.Reference(args.data[0]); - value_vector.Reference(args.data[1]); - MapConversionVerify(result, args.size()); + for (idx_t i = 0; i < args.size(); i++) { + list_data[i] = args_data[i]; + } + key_vector.Reference(ListVector::GetEntry(args.data[0])); + value_vector.Reference(ListVector::GetEntry(args.data[1])); + MapConversionVerify(result, args.size()); result.Verify(args.size()); } @@ -123397,8 +130805,9 @@ static unique_ptr MapBind(ClientContext &context, ScalarFunction & child_types.push_back(make_pair("value", empty)); } - //! this is more for completeness reasons - bound_function.return_type = LogicalType::MAP(move(child_types)); + bound_function.return_type = + LogicalType::MAP(ListType::GetChildType(child_types[0].second), ListType::GetChildType(child_types[1].second)); + return make_unique(bound_function.return_type); } @@ -123440,7 +130849,6 @@ static void MapExtractFunction(DataChunk &args, ExpressionState &state, Vector & if (args.data[1].GetType().id() == LogicalTypeId::SQLNULL) { //! We don't need to look through the map if the 'key' to look for is NULL - //! Because maps can't have NULL as key ListVector::SetListSize(result, 0); result.SetVectorType(VectorType::CONSTANT_VECTOR); auto list_data = ConstantVector::GetData(result); @@ -123453,21 +130861,20 @@ static void MapExtractFunction(DataChunk &args, ExpressionState &state, Vector & auto &map = args.data[0]; auto &key = args.data[1]; - UnifiedVectorFormat map_keys_data; - UnifiedVectorFormat key_data; + UnifiedVectorFormat map_data; auto &map_keys = MapVector::GetKeys(map); auto &map_values = MapVector::GetValues(map); - map_keys.ToUnifiedFormat(args.size(), map_keys_data); - key.ToUnifiedFormat(args.size(), key_data); + map.ToUnifiedFormat(args.size(), map_data); for (idx_t row = 0; row < args.size(); row++) { - idx_t row_index = map_keys_data.sel->get_index(row); - idx_t key_index = key_data.sel->get_index(row); - auto key_value = key.GetValue(key_index); - auto offsets = ListVector::Search(map_keys, key_value, row_index); - auto values = ListVector::GetValuesFromOffsets(map_values, offsets); + idx_t row_index = map_data.sel->get_index(row); + auto key_value = key.GetValue(row); + + list_entry_t entry = ListVector::GetData(map)[row_index]; + auto offsets = MapVector::Search(map_keys, args.size(), key_value, entry); + auto values = FlatVector::GetValuesFromOffsets(map_values, offsets); FillResult(values, result, row); } @@ -123514,123 +130921,13 @@ void MapExtractFun::RegisterFunction(BuiltinFunctions &set) { - namespace duckdb { -struct VectorInfo { - Vector &container; - list_entry_t &data; -}; - -static void MapStruct(Value &element, VectorInfo &keys, VectorInfo &values) { - D_ASSERT(element.type().id() == LogicalTypeId::STRUCT); - D_ASSERT(!element.IsNull()); - auto &key_value = StructValue::GetChildren(element); - auto &key = key_value[0]; - auto &value = key_value[1]; - - if (key.IsNull()) { - throw InvalidInputException("None of the keys of the map can be NULL"); - } - // Add to the inner key/value lists of the resulting map - ListVector::PushBack(keys.container, key); - ListVector::PushBack(values.container, value); -} - -// FIXME: this operation has a time complexity of O(n^2) -void CheckKeyUniqueness(VectorInfo &keys) { - auto end = keys.data.offset + keys.data.length; - auto &entries = ListVector::GetEntry(keys.container); - for (auto lhs = keys.data.offset; lhs < end; lhs++) { - auto element = entries.GetValue(lhs); - D_ASSERT(!element.IsNull()); - for (auto rhs = lhs + 1; rhs < end; rhs++) { - auto other = entries.GetValue(rhs); - D_ASSERT(!other.IsNull()); - - if (element.type() != other.type()) { - throw InvalidInputException("Not all keys are of the same type!"); - } - if (element == other) { - throw InvalidInputException("The given keys aren't unique"); - } - } - } -} - -static bool MapSingleList(VectorInfo &input, VectorInfo &keys, VectorInfo &values) { - // Get the length and offset of this list from the argument data - auto pair_amount = input.data.length; - auto input_offset = input.data.offset; - - // Loop over the list of structs - idx_t inserted_values = 0; - for (idx_t i = 0; i < pair_amount; i++) { - auto index = i + input_offset; - // Get the struct using the offset and the index; - auto element = input.container.GetValue(index); - if (element.IsNull()) { - continue; - } - MapStruct(element, keys, values); - inserted_values++; - } - // Set the length of the key value lists - keys.data.length = inserted_values; - values.data.length = inserted_values; - return inserted_values != 0; -} - static void MapFromEntriesFunction(DataChunk &args, ExpressionState &state, Vector &result) { - D_ASSERT(result.GetType().id() == LogicalTypeId::MAP); - - result.SetVectorType(duckdb::VectorType::FLAT_VECTOR); - - // Get the arguments vector - auto &input_list = args.data[0]; - auto arg_data = FlatVector::GetData(input_list); - auto &entries = ListVector::GetEntry(input_list); - - // Prepare the result vectors - auto &child_entries = StructVector::GetEntries(result); - D_ASSERT(child_entries.size() == 2); - auto &key_vector = *child_entries[0]; - auto &value_vector = *child_entries[1]; - auto &result_validity = FlatVector::Validity(result); - - // Get the offset+length data for the list(s) - auto key_data = FlatVector::GetData(key_vector); - auto value_data = FlatVector::GetData(value_vector); - - auto &key_validity = FlatVector::Validity(key_vector); - auto &value_validity = FlatVector::Validity(value_vector); - auto count = args.size(); - UnifiedVectorFormat input_list_data; - input_list.ToUnifiedFormat(count, input_list_data); - - // Current offset into the keys/values list - idx_t offset = 0; + result.Reinterpret(args.data[0]); - // Transform to mapped values - for (idx_t i = 0; i < count; i++) { - VectorInfo input {entries, arg_data[i]}; - VectorInfo keys {key_vector, key_data[i]}; - VectorInfo values {value_vector, value_data[i]}; - - keys.data.offset = offset; - values.data.offset = offset; - auto row_valid = MapSingleList(input, keys, values); - offset += keys.data.length; - - // Check validity - if (!row_valid || !input_list_data.validity.RowIsValid(i)) { - key_validity.SetInvalid(i); - value_validity.SetInvalid(i); - result_validity.SetInvalid(i); - } - } MapConversionVerify(result, count); result.Verify(count); @@ -123641,8 +130938,6 @@ static void MapFromEntriesFunction(DataChunk &args, ExpressionState &state, Vect static unique_ptr MapFromEntriesBind(ClientContext &context, ScalarFunction &bound_function, vector> &arguments) { - child_list_t child_types; - if (arguments.size() != 1) { throw InvalidInputException("The input argument must be a list of structs."); } @@ -123665,11 +130960,8 @@ static unique_ptr MapFromEntriesBind(ClientContext &context, Scala if (children.size() != 2) { throw InvalidInputException("The provided struct type should only contain 2 fields, a key and a value"); } - child_types.push_back(make_pair("key", LogicalType::LIST(children[0].second))); - child_types.push_back(make_pair("value", LogicalType::LIST(children[1].second))); - //! this is more for completeness reasons - bound_function.return_type = LogicalType::MAP(move(child_types)); + bound_function.return_type = LogicalType::MAP(elem_type); return make_unique(bound_function.return_type); } @@ -123695,6 +130987,7 @@ void MapFromEntriesFun::RegisterFunction(BuiltinFunctions &set) { + namespace duckdb { struct AbsFun { @@ -123793,6 +131086,10 @@ struct IsNanFun { static void RegisterFunction(BuiltinFunctions &set); }; +struct SignBitFun { + static void RegisterFunction(BuiltinFunctions &set); +}; + struct IsInfiniteFun { static void RegisterFunction(BuiltinFunctions &set); }; @@ -123817,6 +131114,7 @@ struct IsFiniteFun { + namespace duckdb { struct SinFun { @@ -123861,6 +131159,7 @@ struct Atan2Fun { + #include #include @@ -123975,17 +131274,17 @@ static unique_ptr PropagateAbsStats(ClientContext &context, Func max_val = MaxValue(AbsValue(current_min), current_max); } else { // if both current_min and current_max are > 0, then the abs is a no-op and can be removed entirely - *input.expr_ptr = move(input.expr.children[0]); - return move(child_stats[0]); + *input.expr_ptr = std::move(input.expr.children[0]); + return std::move(child_stats[0]); } new_min = Value::Numeric(expr.return_type, min_val); new_max = Value::Numeric(expr.return_type, max_val); expr.function.function = ScalarFunction::GetScalarUnaryFunction(expr.return_type); } - auto stats = - make_unique(expr.return_type, move(new_min), move(new_max), StatisticsType::LOCAL_STATS); + auto stats = make_unique(expr.return_type, std::move(new_min), std::move(new_max), + StatisticsType::LOCAL_STATS); stats->validity_stats = lstats.validity_stats->Copy(); - return move(stats); + return std::move(stats); } template @@ -124074,6 +131373,14 @@ struct HugeIntBitCntOperator { } }; +struct BitStringBitCntOperator { + template + static inline TR Operation(TA input) { + TR count = Bit::BitCount(input); + return count; + } +}; + void BitCountFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet functions("bit_count"); functions.AddFunction(ScalarFunction({LogicalType::TINYINT}, LogicalType::TINYINT, @@ -124086,6 +131393,8 @@ void BitCountFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunction::UnaryFunction)); functions.AddFunction(ScalarFunction({LogicalType::HUGEINT}, LogicalType::TINYINT, ScalarFunction::UnaryFunction)); + functions.AddFunction(ScalarFunction({LogicalType::BIT}, LogicalType::BIGINT, + ScalarFunction::UnaryFunction)); set.AddFunction(functions); } @@ -124698,6 +132007,25 @@ void IsNanFun::RegisterFunction(BuiltinFunctions &set) { set.AddFunction(funcs); } +//===--------------------------------------------------------------------===// +// signbit +//===--------------------------------------------------------------------===// +struct SignBitOperator { + template + static inline TR Operation(TA input) { + return std::signbit(input); + } +}; + +void SignBitFun::RegisterFunction(BuiltinFunctions &set) { + ScalarFunctionSet funcs("signbit"); + funcs.AddFunction(ScalarFunction({LogicalType::FLOAT}, LogicalType::BOOLEAN, + ScalarFunction::UnaryFunction)); + funcs.AddFunction(ScalarFunction({LogicalType::DOUBLE}, LogicalType::BOOLEAN, + ScalarFunction::UnaryFunction)); + set.AddFunction(funcs); +} + //===--------------------------------------------------------------------===// // isinf //===--------------------------------------------------------------------===// @@ -125005,6 +132333,7 @@ void EvenFun::RegisterFunction(BuiltinFunctions &set) { + namespace duckdb { struct UUIDFun { @@ -125108,7 +132437,7 @@ static void SetSeedFunction(DataChunk &args, ExpressionState &state, Vector &res auto &random_engine = RandomEngine::Get(info.context); for (idx_t i = 0; i < args.size(); i++) { - if (input_seeds[i] < -1.0 || input_seeds[i] > 1.0) { + if (input_seeds[i] < -1.0 || input_seeds[i] > 1.0 || Value::IsNan(input_seeds[i])) { throw Exception("SETSEED accepts seed values between -1.0 and 1.0, inclusive"); } uint32_t norm_seed = (input_seeds[i] + 1.0) * half_max; @@ -125171,6 +132500,7 @@ void BuiltinFunctions::RegisterMathFunctions() { Register(); Register(); + Register(); Register(); Register(); } @@ -125470,6 +132800,7 @@ dtime_t AddTimeOperator::Operation(interval_t left, dtime_t right) { + namespace duckdb { struct AddFun { @@ -125630,7 +132961,7 @@ struct DecimalArithmeticBindData : public FunctionData { unique_ptr Copy() const override { auto res = make_unique(); res->check_overflow = check_overflow; - return move(res); + return std::move(res); } bool Equals(const FunctionData &other_p) const override { @@ -125687,10 +133018,10 @@ static unique_ptr PropagateNumericStats(ClientContext &context, } expr.function.function = GetScalarIntegerFunction(expr.return_type.InternalType()); } - auto stats = - make_unique(expr.return_type, move(new_min), move(new_max), StatisticsType::LOCAL_STATS); + auto stats = make_unique(expr.return_type, std::move(new_min), std::move(new_max), + StatisticsType::LOCAL_STATS); stats->validity_stats = ValidityStatistics::Combine(lstats.validity_stats, rstats.validity_stats); - return move(stats); + return std::move(stats); } template @@ -125757,7 +133088,7 @@ unique_ptr BindDecimalAddSubtract(ClientContext &context, ScalarFu bound_function.statistics = PropagateNumericStats; } } - return move(bind_data); + return std::move(bind_data); } static void SerializeDecimalArithmetic(FieldWriter &writer, const FunctionData *bind_data_p, @@ -125789,7 +133120,7 @@ unique_ptr DeserializeDecimalArithmetic(ClientContext &context, Fi auto bind_data = make_unique(); bind_data->check_overflow = check_overflow; - return move(bind_data); + return std::move(bind_data); } unique_ptr NopDecimalBind(ClientContext &context, ScalarFunction &bound_function, @@ -125966,7 +133297,7 @@ struct DecimalNegateBindData : public FunctionData { unique_ptr Copy() const override { auto res = make_unique(); res->bound_type = bound_type; - return move(res); + return std::move(res); } bool Equals(const FunctionData &other_p) const override { @@ -126053,12 +133384,12 @@ static unique_ptr NegateBindStatistics(ClientContext &context, F new_min = Value(expr.return_type); new_max = Value(expr.return_type); } - auto stats = - make_unique(expr.return_type, move(new_min), move(new_max), StatisticsType::LOCAL_STATS); + auto stats = make_unique(expr.return_type, std::move(new_min), std::move(new_max), + StatisticsType::LOCAL_STATS); if (istats.validity_stats) { stats->validity_stats = istats.validity_stats->Copy(); } - return move(stats); + return std::move(stats); } ScalarFunction SubtractFun::GetFunction(const LogicalType &type) { @@ -126275,7 +133606,7 @@ unique_ptr BindDecimalMultiply(ClientContext &context, ScalarFunct bound_function.statistics = PropagateNumericStats; } - return move(bind_data); + return std::move(bind_data); } void MultiplyFun::RegisterFunction(BuiltinFunctions &set) { @@ -126500,6 +133831,36 @@ void ModFun::RegisterFunction(BuiltinFunctions &set) { +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/function/scalar/bit_functions.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +struct GetBitFun { + static void RegisterFunction(BuiltinFunctions &set); +}; + +struct SetBitFun { + static void RegisterFunction(BuiltinFunctions &set); +}; + +struct BitPositionFun { + static void RegisterFunction(BuiltinFunctions &set); +}; + +} // namespace duckdb + + namespace duckdb { @@ -126587,12 +133948,24 @@ struct BitwiseANDOperator { } }; +static void BitwiseANDOperation(DataChunk &args, ExpressionState &state, Vector &result) { + BinaryExecutor::Execute( + args.data[0], args.data[1], result, args.size(), [&](string_t rhs, string_t lhs) { + string_t target = StringVector::EmptyString(result, rhs.GetSize()); + + Bit::BitwiseAnd(rhs, lhs, target); + return target; + }); +} + void BitwiseAndFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet functions("&"); for (auto &type : LogicalType::Integral()) { functions.AddFunction( ScalarFunction({type, type}, type, GetScalarIntegerBinaryFunction(type))); } + functions.AddFunction(ScalarFunction({LogicalType::BIT, LogicalType::BIT}, LogicalType::BIT, BitwiseANDOperation)); + set.AddFunction(functions); } @@ -126606,12 +133979,23 @@ struct BitwiseOROperator { } }; +static void BitwiseOROperation(DataChunk &args, ExpressionState &state, Vector &result) { + BinaryExecutor::Execute( + args.data[0], args.data[1], result, args.size(), [&](string_t rhs, string_t lhs) { + string_t target = StringVector::EmptyString(result, rhs.GetSize()); + + Bit::BitwiseOr(rhs, lhs, target); + return target; + }); +} + void BitwiseOrFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet functions("|"); for (auto &type : LogicalType::Integral()) { functions.AddFunction( ScalarFunction({type, type}, type, GetScalarIntegerBinaryFunction(type))); } + functions.AddFunction(ScalarFunction({LogicalType::BIT, LogicalType::BIT}, LogicalType::BIT, BitwiseOROperation)); set.AddFunction(functions); } @@ -126625,12 +134009,51 @@ struct BitwiseXOROperator { } }; +static void BitwiseXOROperation(DataChunk &args, ExpressionState &state, Vector &result) { + BinaryExecutor::Execute( + args.data[0], args.data[1], result, args.size(), [&](string_t rhs, string_t lhs) { + string_t target = StringVector::EmptyString(result, rhs.GetSize()); + + Bit::BitwiseXor(rhs, lhs, target); + return target; + }); +} + void BitwiseXorFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet functions("xor"); for (auto &type : LogicalType::Integral()) { functions.AddFunction( ScalarFunction({type, type}, type, GetScalarIntegerBinaryFunction(type))); } + functions.AddFunction(ScalarFunction({LogicalType::BIT, LogicalType::BIT}, LogicalType::BIT, BitwiseXOROperation)); + set.AddFunction(functions); +} + +//===--------------------------------------------------------------------===// +// ~ [bitwise_not] +//===--------------------------------------------------------------------===// +struct BitwiseNotOperator { + template + static inline TR Operation(TA input) { + return ~input; + } +}; + +static void BitwiseNOTOperation(DataChunk &args, ExpressionState &state, Vector &result) { + UnaryExecutor::Execute(args.data[0], result, args.size(), [&](string_t input) { + string_t target = StringVector::EmptyString(result, input.GetSize()); + + Bit::BitwiseNot(input, target); + return target; + }); +} + +void BitwiseNotFun::RegisterFunction(BuiltinFunctions &set) { + ScalarFunctionSet functions("~"); + for (auto &type : LogicalType::Integral()) { + functions.AddFunction(ScalarFunction({type}, type, GetScalarIntegerUnaryFunction(type))); + } + functions.AddFunction(ScalarFunction({LogicalType::BIT}, LogicalType::BIT, BitwiseNOTOperation)); set.AddFunction(functions); } @@ -126666,12 +134089,35 @@ struct BitwiseShiftLeftOperator { } }; +static void BitwiseShiftLeftOperation(DataChunk &args, ExpressionState &state, Vector &result) { + BinaryExecutor::Execute( + args.data[0], args.data[1], result, args.size(), [&](string_t input, int32_t shift) { + int32_t max_shift = Bit::BitLength(input); + if (shift == 0) { + return input; + } + if (shift < 0) { + throw OutOfRangeException("Cannot left-shift by negative number %s", NumericHelper::ToString(shift)); + } + string_t target = StringVector::EmptyString(result, input.GetSize()); + + if (shift >= max_shift) { + Bit::SetEmptyBitString(target, input); + return target; + } + Bit::LeftShift(input, shift, target); + return target; + }); +} + void LeftShiftFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet functions("<<"); for (auto &type : LogicalType::Integral()) { functions.AddFunction( ScalarFunction({type, type}, type, GetScalarIntegerBinaryFunction(type))); } + functions.AddFunction( + ScalarFunction({LogicalType::BIT, LogicalType::INTEGER}, LogicalType::BIT, BitwiseShiftLeftOperation)); set.AddFunction(functions); } @@ -126690,31 +134136,94 @@ struct BitwiseShiftRightOperator { } }; +static void BitwiseShiftRightOperation(DataChunk &args, ExpressionState &state, Vector &result) { + BinaryExecutor::Execute( + args.data[0], args.data[1], result, args.size(), [&](string_t input, int32_t shift) { + int32_t max_shift = Bit::BitLength(input); + if (shift == 0) { + return input; + } + string_t target = StringVector::EmptyString(result, input.GetSize()); + if (shift < 0 || shift >= max_shift) { + Bit::SetEmptyBitString(target, input); + return target; + } + Bit::RightShift(input, shift, target); + return target; + }); +} + void RightShiftFun::RegisterFunction(BuiltinFunctions &set) { ScalarFunctionSet functions(">>"); for (auto &type : LogicalType::Integral()) { functions.AddFunction( ScalarFunction({type, type}, type, GetScalarIntegerBinaryFunction(type))); } + functions.AddFunction( + ScalarFunction({LogicalType::BIT, LogicalType::INTEGER}, LogicalType::BIT, BitwiseShiftRightOperation)); set.AddFunction(functions); } //===--------------------------------------------------------------------===// -// ~ [bitwise_not] +// get_bit //===--------------------------------------------------------------------===// -struct BitwiseNotOperator { - template - static inline TR Operation(TA input) { - return ~input; +struct GetBitOperator { + template + static inline TR Operation(TA input, TB n) { + if (n < 0 || (idx_t)n > Bit::BitLength(input) - 1) { + throw OutOfRangeException("bit index %s out of valid range (0..%s)", NumericHelper::ToString(n), + NumericHelper::ToString(Bit::BitLength(input) - 1)); + } + return Bit::GetBit(input, n); } }; -void BitwiseNotFun::RegisterFunction(BuiltinFunctions &set) { - ScalarFunctionSet functions("~"); - for (auto &type : LogicalType::Integral()) { - functions.AddFunction(ScalarFunction({type}, type, GetScalarIntegerUnaryFunction(type))); +void GetBitFun::RegisterFunction(BuiltinFunctions &set) { + set.AddFunction(ScalarFunction("get_bit", {LogicalType::BIT, LogicalType::INTEGER}, LogicalType::INTEGER, + ScalarFunction::BinaryFunction)); +} + +//===--------------------------------------------------------------------===// +// set_bit +//===--------------------------------------------------------------------===// +static void SetBitOperation(DataChunk &args, ExpressionState &state, Vector &result) { + TernaryExecutor::Execute( + args.data[0], args.data[1], args.data[2], result, args.size(), + [&](string_t input, int32_t n, int32_t new_value) { + if (new_value != 0 && new_value != 1) { + throw InvalidInputException("The new bit must be 1 or 0"); + } + if (n < 0 || (idx_t)n > Bit::BitLength(input) - 1) { + throw OutOfRangeException("bit index %s out of valid range (0..%s)", NumericHelper::ToString(n), + NumericHelper::ToString(Bit::BitLength(input) - 1)); + } + string_t target = StringVector::EmptyString(result, input.GetSize()); + Bit::SetBit(input, n, new_value, target); + return target; + }); +} + +void SetBitFun::RegisterFunction(BuiltinFunctions &set) { + set.AddFunction(ScalarFunction("set_bit", {LogicalType::BIT, LogicalType::INTEGER, LogicalType::INTEGER}, + LogicalType::BIT, SetBitOperation)); +} + +//===--------------------------------------------------------------------===// +// bit_position +//===--------------------------------------------------------------------===// +struct BitPositionOperator { + template + static inline TR Operation(TA substring, TB input) { + if (substring.GetSize() > input.GetSize()) { + return 0; + } + return Bit::BitPosition(substring, input); } - set.AddFunction(functions); +}; + +void BitPositionFun::RegisterFunction(BuiltinFunctions &set) { + set.AddFunction(ScalarFunction("bit_position", {LogicalType::BIT, LogicalType::BIT}, LogicalType::INTEGER, + ScalarFunction::BinaryFunction)); } } // namespace duckdb @@ -127222,6 +134731,7 @@ void BuiltinFunctions::RegisterPragmaFunctions() { + namespace duckdb { struct NextvalFun { @@ -127244,6 +134754,8 @@ struct CurrvalFun { + + namespace duckdb { struct NextvalBindData : public FunctionData { @@ -127264,7 +134776,7 @@ struct NextvalBindData : public FunctionData { }; struct CurrentSequenceValueOperator { - static int64_t Operation(Transaction &transaction, SequenceCatalogEntry *seq) { + static int64_t Operation(DuckTransaction &transaction, SequenceCatalogEntry *seq) { lock_guard seqlock(seq->lock); int64_t result; if (seq->usage_count == 0u) { @@ -127276,7 +134788,7 @@ struct CurrentSequenceValueOperator { }; struct NextSequenceValueOperator { - static int64_t Operation(Transaction &transaction, SequenceCatalogEntry *seq) { + static int64_t Operation(DuckTransaction &transaction, SequenceCatalogEntry *seq) { lock_guard seqlock(seq->lock); int64_t result; result = seq->counter; @@ -127308,14 +134820,12 @@ struct NextSequenceValueOperator { } }; -struct NextValData { - NextValData(NextvalBindData &bind_data_p, Transaction &transaction_p) - : bind_data(bind_data_p), transaction(transaction_p) { - } - - NextvalBindData &bind_data; - Transaction &transaction; -}; +SequenceCatalogEntry *BindSequence(ClientContext &context, const string &name) { + auto qname = QualifiedName::Parse(name); + // fetch the sequence from the catalog + Binder::BindSchemaOrCatalog(context, qname.catalog, qname.schema); + return Catalog::GetEntry(context, qname.catalog, qname.schema, qname.name); +} template static void NextValFunction(DataChunk &args, ExpressionState &state, Vector &result) { @@ -127324,8 +134834,8 @@ static void NextValFunction(DataChunk &args, ExpressionState &state, Vector &res auto &input = args.data[0]; auto &context = state.GetContext(); - auto &transaction = Transaction::GetTransaction(context); if (info.sequence) { + auto &transaction = DuckTransaction::Get(context, *info.sequence->catalog); // sequence to use is hard coded // increment the sequence result.SetVectorType(VectorType::FLAT_VECTOR); @@ -127335,14 +134845,12 @@ static void NextValFunction(DataChunk &args, ExpressionState &state, Vector &res result_data[i] = OP::Operation(transaction, info.sequence); } } else { - NextValData next_val_input(info, transaction); // sequence to use comes from the input UnaryExecutor::Execute(input, result, args.size(), [&](string_t value) { - auto qname = QualifiedName::Parse(value.GetString()); // fetch the sequence from the catalog - auto sequence = - Catalog::GetCatalog(context).GetEntry(context, qname.schema, qname.name); + auto sequence = BindSequence(context, value.GetString()); // finally get the next value from the sequence + auto &transaction = DuckTransaction::Get(context, *sequence->catalog); return OP::Operation(transaction, sequence); }); } @@ -127356,17 +134864,16 @@ static unique_ptr NextValBind(ClientContext &context, ScalarFuncti // evaluate the constant and perform the catalog lookup already auto seqname = ExpressionExecutor::EvaluateScalar(context, *arguments[0]); if (!seqname.IsNull()) { - auto qname = QualifiedName::Parse(seqname.ToString()); - sequence = Catalog::GetCatalog(context).GetEntry(context, qname.schema, qname.name); + sequence = BindSequence(context, seqname.ToString()); } } return make_unique(sequence); } -static void NextValDependency(BoundFunctionExpression &expr, unordered_set &dependencies) { +static void NextValDependency(BoundFunctionExpression &expr, DependencyList &dependencies) { auto &info = (NextvalBindData &)*expr.bind_info; if (info.sequence) { - dependencies.insert(info.sequence); + dependencies.AddDependency(info.sequence); } } @@ -127426,6 +134933,476 @@ void ASCII::RegisterFunction(BuiltinFunctions &set) { +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/vector_operations/generic_executor.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + +#include + +namespace duckdb { + +struct PrimitiveTypeState { + UnifiedVectorFormat main_data; + + void PrepareVector(Vector &input, idx_t count) { + input.ToUnifiedFormat(count, main_data); + } +}; + +template +struct PrimitiveType { + PrimitiveType() { + } + PrimitiveType(INPUT_TYPE val) : val(val) { + } // NOLINT: allow implicit cast + + INPUT_TYPE val; + + using STRUCT_STATE = PrimitiveTypeState; + + static bool ConstructType(STRUCT_STATE &state, idx_t i, PrimitiveType &result) { + auto &vdata = state.main_data; + auto idx = vdata.sel->get_index(i); + auto ptr = (INPUT_TYPE *)vdata.data; + result.val = ptr[idx]; + return true; + } + + static void AssignResult(Vector &result, idx_t i, PrimitiveType value) { + auto result_data = FlatVector::GetData(result); + result_data[i] = value.val; + } +}; + +template +struct StructTypeState { + UnifiedVectorFormat main_data; + UnifiedVectorFormat child_data[CHILD_COUNT]; + + void PrepareVector(Vector &input, idx_t count) { + auto &entries = StructVector::GetEntries(input); + + input.ToUnifiedFormat(count, main_data); + + for (idx_t i = 0; i < CHILD_COUNT; i++) { + entries[i]->ToUnifiedFormat(count, child_data[i]); + } + } +}; + +template +struct StructTypeUnary { + A_TYPE a_val; + + using STRUCT_STATE = StructTypeState<1>; + + static bool ConstructType(STRUCT_STATE &state, idx_t i, StructTypeUnary &result) { + auto &a_data = state.child_data[0]; + auto a_idx = a_data.sel->get_index(i); + if (!a_data.validity.RowIsValid(a_idx)) { + return false; + } + auto a_ptr = (A_TYPE *)a_data.data; + result.a_val = a_ptr[a_idx]; + return true; + } + + static void AssignResult(Vector &result, idx_t i, StructTypeUnary value) { + auto &entries = StructVector::GetEntries(result); + + auto a_data = FlatVector::GetData(*entries[0]); + a_data[i] = value.a_val; + } +}; + +template +struct StructTypeBinary { + A_TYPE a_val; + B_TYPE b_val; + + using STRUCT_STATE = StructTypeState<2>; + + static bool ConstructType(STRUCT_STATE &state, idx_t i, StructTypeBinary &result) { + auto &a_data = state.child_data[0]; + auto &b_data = state.child_data[1]; + + auto a_idx = a_data.sel->get_index(i); + auto b_idx = b_data.sel->get_index(i); + if (!a_data.validity.RowIsValid(a_idx) || !b_data.validity.RowIsValid(b_idx)) { + return false; + } + auto a_ptr = (A_TYPE *)a_data.data; + auto b_ptr = (B_TYPE *)b_data.data; + result.a_val = a_ptr[a_idx]; + result.b_val = b_ptr[b_idx]; + return true; + } + + static void AssignResult(Vector &result, idx_t i, StructTypeBinary value) { + auto &entries = StructVector::GetEntries(result); + + auto a_data = FlatVector::GetData(*entries[0]); + auto b_data = FlatVector::GetData(*entries[1]); + a_data[i] = value.a_val; + b_data[i] = value.b_val; + } +}; + +template +struct StructTypeTernary { + A_TYPE a_val; + B_TYPE b_val; + C_TYPE c_val; + + using STRUCT_STATE = StructTypeState<3>; + + static bool ConstructType(STRUCT_STATE &state, idx_t i, StructTypeTernary &result) { + auto &a_data = state.child_data[0]; + auto &b_data = state.child_data[1]; + auto &c_data = state.child_data[2]; + + auto a_idx = a_data.sel->get_index(i); + auto b_idx = b_data.sel->get_index(i); + auto c_idx = c_data.sel->get_index(i); + if (!a_data.validity.RowIsValid(a_idx) || !b_data.validity.RowIsValid(b_idx) || + !c_data.validity.RowIsValid(c_idx)) { + return false; + } + auto a_ptr = (A_TYPE *)a_data.data; + auto b_ptr = (B_TYPE *)b_data.data; + auto c_ptr = (C_TYPE *)c_data.data; + result.a_val = a_ptr[a_idx]; + result.b_val = b_ptr[b_idx]; + result.c_val = c_ptr[c_idx]; + return true; + } + + static void AssignResult(Vector &result, idx_t i, StructTypeTernary value) { + auto &entries = StructVector::GetEntries(result); + + auto a_data = FlatVector::GetData(*entries[0]); + auto b_data = FlatVector::GetData(*entries[1]); + auto c_data = FlatVector::GetData(*entries[2]); + a_data[i] = value.a_val; + b_data[i] = value.b_val; + c_data[i] = value.c_val; + } +}; + +template +struct StructTypeQuaternary { + A_TYPE a_val; + B_TYPE b_val; + C_TYPE c_val; + D_TYPE d_val; + + using STRUCT_STATE = StructTypeState<4>; + + static bool ConstructType(STRUCT_STATE &state, idx_t i, + StructTypeQuaternary &result) { + auto &a_data = state.child_data[0]; + auto &b_data = state.child_data[1]; + auto &c_data = state.child_data[2]; + auto &d_data = state.child_data[3]; + + auto a_idx = a_data.sel->get_index(i); + auto b_idx = b_data.sel->get_index(i); + auto c_idx = c_data.sel->get_index(i); + auto d_idx = d_data.sel->get_index(i); + if (!a_data.validity.RowIsValid(a_idx) || !b_data.validity.RowIsValid(b_idx) || + !c_data.validity.RowIsValid(c_idx) || !d_data.validity.RowIsValid(d_idx)) { + return false; + } + auto a_ptr = (A_TYPE *)a_data.data; + auto b_ptr = (B_TYPE *)b_data.data; + auto c_ptr = (C_TYPE *)c_data.data; + auto d_ptr = (D_TYPE *)d_data.data; + result.a_val = a_ptr[a_idx]; + result.b_val = b_ptr[b_idx]; + result.c_val = c_ptr[c_idx]; + result.d_val = d_ptr[d_idx]; + return true; + } + + static void AssignResult(Vector &result, idx_t i, StructTypeQuaternary value) { + auto &entries = StructVector::GetEntries(result); + + auto a_data = FlatVector::GetData(*entries[0]); + auto b_data = FlatVector::GetData(*entries[1]); + auto c_data = FlatVector::GetData(*entries[2]); + auto d_data = FlatVector::GetData(*entries[3]); + + a_data[i] = value.a_val; + b_data[i] = value.b_val; + c_data[i] = value.c_val; + d_data[i] = value.d_val; + } +}; + +//! The GenericExecutor can handle struct types in addition to primitive types +struct GenericExecutor { +private: + template + static void ExecuteUnaryInternal(Vector &input, Vector &result, idx_t count, FUNC &fun) { + auto constant = input.GetVectorType() == VectorType::CONSTANT_VECTOR; + + typename A_TYPE::STRUCT_STATE state; + state.PrepareVector(input, count); + + for (idx_t i = 0; i < (constant ? 1 : count); i++) { + auto idx = state.main_data.sel->get_index(i); + if (!state.main_data.validity.RowIsValid(idx)) { + FlatVector::SetNull(result, i, true); + continue; + } + A_TYPE input; + if (!A_TYPE::ConstructType(state, i, input)) { + FlatVector::SetNull(result, i, true); + continue; + } + RESULT_TYPE::AssignResult(result, i, fun(input)); + } + if (constant) { + result.SetVectorType(VectorType::CONSTANT_VECTOR); + } + } + + template + static void ExecuteBinaryInternal(Vector &a, Vector &b, Vector &result, idx_t count, FUNC &fun) { + auto constant = + a.GetVectorType() == VectorType::CONSTANT_VECTOR && b.GetVectorType() == VectorType::CONSTANT_VECTOR; + + typename A_TYPE::STRUCT_STATE a_state; + typename B_TYPE::STRUCT_STATE b_state; + a_state.PrepareVector(a, count); + b_state.PrepareVector(b, count); + + for (idx_t i = 0; i < (constant ? 1 : count); i++) { + auto a_idx = a_state.main_data.sel->get_index(i); + auto b_idx = a_state.main_data.sel->get_index(i); + if (!a_state.main_data.validity.RowIsValid(a_idx) || !b_state.main_data.validity.RowIsValid(b_idx)) { + FlatVector::SetNull(result, i, true); + continue; + } + A_TYPE a_val; + B_TYPE b_val; + if (!A_TYPE::ConstructType(a_state, i, a_val) || !B_TYPE::ConstructType(b_state, i, b_val)) { + FlatVector::SetNull(result, i, true); + continue; + } + RESULT_TYPE::AssignResult(result, i, fun(a_val, b_val)); + } + if (constant) { + result.SetVectorType(VectorType::CONSTANT_VECTOR); + } + } + + template + static void ExecuteTernaryInternal(Vector &a, Vector &b, Vector &c, Vector &result, idx_t count, FUNC &fun) { + auto constant = a.GetVectorType() == VectorType::CONSTANT_VECTOR && + b.GetVectorType() == VectorType::CONSTANT_VECTOR && + c.GetVectorType() == VectorType::CONSTANT_VECTOR; + + typename A_TYPE::STRUCT_STATE a_state; + typename B_TYPE::STRUCT_STATE b_state; + typename C_TYPE::STRUCT_STATE c_state; + + a_state.PrepareVector(a, count); + b_state.PrepareVector(b, count); + c_state.PrepareVector(c, count); + + for (idx_t i = 0; i < (constant ? 1 : count); i++) { + auto a_idx = a_state.main_data.sel->get_index(i); + auto b_idx = a_state.main_data.sel->get_index(i); + auto c_idx = a_state.main_data.sel->get_index(i); + if (!a_state.main_data.validity.RowIsValid(a_idx) || !b_state.main_data.validity.RowIsValid(b_idx) || + !c_state.main_data.validity.RowIsValid(c_idx)) { + FlatVector::SetNull(result, i, true); + continue; + } + A_TYPE a_val; + B_TYPE b_val; + C_TYPE c_val; + if (!A_TYPE::ConstructType(a_state, i, a_val) || !B_TYPE::ConstructType(b_state, i, b_val) || + !C_TYPE::ConstructType(c_state, i, c_val)) { + FlatVector::SetNull(result, i, true); + continue; + } + RESULT_TYPE::AssignResult(result, i, fun(a_val, b_val, c_val)); + } + if (constant) { + result.SetVectorType(VectorType::CONSTANT_VECTOR); + } + } + + template + static void ExecuteQuaternaryInternal(Vector &a, Vector &b, Vector &c, Vector &d, Vector &result, idx_t count, + FUNC &fun) { + auto constant = + a.GetVectorType() == VectorType::CONSTANT_VECTOR && b.GetVectorType() == VectorType::CONSTANT_VECTOR && + c.GetVectorType() == VectorType::CONSTANT_VECTOR && d.GetVectorType() == VectorType::CONSTANT_VECTOR; + + typename A_TYPE::STRUCT_STATE a_state; + typename B_TYPE::STRUCT_STATE b_state; + typename C_TYPE::STRUCT_STATE c_state; + typename D_TYPE::STRUCT_STATE d_state; + + a_state.PrepareVector(a, count); + b_state.PrepareVector(b, count); + c_state.PrepareVector(c, count); + d_state.PrepareVector(d, count); + + for (idx_t i = 0; i < (constant ? 1 : count); i++) { + auto a_idx = a_state.main_data.sel->get_index(i); + auto b_idx = a_state.main_data.sel->get_index(i); + auto c_idx = a_state.main_data.sel->get_index(i); + auto d_idx = a_state.main_data.sel->get_index(i); + if (!a_state.main_data.validity.RowIsValid(a_idx) || !b_state.main_data.validity.RowIsValid(b_idx) || + !c_state.main_data.validity.RowIsValid(c_idx) || !d_state.main_data.validity.RowIsValid(d_idx)) { + FlatVector::SetNull(result, i, true); + continue; + } + A_TYPE a_val; + B_TYPE b_val; + C_TYPE c_val; + D_TYPE d_val; + if (!A_TYPE::ConstructType(a_state, i, a_val) || !B_TYPE::ConstructType(b_state, i, b_val) || + !C_TYPE::ConstructType(c_state, i, c_val) || !D_TYPE::ConstructType(d_state, i, d_val)) { + FlatVector::SetNull(result, i, true); + continue; + } + RESULT_TYPE::AssignResult(result, i, fun(a_val, b_val, c_val, d_val)); + } + if (constant) { + result.SetVectorType(VectorType::CONSTANT_VECTOR); + } + } + +public: + template > + static void ExecuteUnary(Vector &input, Vector &result, idx_t count, FUNC fun) { + ExecuteUnaryInternal(input, result, count, fun); + } + template > + static void ExecuteBinary(Vector &a, Vector &b, Vector &result, idx_t count, FUNC fun) { + ExecuteBinaryInternal(a, b, result, count, fun); + } + template > + static void ExecuteTernary(Vector &a, Vector &b, Vector &c, Vector &result, idx_t count, FUNC fun) { + ExecuteTernaryInternal(a, b, c, result, count, fun); + } + template > + static void ExecuteQuaternary(Vector &a, Vector &b, Vector &c, Vector &d, Vector &result, idx_t count, FUNC fun) { + ExecuteQuaternaryInternal(a, b, c, d, result, count, fun); + } +}; + +} // namespace duckdb + + + +namespace duckdb { + +static string_t BarScalarFunction(double x, double min, double max, double max_width, string &result) { + static const char *FULL_BLOCK = UnicodeBar::FullBlock(); + static const char *const *PARTIAL_BLOCKS = UnicodeBar::PartialBlocks(); + static const idx_t PARTIAL_BLOCKS_COUNT = UnicodeBar::PartialBlocksCount(); + + if (!Value::IsFinite(max_width)) { + throw ValueOutOfRangeException("Max bar width must not be NaN or infinity"); + } + if (max_width < 1) { + throw ValueOutOfRangeException("Max bar width must be >= 1"); + } + if (max_width > 1000) { + throw ValueOutOfRangeException("Max bar width must be <= 1000"); + } + + double width; + + if (Value::IsNan(x) || Value::IsNan(min) || Value::IsNan(max) || x <= min) { + width = 0; + } else if (x >= max) { + width = max_width; + } else { + width = max_width * (x - min) / (max - min); + } + + if (!Value::IsFinite(width)) { + throw ValueOutOfRangeException("Bar width must not be NaN or infinity"); + } + + result.clear(); + + int32_t width_as_int = static_cast(width * PARTIAL_BLOCKS_COUNT); + idx_t full_blocks_count = (width_as_int / PARTIAL_BLOCKS_COUNT); + for (idx_t i = 0; i < full_blocks_count; i++) { + result += FULL_BLOCK; + } + + idx_t remaining = width_as_int % PARTIAL_BLOCKS_COUNT; + + if (remaining) { + result += PARTIAL_BLOCKS[remaining]; + } + + return string_t(result); +} + +static void BarFunction(DataChunk &args, ExpressionState &state, Vector &result) { + D_ASSERT(args.ColumnCount() == 3 || args.ColumnCount() == 4); + auto &x_arg = args.data[0]; + auto &min_arg = args.data[1]; + auto &max_arg = args.data[2]; + string buffer; + + if (args.ColumnCount() == 3) { + GenericExecutor::ExecuteTernary, PrimitiveType, PrimitiveType, + PrimitiveType>( + x_arg, min_arg, max_arg, result, args.size(), + [&](PrimitiveType x, PrimitiveType min, PrimitiveType max) { + return StringVector::AddString(result, BarScalarFunction(x.val, min.val, max.val, 80, buffer)); + }); + } else { + auto &width_arg = args.data[3]; + GenericExecutor::ExecuteQuaternary, PrimitiveType, PrimitiveType, + PrimitiveType, PrimitiveType>( + x_arg, min_arg, max_arg, width_arg, result, args.size(), + [&](PrimitiveType x, PrimitiveType min, PrimitiveType max, + PrimitiveType width) { + return StringVector::AddString(result, BarScalarFunction(x.val, min.val, max.val, width.val, buffer)); + }); + } +} + +void BarFun::RegisterFunction(BuiltinFunctions &set) { + ScalarFunctionSet bar("bar"); + bar.AddFunction(ScalarFunction({LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE}, + LogicalType::VARCHAR, BarFunction)); + bar.AddFunction(ScalarFunction({LogicalType::DOUBLE, LogicalType::DOUBLE, LogicalType::DOUBLE}, + LogicalType::VARCHAR, BarFunction)); + set.AddFunction(bar); +} + +} // namespace duckdb + + + + + + @@ -129404,6 +137381,7 @@ void JaroWinklerFun::RegisterFunction(BuiltinFunctions &set) { + #include #include @@ -129468,7 +137446,10 @@ static string_t RightScalarFunction(Vector &result, const string_t str, int64_t return OP::Substring(result, str, start, len); } - int64_t len = num_characters - MinValue(num_characters, -pos); + int64_t len = 0; + if (pos != std::numeric_limits::min()) { + len = num_characters - MinValue(num_characters, -pos); + } int64_t start = num_characters - len + 1; return OP::Substring(result, str, start, len); } @@ -129499,6 +137480,7 @@ void RightFun::RegisterFunction(BuiltinFunctions &set) { + namespace duckdb { // length returns the number of unicode codepoints @@ -129541,6 +137523,13 @@ struct StrLenOperator { } }; +struct OctetLenOperator { + template + static inline TR Operation(TA input) { + return Bit::OctetLength(input); + } +}; + // bitlen returns the size in bits struct BitLenOperator { template @@ -129549,6 +137538,14 @@ struct BitLenOperator { } }; +// bitstringlen returns the amount of bits in a bitstring +struct BitStringLenOperator { + template + static inline TR Operation(TA input) { + return Bit::BitLength(input); + } +}; + static unique_ptr LengthPropagateStats(ClientContext &context, FunctionStatisticsInput &input) { auto &child_stats = input.child_stats; auto &expr = input.expr; @@ -129581,6 +137578,8 @@ void LengthFun::RegisterFunction(BuiltinFunctions &set) { length.AddFunction(ScalarFunction({LogicalType::VARCHAR}, LogicalType::BIGINT, ScalarFunction::UnaryFunction, nullptr, nullptr, LengthPropagateStats)); + length.AddFunction(ScalarFunction({LogicalType::BIT}, LogicalType::BIGINT, + ScalarFunction::UnaryFunction)); length.AddFunction(array_length_unary); set.AddFunction(length); length.name = "len"; @@ -129601,11 +137600,19 @@ void LengthFun::RegisterFunction(BuiltinFunctions &set) { set.AddFunction(ScalarFunction("strlen", {LogicalType::VARCHAR}, LogicalType::BIGINT, ScalarFunction::UnaryFunction)); - set.AddFunction(ScalarFunction("bit_length", {LogicalType::VARCHAR}, LogicalType::BIGINT, - ScalarFunction::UnaryFunction)); + ScalarFunctionSet bit_length("bit_length"); + bit_length.AddFunction(ScalarFunction({LogicalType::VARCHAR}, LogicalType::BIGINT, + ScalarFunction::UnaryFunction)); + bit_length.AddFunction(ScalarFunction({LogicalType::BIT}, LogicalType::BIGINT, + ScalarFunction::UnaryFunction)); + set.AddFunction(bit_length); // length for BLOB type - set.AddFunction(ScalarFunction("octet_length", {LogicalType::BLOB}, LogicalType::BIGINT, - ScalarFunction::UnaryFunction)); + ScalarFunctionSet octet_length("octet_length"); + octet_length.AddFunction(ScalarFunction({LogicalType::BLOB}, LogicalType::BIGINT, + ScalarFunction::UnaryFunction)); + octet_length.AddFunction(ScalarFunction({LogicalType::BIT}, LogicalType::BIGINT, + ScalarFunction::UnaryFunction)); + set.AddFunction(octet_length); } struct UnicodeOperator { @@ -129788,7 +137795,7 @@ bool TemplatedLikeOperator(const char *sdata, idx_t slen, const char *pdata, idx } struct LikeSegment { - explicit LikeSegment(string pattern) : pattern(move(pattern)) { + explicit LikeSegment(string pattern) : pattern(std::move(pattern)) { } string pattern; @@ -129796,8 +137803,8 @@ struct LikeSegment { struct LikeMatcher : public FunctionData { LikeMatcher(string like_pattern_p, vector segments, bool has_start_percentage, bool has_end_percentage) - : like_pattern(move(like_pattern_p)), segments(move(segments)), has_start_percentage(has_start_percentage), - has_end_percentage(has_end_percentage) { + : like_pattern(std::move(like_pattern_p)), segments(std::move(segments)), + has_start_percentage(has_start_percentage), has_end_percentage(has_end_percentage) { } bool Match(string_t &str) { @@ -129893,7 +137900,8 @@ struct LikeMatcher : public FunctionData { if (segments.empty()) { return nullptr; } - return make_unique(move(like_pattern), move(segments), has_start_percentage, has_end_percentage); + return make_unique(std::move(like_pattern), std::move(segments), has_start_percentage, + has_end_percentage); } unique_ptr Copy() const override { @@ -130849,6 +138857,7 @@ void PrintfFun::RegisterFunction(BuiltinFunctions &set) { + namespace duckdb { struct RegexpBaseBindData : public FunctionData { @@ -130936,7 +138945,7 @@ RegexpBaseBindData::RegexpBaseBindData() : constant_pattern(false) { } RegexpBaseBindData::RegexpBaseBindData(duckdb_re2::RE2::Options options, string constant_string_p, bool constant_pattern) - : options(options), constant_string(move(constant_string_p)), constant_pattern(constant_pattern) { + : options(options), constant_string(std::move(constant_string_p)), constant_pattern(constant_pattern) { } RegexpBaseBindData::~RegexpBaseBindData() { @@ -131035,7 +139044,7 @@ static bool TryParseConstantPattern(ClientContext &context, Expression &expr, st //===--------------------------------------------------------------------===// RegexpMatchesBindData::RegexpMatchesBindData(duckdb_re2::RE2::Options options, string constant_string_p, bool constant_pattern) - : RegexpBaseBindData(options, move(constant_string_p), constant_pattern) { + : RegexpBaseBindData(options, std::move(constant_string_p), constant_pattern) { if (constant_pattern) { auto pattern = make_unique(constant_string, options); if (!pattern->ok()) { @@ -131051,8 +139060,8 @@ RegexpMatchesBindData::RegexpMatchesBindData(duckdb_re2::RE2::Options options, s RegexpMatchesBindData::RegexpMatchesBindData(duckdb_re2::RE2::Options options, string constant_string_p, bool constant_pattern, string range_min_p, string range_max_p, bool range_success) - : RegexpBaseBindData(options, move(constant_string_p), constant_pattern), range_min(move(range_min_p)), - range_max(move(range_max_p)), range_success(range_success) { + : RegexpBaseBindData(options, std::move(constant_string_p), constant_pattern), range_min(std::move(range_min_p)), + range_max(std::move(range_max_p)), range_success(range_success) { } unique_ptr RegexpMatchesBindData::Copy() const { @@ -131073,7 +139082,7 @@ unique_ptr RegexpMatchesBind(ClientContext &context, ScalarFunctio string constant_string; bool constant_pattern; constant_pattern = TryParseConstantPattern(context, *arguments[1], constant_string); - return make_unique(options, move(constant_string), constant_pattern); + return make_unique(options, std::move(constant_string), constant_pattern); } struct RegexPartialMatch { @@ -131121,12 +139130,12 @@ RegexpReplaceBindData::RegexpReplaceBindData() : global_replace(false) { RegexpReplaceBindData::RegexpReplaceBindData(duckdb_re2::RE2::Options options, string constant_string_p, bool constant_pattern, bool global_replace) - : RegexpBaseBindData(options, move(constant_string_p), constant_pattern), global_replace(global_replace) { + : RegexpBaseBindData(options, std::move(constant_string_p), constant_pattern), global_replace(global_replace) { } unique_ptr RegexpReplaceBindData::Copy() const { auto copy = make_unique(options, constant_string, constant_pattern, global_replace); - return move(copy); + return std::move(copy); } bool RegexpReplaceBindData::Equals(const FunctionData &other_p) const { @@ -131143,7 +139152,7 @@ static unique_ptr RegexReplaceBind(ClientContext &context, ScalarF ParseRegexOptions(context, *arguments[3], data->options, &data->global_replace); } data->options.set_log_errors(false); - return move(data); + return std::move(data); } static void RegexReplaceFunction(DataChunk &args, ExpressionState &state, Vector &result) { @@ -131189,8 +139198,8 @@ RegexpExtractBindData::RegexpExtractBindData() { RegexpExtractBindData::RegexpExtractBindData(duckdb_re2::RE2::Options options, string constant_string_p, bool constant_pattern, string group_string_p) - : RegexpBaseBindData(options, move(constant_string_p), constant_pattern), group_string(move(group_string_p)), - rewrite(group_string) { + : RegexpBaseBindData(options, std::move(constant_string_p), constant_pattern), + group_string(std::move(group_string_p)), rewrite(group_string) { } unique_ptr RegexpExtractBindData::Copy() const { @@ -131233,7 +139242,8 @@ static unique_ptr RegexExtractBind(ClientContext &context, ScalarF if (arguments.size() >= 4) { ParseRegexOptions(context, *arguments[3], options); } - return make_unique(options, move(constant_string), constant_pattern, move(group_string)); + return make_unique(options, std::move(constant_string), constant_pattern, + std::move(group_string)); } inline static string_t Extract(const string_t &input, Vector &result, const RE2 &re, @@ -131505,6 +139515,53 @@ void ReverseFun::RegisterFunction(BuiltinFunctions &set) { +namespace duckdb { + +static bool StartsWith(const unsigned char *haystack, idx_t haystack_size, const unsigned char *needle, + idx_t needle_size) { + D_ASSERT(needle_size > 0); + if (needle_size > haystack_size) { + // needle is bigger than haystack: haystack cannot start with needle + return false; + } + return memcmp(haystack, needle, needle_size) == 0; +} + +static bool StartsWith(const string_t &haystack_s, const string_t &needle_s) { + auto haystack = (const unsigned char *)haystack_s.GetDataUnsafe(); + auto haystack_size = haystack_s.GetSize(); + auto needle = (const unsigned char *)needle_s.GetDataUnsafe(); + auto needle_size = needle_s.GetSize(); + if (needle_size == 0) { + // empty needle: always true + return true; + } + return StartsWith(haystack, haystack_size, needle, needle_size); +} + +struct StartsWithOperator { + template + static inline TR Operation(TA left, TB right) { + return StartsWith(left, right); + } +}; + +void StartsWithFun::RegisterFunction(BuiltinFunctions &set) { + ScalarFunction starts_with = + ScalarFunction("starts_with", {LogicalType::VARCHAR, LogicalType::VARCHAR}, LogicalType::BOOLEAN, + ScalarFunction::BinaryFunction); + set.AddFunction(starts_with); + starts_with.name = "^@"; + set.AddFunction(starts_with); +} + +} // namespace duckdb + + + + + + namespace duckdb { @@ -131575,7 +139632,7 @@ struct StringSplitter { auto delim_size = delim.GetSize(); idx_t list_idx = 0; while (input_size > 0) { - idx_t match_size; + idx_t match_size = 0; auto pos = OP::Find(input_data, input_size, delim_data, delim_size, match_size, data); if (pos > input_size) { break; @@ -131752,6 +139809,7 @@ void StripAccentsFun::RegisterFunction(BuiltinFunctions &set) { + namespace duckdb { static const int64_t SUPPORTED_UPPER_BOUND = NumericLimits::Maximum(); @@ -131882,6 +139940,13 @@ string_t SubstringFun::SubstringUnicode(Vector &result, string_t input, int64_t } } } + while (!LengthFun::IsCharacter(input_data[start_pos])) { + start_pos++; + } + while (end_pos < input_size && !LengthFun::IsCharacter(input_data[end_pos])) { + end_pos++; + } + if (end_pos == DConstants::INVALID_INDEX) { return SubstringEmptyString(result); } @@ -132131,6 +140196,105 @@ void SuffixFun::RegisterFunction(BuiltinFunctions &set) { + +#include +#include +#include +#include + +namespace duckdb { + +static string_t TranslateScalarFunction(const string_t &haystack, const string_t &needle, const string_t &thread, + vector &result) { + // Get information about the haystack, the needle and the "thread" + auto input_haystack = haystack.GetDataUnsafe(); + auto size_haystack = haystack.GetSize(); + + auto input_needle = needle.GetDataUnsafe(); + auto size_needle = needle.GetSize(); + + auto input_thread = thread.GetDataUnsafe(); + auto size_thread = thread.GetSize(); + + // Reuse the buffer + result.clear(); + result.reserve(size_haystack); + + idx_t i = 0, j = 0; + int sz = 0, c_sz = 0; + + // Character to be replaced + unordered_map to_replace; + while (i < size_needle && j < size_thread) { + auto codepoint_needle = Utf8Proc::UTF8ToCodepoint(input_needle, sz); + input_needle += sz; + i += sz; + auto codepoint_thread = Utf8Proc::UTF8ToCodepoint(input_thread, sz); + input_thread += sz; + j += sz; + // Ignore unicode character that is existed in to_replace + if (to_replace.count(codepoint_needle) == 0) { + to_replace[codepoint_needle] = codepoint_thread; + } + } + + // Character to be deleted + unordered_set to_delete; + while (i < size_needle) { + auto codepoint_needle = Utf8Proc::UTF8ToCodepoint(input_needle, sz); + input_needle += sz; + i += sz; + // Add unicode character that will be deleted + if (to_replace.count(codepoint_needle) == 0) { + to_delete.insert(codepoint_needle); + } + } + + char c[5] = {'\0', '\0', '\0', '\0', '\0'}; + for (i = 0; i < size_haystack; i += sz) { + auto codepoint_haystack = Utf8Proc::UTF8ToCodepoint(input_haystack, sz); + if (to_replace.count(codepoint_haystack) != 0) { + Utf8Proc::CodepointToUtf8(to_replace[codepoint_haystack], c_sz, c); + result.insert(result.end(), c, c + c_sz); + } else if (to_delete.count(codepoint_haystack) == 0) { + result.insert(result.end(), input_haystack, input_haystack + sz); + } + input_haystack += sz; + } + + return string_t(result.data(), result.size()); +} + +static void TranslateFunction(DataChunk &args, ExpressionState &state, Vector &result) { + auto &haystack_vector = args.data[0]; + auto &needle_vector = args.data[1]; + auto &thread_vector = args.data[2]; + + vector buffer; + TernaryExecutor::Execute( + haystack_vector, needle_vector, thread_vector, result, args.size(), + [&](string_t input_string, string_t needle_string, string_t thread_string) { + return StringVector::AddString(result, + TranslateScalarFunction(input_string, needle_string, thread_string, buffer)); + }); +} + +void TranslateFun::RegisterFunction(BuiltinFunctions &set) { + set.AddFunction(ScalarFunction("translate", // name of the function + {LogicalType::VARCHAR, // argument list + LogicalType::VARCHAR, LogicalType::VARCHAR}, + LogicalType::VARCHAR, // return type + TranslateFunction)); // pointer to function implementation +} + +} // namespace duckdb + + + + + + + #include namespace duckdb { @@ -132277,6 +140441,7 @@ void TrimFun::RegisterFunction(BuiltinFunctions &set) { + namespace duckdb { void BuiltinFunctions::RegisterStringFunctions() { @@ -132285,6 +140450,7 @@ void BuiltinFunctions::RegisterStringFunctions() { Register(); Register(); Register(); + Register(); Register(); Register(); Register(); @@ -132301,11 +140467,13 @@ void BuiltinFunctions::RegisterStringFunctions() { Register(); Register(); Register(); + Register(); Register(); Register(); Register(); Register(); Register(); + Register(); Register(); Register(); Register(); @@ -132317,6 +140485,11 @@ void BuiltinFunctions::RegisterStringFunctions() { Register(); Register(); + // bit functions + Register(); + Register(); + Register(); + // uuid functions Register(); } @@ -132368,7 +140541,8 @@ class StructStatistics : public BaseStatistics { namespace duckdb { struct StructExtractBindData : public FunctionData { - StructExtractBindData(string key, idx_t index, LogicalType type) : key(move(key)), index(index), type(move(type)) { + StructExtractBindData(string key, idx_t index, LogicalType type) + : key(std::move(key)), index(index), type(std::move(type)) { } string key; @@ -132560,7 +140734,7 @@ static unique_ptr StructInsertBind(ClientContext &context, ScalarF } // this is more for completeness reasons - bound_function.return_type = LogicalType::STRUCT(move(new_struct_children)); + bound_function.return_type = LogicalType::STRUCT(std::move(new_struct_children)); return make_unique(bound_function.return_type); } @@ -132582,7 +140756,7 @@ unique_ptr StructInsertStats(ClientContext &context, FunctionSta for (idx_t i = 1; i < child_stats.size(); i++) { new_struct_stats->child_stats[offset + i] = child_stats[i] ? child_stats[i]->Copy() : nullptr; } - return move(new_struct_stats); + return std::move(new_struct_stats); } void StructInsertFun::RegisterFunction(BuiltinFunctions &set) { @@ -132652,7 +140826,7 @@ static unique_ptr StructPackBind(ClientContext &context, ScalarFun } // this is more for completeness reasons - bound_function.return_type = LogicalType::STRUCT(move(struct_children)); + bound_function.return_type = LogicalType::STRUCT(std::move(struct_children)); return make_unique(bound_function.return_type); } @@ -132664,7 +140838,7 @@ unique_ptr StructPackStats(ClientContext &context, FunctionStati for (idx_t i = 0; i < struct_stats->child_stats.size(); i++) { struct_stats->child_stats[i] = child_stats[i] ? child_stats[i]->Copy() : nullptr; } - return move(struct_stats); + return std::move(struct_stats); } void StructPackFun::RegisterFunction(BuiltinFunctions &set) { @@ -132698,7 +140872,7 @@ struct ExportAggregateBindData : public FunctionData { idx_t state_size; explicit ExportAggregateBindData(AggregateFunction aggr_p, idx_t state_size_p) - : aggr(move(aggr_p)), state_size(state_size_p) { + : aggr(std::move(aggr_p)), state_size(state_size_p) { } unique_ptr Copy() const override { @@ -132882,8 +141056,8 @@ static unique_ptr BindAggregateState(ClientContext &context, Scala auto state_type = AggregateStateType::GetStateType(arg_return_type); // now we can look up the function in the catalog again and bind it - auto func = Catalog::GetCatalog(context).GetEntry(context, CatalogType::SCALAR_FUNCTION_ENTRY, DEFAULT_SCHEMA, - state_type.function_name); + auto func = Catalog::GetSystemCatalog(context).GetEntry(context, CatalogType::SCALAR_FUNCTION_ENTRY, DEFAULT_SCHEMA, + state_type.function_name); if (func->type != CatalogType::AGGREGATE_FUNCTION_ENTRY) { throw InternalException("Could not find aggregate %s", state_type.function_name); } @@ -132902,6 +141076,7 @@ static unique_ptr BindAggregateState(ClientContext &context, Scala // FIXME: this is really hacky // but the aggregate state export needs a rework around how it handles more complex aggregates anyway vector> args; + args.reserve(state_type.bound_argument_types.size()); for (auto &arg_type : state_type.bound_argument_types) { args.push_back(make_unique(Value(arg_type))); } @@ -132985,7 +141160,6 @@ ExportAggregateFunction::Bind(unique_ptr child_aggrega // this should be required D_ASSERT(bound_function.state_size); D_ASSERT(bound_function.finalize); - D_ASSERT(!bound_function.window); D_ASSERT(child_aggregate->function.return_type.id() != LogicalTypeId::INVALID); #ifdef DEBUG @@ -132996,7 +141170,7 @@ ExportAggregateFunction::Bind(unique_ptr child_aggrega auto export_bind_data = make_unique(child_aggregate->Copy()); aggregate_state_t state_type(child_aggregate->function.name, child_aggregate->function.return_type, child_aggregate->function.arguments); - auto return_type = LogicalType::AGGREGATE_STATE(move(state_type)); + auto return_type = LogicalType::AGGREGATE_STATE(std::move(state_type)); auto export_function = AggregateFunction("aggregate_state_export_" + bound_function.name, bound_function.arguments, return_type, @@ -133008,8 +141182,8 @@ ExportAggregateFunction::Bind(unique_ptr child_aggrega export_function.serialize = ExportStateAggregateSerialize; export_function.deserialize = ExportStateAggregateDeserialize; - return make_unique(export_function, move(child_aggregate->children), - move(child_aggregate->filter), move(export_bind_data), + return make_unique(export_function, std::move(child_aggregate->children), + std::move(child_aggregate->filter), std::move(export_bind_data), child_aggregate->aggr_type); } @@ -133042,6 +141216,7 @@ ScalarFunction ExportAggregateFunction::GetCombine() { + namespace duckdb { // current_query @@ -133052,7 +141227,13 @@ static void CurrentQueryFunction(DataChunk &input, ExpressionState &state, Vecto // current_schema static void CurrentSchemaFunction(DataChunk &input, ExpressionState &state, Vector &result) { - Value val(ClientData::Get(state.GetContext()).catalog_search_path->GetDefault()); + Value val(ClientData::Get(state.GetContext()).catalog_search_path->GetDefault().schema); + result.Reference(val); +} + +// current_database +static void CurrentDatabaseFunction(DataChunk &input, ExpressionState &state, Vector &result) { + Value val(DatabaseManager::GetDefaultDatabase(state.GetContext())); result.Reference(val); } @@ -133069,9 +141250,9 @@ static void CurrentSchemasFunction(DataChunk &input, ExpressionState &state, Vec auto implicit_schemas = *ConstantVector::GetData(input.data[0]); vector schema_list; auto &catalog_search_path = ClientData::Get(state.GetContext()).catalog_search_path; - vector search_path = implicit_schemas ? catalog_search_path->Get() : catalog_search_path->GetSetPaths(); + auto &search_path = implicit_schemas ? catalog_search_path->Get() : catalog_search_path->GetSetPaths(); std::transform(search_path.begin(), search_path.end(), std::back_inserter(schema_list), - [](const string &s) -> Value { return Value(s); }); + [](const CatalogSearchEntry &s) -> Value { return Value(s.schema); }); auto val = Value::LIST(LogicalType::VARCHAR, schema_list); result.Reference(val); @@ -133079,7 +141260,9 @@ static void CurrentSchemasFunction(DataChunk &input, ExpressionState &state, Vec // txid_current static void TransactionIdCurrent(DataChunk &input, ExpressionState &state, Vector &result) { - auto &transaction = Transaction::GetTransaction(state.GetContext()); + auto &context = state.GetContext(); + auto &catalog = Catalog::GetCatalog(context, DatabaseManager::GetDefaultDatabase(context)); + auto &transaction = DuckTransaction::Get(context, catalog); auto val = Value::BIGINT(transaction.start_time); result.Reference(val); } @@ -133097,6 +141280,7 @@ void SystemFun::RegisterFunction(BuiltinFunctions &set) { current_query.side_effects = FunctionSideEffects::HAS_SIDE_EFFECTS; set.AddFunction(current_query); set.AddFunction(ScalarFunction("current_schema", {}, LogicalType::VARCHAR, CurrentSchemaFunction)); + set.AddFunction(ScalarFunction("current_database", {}, LogicalType::VARCHAR, CurrentDatabaseFunction)); set.AddFunction( ScalarFunction("current_schemas", {LogicalType::BOOLEAN}, varchar_list_type, CurrentSchemasFunction)); set.AddFunction(ScalarFunction("txid_current", {}, LogicalType::BIGINT, TransactionIdCurrent)); @@ -133133,7 +141317,8 @@ void BuiltinFunctions::RegisterTrigonometricsFunctions() { namespace duckdb { struct UnionExtractBindData : public FunctionData { - UnionExtractBindData(string key, idx_t index, LogicalType type) : key(move(key)), index(index), type(move(type)) { + UnionExtractBindData(string key, idx_t index, LogicalType type) + : key(std::move(key)), index(index), type(std::move(type)) { } string key; @@ -133399,7 +141584,7 @@ static unique_ptr UnionValueBind(ClientContext &context, ScalarFun union_members.push_back(make_pair(child->alias, child->return_type)); - bound_function.return_type = LogicalType::UNION(move(union_members)); + bound_function.return_type = LogicalType::UNION(std::move(union_members)); return make_unique(bound_function.return_type); } @@ -133430,8 +141615,9 @@ ScalarFunction::ScalarFunction(string name, vector arguments, Logic dependency_function_t dependency, function_statistics_t statistics, init_local_state_t init_local_state, LogicalType varargs, FunctionSideEffects side_effects, FunctionNullHandling null_handling) - : BaseScalarFunction(move(name), move(arguments), move(return_type), side_effects, move(varargs), null_handling), - function(move(function)), bind(bind), init_local_state(init_local_state), dependency(dependency), + : BaseScalarFunction(std::move(name), std::move(arguments), std::move(return_type), side_effects, + std::move(varargs), null_handling), + function(std::move(function)), bind(bind), init_local_state(init_local_state), dependency(dependency), statistics(statistics), serialize(nullptr), deserialize(nullptr) { } @@ -133440,8 +141626,8 @@ ScalarFunction::ScalarFunction(vector arguments, LogicalType return function_statistics_t statistics, init_local_state_t init_local_state, LogicalType varargs, FunctionSideEffects side_effects, FunctionNullHandling null_handling) - : ScalarFunction(string(), move(arguments), move(return_type), move(function), bind, dependency, statistics, - init_local_state, move(varargs), side_effects, null_handling) { + : ScalarFunction(string(), std::move(arguments), std::move(return_type), std::move(function), bind, dependency, + statistics, init_local_state, std::move(varargs), side_effects, null_handling) { } bool ScalarFunction::operator==(const ScalarFunction &rhs) const { @@ -133515,7 +141701,7 @@ void ScalarFunction::NopFunction(DataChunk &input, ExpressionState &state, Vecto namespace duckdb { ScalarMacroFunction::ScalarMacroFunction(unique_ptr expression) - : MacroFunction(MacroType::SCALAR_MACRO), expression(move(expression)) { + : MacroFunction(MacroType::SCALAR_MACRO), expression(std::move(expression)) { } ScalarMacroFunction::ScalarMacroFunction(void) : MacroFunction(MacroType::SCALAR_MACRO) { @@ -133526,7 +141712,7 @@ unique_ptr ScalarMacroFunction::Copy() { result->expression = expression->Copy(); CopyProperties(*result); - return move(result); + return std::move(result); } void RemoveQualificationRecursive(unique_ptr &expr) { @@ -133591,6 +141777,7 @@ using std::thread; + namespace duckdb { //===--------------------------------------------------------------------===// // Arrow Variable Size Types @@ -133652,7 +141839,7 @@ struct ArrowScanFunctionData : public PyTableFunctionData { }; struct ArrowScanLocalState : public LocalTableFunctionState { - explicit ArrowScanLocalState(unique_ptr current_chunk) : chunk(move(current_chunk)) { + explicit ArrowScanLocalState(unique_ptr current_chunk) : chunk(std::move(current_chunk)) { } unique_ptr stream; @@ -133845,27 +142032,23 @@ LogicalType ArrowTableFunction::GetArrowLogicalType( idx_t fixed_size = std::stoi(parameters); arrow_convert_data[col_idx]->variable_sz_type.emplace_back(ArrowVariableSizeType::FIXED_SIZE, fixed_size); auto child_type = GetArrowLogicalType(*schema.children[0], arrow_convert_data, col_idx); - return LogicalType::LIST(move(child_type)); + return LogicalType::LIST(std::move(child_type)); } else if (format == "+s") { child_list_t child_types; for (idx_t type_idx = 0; type_idx < (idx_t)schema.n_children; type_idx++) { auto child_type = GetArrowLogicalType(*schema.children[type_idx], arrow_convert_data, col_idx); child_types.push_back({schema.children[type_idx]->name, child_type}); } - return LogicalType::STRUCT(move(child_types)); + return LogicalType::STRUCT(std::move(child_types)); } else if (format == "+m") { - child_list_t child_types; - //! First type will be struct, so we skip it - auto &struct_schema = *schema.children[0]; - for (idx_t type_idx = 0; type_idx < (idx_t)struct_schema.n_children; type_idx++) { - //! The other types must be added on lists - auto child_type = GetArrowLogicalType(*struct_schema.children[type_idx], arrow_convert_data, col_idx); + arrow_convert_data[col_idx]->variable_sz_type.emplace_back(ArrowVariableSizeType::NORMAL, 0); - auto list_type = LogicalType::LIST(child_type); - child_types.push_back({struct_schema.children[type_idx]->name, list_type}); - } - return LogicalType::MAP(move(child_types)); + auto &arrow_struct_type = *schema.children[0]; + D_ASSERT(arrow_struct_type.n_children == 2); + auto key_type = GetArrowLogicalType(*arrow_struct_type.children[0], arrow_convert_data, col_idx); + auto value_type = GetArrowLogicalType(*arrow_struct_type.children[1], arrow_convert_data, col_idx); + return LogicalType::MAP(key_type, value_type); } else if (format == "z") { arrow_convert_data[col_idx]->variable_sz_type.emplace_back(ArrowVariableSizeType::NORMAL, 0); return LogicalType::BLOB; @@ -133952,7 +142135,7 @@ unique_ptr ArrowTableFunction::ArrowScanBind(ClientContext &contex } RenameArrowColumns(names); res->all_types = return_types; - return move(res); + return std::move(res); } unique_ptr ProduceArrowScan(const ArrowScanFunctionData &function, @@ -133989,7 +142172,7 @@ bool ArrowTableFunction::ArrowScanParallelStateNext(ClientContext &context, cons while (current_chunk->arrow_array.length == 0 && current_chunk->arrow_array.release) { current_chunk = parallel_state.stream->GetNextChunk(); } - state.chunk = move(current_chunk); + state.chunk = std::move(current_chunk); //! have we run out of chunks? we are done if (!state.chunk->arrow_array.release) { parallel_state.done = true; @@ -134014,7 +142197,7 @@ unique_ptr ArrowTableFunction::ArrowScanInitGlobal(Cli } } } - return move(result); + return std::move(result); } unique_ptr ArrowTableFunction::ArrowScanInitLocal(ExecutionContext &context, @@ -134022,7 +142205,7 @@ unique_ptr ArrowTableFunction::ArrowScanInitLocal(Execu GlobalTableFunctionState *global_state_p) { auto &global_state = (ArrowScanGlobalState &)*global_state_p; auto current_chunk = make_unique(); - auto result = make_unique(move(current_chunk)); + auto result = make_unique(std::move(current_chunk)); result->column_ids = input.column_ids; result->filters = input.filters; if (input.CanRemoveFilterColumns()) { @@ -134032,7 +142215,7 @@ unique_ptr ArrowTableFunction::ArrowScanInitLocal(Execu if (!ArrowScanParallelStateNext(context.client, input.bind_data, *result, global_state)) { return nullptr; } - return move(result); + return std::move(result); } void ArrowTableFunction::ArrowScanFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { @@ -134085,6 +142268,15 @@ void ArrowTableFunction::RegisterFunction(BuiltinFunctions &set) { arrow.filter_pushdown = true; arrow.filter_prune = true; set.AddFunction(arrow); + + TableFunction arrow_dumb("arrow_scan_dumb", {LogicalType::POINTER, LogicalType::POINTER, LogicalType::POINTER}, + ArrowScanFunction, ArrowScanBind, ArrowScanInitGlobal, ArrowScanInitLocal); + arrow_dumb.cardinality = ArrowScanCardinality; + arrow_dumb.get_batch_index = ArrowGetBatchIndex; + arrow_dumb.projection_pushdown = false; + arrow_dumb.filter_pushdown = false; + arrow_dumb.filter_prune = false; + set.AddFunction(arrow_dumb); } void BuiltinFunctions::RegisterArrowFunctions() { @@ -134320,47 +142512,6 @@ void ArrowToDuckDBMapVerify(Vector &vector, idx_t count) { } } -void ArrowToDuckDBMapList(Vector &vector, ArrowArray &array, ArrowScanLocalState &scan_state, idx_t size, - unordered_map> &arrow_convert_data, idx_t col_idx, - pair &arrow_convert_idx, uint32_t *offsets, ValidityMask *parent_mask) { - idx_t list_size = offsets[size] - offsets[0]; - ListVector::Reserve(vector, list_size); - - auto &child_vector = ListVector::GetEntry(vector); - auto list_data = FlatVector::GetData(vector); - auto cur_offset = 0; - for (idx_t i = 0; i < size; i++) { - auto &le = list_data[i]; - le.offset = cur_offset; - le.length = offsets[i + 1] - offsets[i]; - cur_offset += le.length; - } - ListVector::SetListSize(vector, list_size); - if (list_size == 0 && offsets[0] == 0) { - SetValidityMask(child_vector, array, scan_state, list_size, -1); - } else { - SetValidityMask(child_vector, array, scan_state, list_size, offsets[0]); - } - - auto &list_mask = FlatVector::Validity(vector); - if (parent_mask) { - //! Since this List is owned by a struct we must guarantee their validity map matches on Null - if (!parent_mask->AllValid()) { - for (idx_t i = 0; i < size; i++) { - if (!parent_mask->RowIsValid(i)) { - list_mask.SetInvalid(i); - } - } - } - } - if (list_size == 0 && offsets[0] == 0) { - ColumnArrowToDuckDB(child_vector, array, scan_state, list_size, arrow_convert_data, col_idx, arrow_convert_idx, - -1); - } else { - ColumnArrowToDuckDB(child_vector, array, scan_state, list_size, arrow_convert_data, col_idx, arrow_convert_idx, - offsets[0]); - } -} template static void SetVectorString(Vector &vector, idx_t size, char *cdata, T *offsets) { auto strings = FlatVector::GetData(vector); @@ -134503,7 +142654,6 @@ void ColumnArrowToDuckDB(Vector &vector, ArrowArray &array, ArrowScanLocalState DirectConversion(vector, array, scan_state, nested_offset); break; } - case LogicalTypeId::JSON: case LogicalTypeId::VARCHAR: { auto original_type = arrow_convert_data[col_idx]->variable_sz_type[arrow_convert_idx.first++]; auto cdata = (char *)array.buffers[2]; @@ -134712,20 +142862,8 @@ void ColumnArrowToDuckDB(Vector &vector, ArrowArray &array, ArrowScanLocalState break; } case LogicalTypeId::MAP: { - //! Since this is a map we skip first child, because its a struct - auto &struct_arrow = *array.children[0]; - auto &child_entries = StructVector::GetEntries(vector); - D_ASSERT(child_entries.size() == 2); - auto offsets = (uint32_t *)array.buffers[1] + array.offset + scan_state.chunk_offset; - if (nested_offset != -1) { - offsets = (uint32_t *)array.buffers[1] + nested_offset; - } - auto &struct_validity_mask = FlatVector::Validity(vector); - //! Fill the children - for (idx_t type_idx = 0; type_idx < (idx_t)struct_arrow.n_children; type_idx++) { - ArrowToDuckDBMapList(*child_entries[type_idx], *struct_arrow.children[type_idx], scan_state, size, - arrow_convert_data, col_idx, arrow_convert_idx, offsets, &struct_validity_mask); - } + ArrowToDuckDBList(vector, array, scan_state, size, arrow_convert_data, col_idx, arrow_convert_idx, + nested_offset, parent_mask); ArrowToDuckDBMapVerify(vector, size); break; } @@ -134887,7 +143025,7 @@ void ColumnArrowToDuckDBDictionary(Vector &vector, ArrowArray &array, ArrowScanL SetValidityMask(*base_vector, *array.dictionary, scan_state, array.dictionary->length, 0, array.null_count > 0); ColumnArrowToDuckDB(*base_vector, *array.dictionary, scan_state, array.dictionary->length, arrow_convert_data, col_idx, arrow_convert_idx); - dict_vectors[col_idx] = move(base_vector); + dict_vectors[col_idx] = std::move(base_vector); } auto dictionary_type = arrow_convert_data[col_idx]->dictionary_type; //! Get Pointer to Indices of Dictionary @@ -134950,6 +143088,7 @@ void ArrowTableFunction::ArrowToDuckDB(ArrowScanLocalState &scan_state, + namespace duckdb { struct CheckpointFunction { @@ -134978,25 +143117,59 @@ struct UnnestTableFunction { + + namespace duckdb { +struct CheckpointBindData : public FunctionData { + explicit CheckpointBindData(AttachedDatabase *db) : db(db) { + } + + AttachedDatabase *db; + +public: + unique_ptr Copy() const override { + return make_unique(db); + } + + bool Equals(const FunctionData &other_p) const override { + auto &other = (const CheckpointBindData &)other_p; + return db == other.db; + } +}; + static unique_ptr CheckpointBind(ClientContext &context, TableFunctionBindInput &input, vector &return_types, vector &names) { return_types.emplace_back(LogicalType::BOOLEAN); names.emplace_back("Success"); - return nullptr; + + AttachedDatabase *db; + auto &db_manager = DatabaseManager::Get(context); + if (!input.inputs.empty()) { + db = db_manager.GetDatabase(context, StringValue::Get(input.inputs[0])); + } else { + db = db_manager.GetDatabase(context, DatabaseManager::GetDefaultDatabase(context)); + } + return make_unique(db); } template static void TemplatedCheckpointFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { - auto &transaction_manager = TransactionManager::Get(context); + auto &bind_data = (CheckpointBindData &)*data_p.bind_data; + auto &transaction_manager = TransactionManager::Get(*bind_data.db); transaction_manager.Checkpoint(context, FORCE); } void CheckpointFunction::RegisterFunction(BuiltinFunctions &set) { - TableFunction checkpoint("checkpoint", {}, TemplatedCheckpointFunction, CheckpointBind); + TableFunctionSet checkpoint("checkpoint"); + checkpoint.AddFunction(TableFunction({}, TemplatedCheckpointFunction, CheckpointBind)); + checkpoint.AddFunction(TableFunction({LogicalType::VARCHAR}, TemplatedCheckpointFunction, CheckpointBind)); set.AddFunction(checkpoint); - TableFunction force_checkpoint("force_checkpoint", {}, TemplatedCheckpointFunction, CheckpointBind); + + TableFunctionSet force_checkpoint("force_checkpoint"); + force_checkpoint.AddFunction(TableFunction({}, TemplatedCheckpointFunction, CheckpointBind)); + force_checkpoint.AddFunction( + TableFunction({LogicalType::VARCHAR}, TemplatedCheckpointFunction, CheckpointBind)); set.AddFunction(force_checkpoint); } @@ -135011,6 +143184,9 @@ void CheckpointFunction::RegisterFunction(BuiltinFunctions &set) { + + + #include namespace duckdb { @@ -135060,13 +143236,6 @@ void BaseCSVData::Finalize() { } } -static Value ConvertVectorToValue(vector set) { - if (set.empty()) { - return Value::EMPTYLIST(LogicalType::BOOLEAN); - } - return Value::LIST(move(set)); -} - static unique_ptr WriteCSVBind(ClientContext &context, CopyInfo &info, vector &names, vector &sql_types) { auto bind_data = make_unique(info.file_path, sql_types, names); @@ -135075,7 +143244,7 @@ static unique_ptr WriteCSVBind(ClientContext &context, CopyInfo &i for (auto &option : info.options) { auto loption = StringUtil::Lower(option.first); auto &set = option.second; - bind_data->options.SetWriteOption(loption, ConvertVectorToValue(move(set))); + bind_data->options.SetWriteOption(loption, ConvertVectorToValue(std::move(set))); } // verify the parsed options if (bind_data->options.force_quote.empty()) { @@ -135085,7 +143254,7 @@ static unique_ptr WriteCSVBind(ClientContext &context, CopyInfo &i bind_data->Finalize(); bind_data->is_simple = bind_data->options.delimiter.size() == 1 && bind_data->options.escape.size() == 1 && bind_data->options.quote.size() == 1; - return move(bind_data); + return std::move(bind_data); } static unique_ptr ReadCSVBind(ClientContext &context, CopyInfo &info, vector &expected_names, @@ -135104,7 +143273,7 @@ static unique_ptr ReadCSVBind(ClientContext &context, CopyInfo &in for (auto &option : info.options) { auto loption = StringUtil::Lower(option.first); auto &set = option.second; - options.SetReadOption(loption, ConvertVectorToValue(move(set)), expected_names); + options.SetReadOption(loption, ConvertVectorToValue(std::move(set)), expected_names); } // verify the parsed options if (options.force_not_null.empty()) { @@ -135117,7 +143286,7 @@ static unique_ptr ReadCSVBind(ClientContext &context, CopyInfo &in auto initial_reader = make_unique(context, options); options = initial_reader->options; } - return move(bind_data); + return std::move(bind_data); } //===--------------------------------------------------------------------===// @@ -135172,12 +143341,14 @@ static bool RequiresQuotes(WriteCSVData &csv_data, const char *str, idx_t len) { } // check for delimiter - if (ContainsFun::Find((const unsigned char *)str, len, (const unsigned char *)options.delimiter.c_str(), + if (options.delimiter.length() != 0 && + ContainsFun::Find((const unsigned char *)str, len, (const unsigned char *)options.delimiter.c_str(), options.delimiter.size()) != DConstants::INVALID_INDEX) { return true; } // check for quote - if (ContainsFun::Find((const unsigned char *)str, len, (const unsigned char *)options.quote.c_str(), + if (options.quote.length() != 0 && + ContainsFun::Find((const unsigned char *)str, len, (const unsigned char *)options.quote.c_str(), options.quote.size()) != DConstants::INVALID_INDEX) { return true; } @@ -135207,10 +143378,12 @@ static void WriteQuotedString(Serializer &serializer, WriteCSVData &csv_data, co } else { // complex CSV // check for quote or escape separately - if (ContainsFun::Find((const unsigned char *)str, len, (const unsigned char *)options.quote.c_str(), + if (options.quote.length() != 0 && + ContainsFun::Find((const unsigned char *)str, len, (const unsigned char *)options.quote.c_str(), options.quote.size()) != DConstants::INVALID_INDEX) { requires_escape = true; - } else if (ContainsFun::Find((const unsigned char *)str, len, (const unsigned char *)options.escape.c_str(), + } else if (options.escape.length() != 0 && + ContainsFun::Find((const unsigned char *)str, len, (const unsigned char *)options.escape.c_str(), options.escape.size()) != DConstants::INVALID_INDEX) { requires_escape = true; } @@ -135276,7 +143449,7 @@ static unique_ptr WriteCSVInitializeLocal(ExecutionContext &c types.resize(csv_data.options.names.size(), LogicalType::VARCHAR); local_data->cast_chunk.Initialize(Allocator::Get(context.client), types); - return move(local_data); + return std::move(local_data); } static unique_ptr WriteCSVInitializeGlobal(ClientContext &context, FunctionData &bind_data, @@ -135300,7 +143473,7 @@ static unique_ptr WriteCSVInitializeGlobal(ClientContext &co global_data->WriteData(serializer.blob.data.get(), serializer.blob.size); } - return move(global_data); + return std::move(global_data); } static void WriteCSVSink(ExecutionContext &context, FunctionData &bind_data, GlobalFunctionData &gstate, @@ -135318,8 +143491,8 @@ static void WriteCSVSink(ExecutionContext &context, FunctionData &bind_data, Glo cast_chunk.SetCardinality(input); for (idx_t col_idx = 0; col_idx < input.ColumnCount(); col_idx++) { if (csv_data.sql_types[col_idx].id() == LogicalTypeId::VARCHAR) { - // VARCHAR, just create a reference - cast_chunk.data[col_idx].Reference(input.data[col_idx]); + // VARCHAR, just reinterpret (cannot reference, because LogicalTypeId::VARCHAR is used by the JSON type too) + cast_chunk.data[col_idx].Reinterpret(input.data[col_idx]); } else if (options.has_format[LogicalTypeId::DATE] && csv_data.sql_types[col_idx].id() == LogicalTypeId::DATE) { // use the date format to cast the chunk csv_data.options.write_date_format[LogicalTypeId::DATE].ConvertDateVector( @@ -135393,6 +143566,17 @@ void WriteCSVFinalize(ClientContext &context, FunctionData &bind_data, GlobalFun global_state.handle.reset(); } +//===--------------------------------------------------------------------===// +// Parallel +//===--------------------------------------------------------------------===// +bool WriteCSVIsParallel(ClientContext &context, FunctionData &bind_data) { + auto &config = DBConfig::GetConfig(context); + if (config.options.preserve_insertion_order) { + return false; + } + return true; +} + void CSVCopyFunction::RegisterFunction(BuiltinFunctions &set) { CopyFunction info("csv"); info.copy_to_bind = WriteCSVBind; @@ -135401,6 +143585,7 @@ void CSVCopyFunction::RegisterFunction(BuiltinFunctions &set) { info.copy_to_sink = WriteCSVSink; info.copy_to_combine = WriteCSVCombine; info.copy_to_finalize = WriteCSVFinalize; + info.parallel = WriteCSVIsParallel; info.copy_from_bind = ReadCSVBind; info.copy_from_function = ReadCSVTableFunction::GetFunction(); @@ -135434,7 +143619,7 @@ static unique_ptr GlobFunctionBind(ClientContext &context, TableFu result->files = fs.Glob(StringValue::Get(input.inputs[0]), context); return_types.emplace_back(LogicalType::VARCHAR); names.emplace_back("file"); - return move(result); + return std::move(result); } struct GlobFunctionState : public GlobalTableFunctionState { @@ -135480,16 +143665,13 @@ void GlobTableFunction::RegisterFunction(BuiltinFunctions &set) { + namespace duckdb { struct PragmaCollations { static void RegisterFunction(BuiltinFunctions &set); }; -struct PragmaFunctionPragma { - static void RegisterFunction(BuiltinFunctions &set); -}; - struct PragmaTableInfo { static void RegisterFunction(BuiltinFunctions &set); }; @@ -135510,10 +143692,6 @@ struct PragmaVersion { static void RegisterFunction(BuiltinFunctions &set); }; -struct PragmaDatabaseList { - static void RegisterFunction(BuiltinFunctions &set); -}; - struct PragmaDatabaseSize { static void RegisterFunction(BuiltinFunctions &set); }; @@ -135530,6 +143708,10 @@ struct DuckDBConstraintsFun { static void RegisterFunction(BuiltinFunctions &set); }; +struct DuckDBDatabasesFun { + static void RegisterFunction(BuiltinFunctions &set); +}; + struct DuckDBDependenciesFun { static void RegisterFunction(BuiltinFunctions &set); }; @@ -135572,11 +143754,11 @@ struct DuckDBViewsFun { struct TestType { TestType(LogicalType type_p, string name_p) - : type(move(type_p)), name(move(name_p)), min_value(Value::MinimumValue(type)), + : type(std::move(type_p)), name(std::move(name_p)), min_value(Value::MinimumValue(type)), max_value(Value::MaximumValue(type)) { } TestType(LogicalType type_p, string name_p, Value min, Value max) - : type(move(type_p)), name(move(name_p)), min_value(move(min)), max_value(move(max)) { + : type(std::move(type_p)), name(std::move(name_p)), min_value(std::move(min)), max_value(std::move(max)) { } LogicalType type; @@ -135664,9 +143846,9 @@ unique_ptr PragmaDetailedProfilingOutputInit(ClientCon static void SetValue(DataChunk &output, int index, int op_id, string annotation, int id, string name, double time, int sample_counter, int tuple_counter, string extra_info) { output.SetValue(0, index, op_id); - output.SetValue(1, index, move(annotation)); + output.SetValue(1, index, std::move(annotation)); output.SetValue(2, index, id); - output.SetValue(3, index, move(name)); + output.SetValue(3, index, std::move(name)); #if defined(RDTSC) output.SetValue(4, index, Value(nullptr)); output.SetValue(5, index, time); @@ -135677,7 +143859,7 @@ static void SetValue(DataChunk &output, int index, int op_id, string annotation, #endif output.SetValue(6, index, sample_counter); output.SetValue(7, index, tuple_counter); - output.SetValue(8, index, move(extra_info)); + output.SetValue(8, index, std::move(extra_info)); } static void ExtractFunctions(ColumnDataCollection &collection, ExpressionInfo &info, DataChunk &chunk, int op_id, @@ -135753,7 +143935,7 @@ static void PragmaDetailedProfilingOutputFunction(ClientContext &context, TableF operator_counter++; } collection->Append(chunk); - data.collection = move(collection); + data.collection = std::move(collection); data.collection->InitializeScan(state.scan_state); state.initialized = true; } @@ -135818,10 +144000,10 @@ static unique_ptr PragmaLastProfilingOutputBind(ClientContext &con static void SetValue(DataChunk &output, int index, int op_id, string name, double time, int64_t car, string description) { output.SetValue(0, index, op_id); - output.SetValue(1, index, move(name)); + output.SetValue(1, index, std::move(name)); output.SetValue(2, index, time); output.SetValue(3, index, car); - output.SetValue(4, index, move(description)); + output.SetValue(4, index, std::move(description)); } unique_ptr PragmaLastProfilingOutputInit(ClientContext &context, @@ -135852,7 +144034,7 @@ static void PragmaLastProfilingOutputFunction(ClientContext &context, TableFunct } } collection->Append(chunk); - data.collection = move(collection); + data.collection = std::move(collection); data.collection->InitializeScan(state.scan_state); state.initialized = true; } @@ -135879,6 +144061,7 @@ void PragmaLastProfilingOutput::RegisterFunction(BuiltinFunctions &set) { + namespace duckdb { struct SummaryTableFunction { @@ -135963,7 +144146,7 @@ static unique_ptr RangeFunctionBind(ClientContext &context, TableF } else { names.emplace_back("range"); } - return move(result); + return std::move(result); } struct RangeFunctionState : public GlobalTableFunctionState { @@ -136082,7 +144265,7 @@ static unique_ptr RangeDateTimeBind(ClientContext &context, TableF result->inclusive_bound = false; names.emplace_back("range"); } - return move(result); + return std::move(result); } struct RangeDateTimeState : public GlobalTableFunctionState { @@ -136169,6 +144352,100 @@ void BuiltinFunctions::RegisterTableFunctions() { +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/union_by_name.hpp +// +// +//===----------------------------------------------------------------------===// + + +#include +#include + + +using std::string; +using std::vector; + +namespace duckdb { + +template +class UnionByName { + +public: + //! Union all files(readers) by their col names + static vector> + UnionCols(ClientContext &context, const vector &files, vector &union_col_types, + vector &union_col_names, case_insensitive_map_t &union_names_map, OPTION_TYPE options) { + idx_t union_names_index = 0; + vector> union_readers; + + for (idx_t file_idx = 0; file_idx < files.size(); ++file_idx) { + const auto file_name = files[file_idx]; + auto reader = make_unique(context, file_name, options); + + auto &col_names = reader->names; + auto &sql_types = reader->return_types; + D_ASSERT(col_names.size() == sql_types.size()); + + for (idx_t col = 0; col < col_names.size(); ++col) { + auto union_find = union_names_map.find(col_names[col]); + + if (union_find != union_names_map.end()) { + // given same name , union_col's type must compatible with col's type + LogicalType compatible_type; + compatible_type = LogicalType::MaxLogicalType(union_col_types[union_find->second], sql_types[col]); + union_col_types[union_find->second] = compatible_type; + } else { + union_names_map[col_names[col]] = union_names_index; + union_names_index++; + + union_col_names.emplace_back(col_names[col]); + union_col_types.emplace_back(sql_types[col]); + } + } + union_readers.push_back(std::move(reader)); + } + return union_readers; + } + + //! Create information for reader's col mapping to union cols + static vector> CreateUnionMap(vector> union_readers, + vector &union_col_types, + vector &union_col_names, + case_insensitive_map_t &union_names_map) { + for (auto &reader : union_readers) { + auto &col_names = reader->names; + vector union_null_cols(union_col_names.size(), true); + vector union_idx_map(col_names.size(), 0); + + for (idx_t col = 0; col < col_names.size(); ++col) { + idx_t union_idx = union_names_map[col_names[col]]; + union_idx_map[col] = union_idx; + union_null_cols[union_idx] = false; + } + + reader->union_col_types = union_col_types; + reader->union_idx_map = std::move(union_idx_map); + reader->union_null_cols = std::move(union_null_cols); + } + return union_readers; + } + + //! Set nulls into the cols that mismtach union names + static void SetNullUnionCols(DataChunk &result, const vector &union_null_cols) { + for (idx_t col = 0; col < union_null_cols.size(); ++col) { + if (union_null_cols[col]) { + result.data[col].SetVectorType(VectorType::CONSTANT_VECTOR); + ConstantVector::SetNull(result.data[col], true); + } + } + } +}; + +} // namespace duckdb + @@ -136200,7 +144477,7 @@ class TableFunctionRef : public TableRef { // if the function takes a subquery as argument its in here unique_ptr subquery; - // External dependencies of this table funcion + // External dependencies of this table function unique_ptr external_dependency; public: @@ -136223,12 +144500,13 @@ class TableFunctionRef : public TableRef { namespace duckdb { -unique_ptr ReadCSV::OpenCSV(const BufferedCSVReaderOptions &options, ClientContext &context) { +unique_ptr ReadCSV::OpenCSV(const string &file_path, FileCompressionType compression, + ClientContext &context) { auto &fs = FileSystem::GetFileSystem(context); auto opener = FileSystem::GetFileOpener(context); - auto file_handle = fs.OpenFile(options.file_path.c_str(), FileFlags::FILE_FLAGS_READ, FileLockType::NO_LOCK, - options.compression, opener); - return make_unique(move(file_handle)); + auto file_handle = + fs.OpenFile(file_path.c_str(), FileFlags::FILE_FLAGS_READ, FileLockType::NO_LOCK, compression, opener); + return make_unique(std::move(file_handle)); } void ReadCSVData::InitializeFiles(ClientContext &context, const vector &patterns) { @@ -136246,7 +144524,14 @@ void ReadCSVData::FinalizeRead(ClientContext &context) { BaseCSVData::Finalize(); auto &config = DBConfig::GetConfig(context); single_threaded = !config.options.experimental_parallel_csv_reader; - if (options.delimiter.size() > 1 || options.escape.size() > 1 || options.quote.size() > 1) { + if (options.has_parallel) { + // Override the option set in the config + single_threaded = !options.use_parallel; + } + bool null_or_empty = options.delimiter.empty() || options.escape.empty() || options.quote.empty() || + options.delimiter[0] == '\0' || options.escape[0] == '\0' || options.quote[0] == '\0'; + bool complex_options = options.delimiter.size() > 1 || options.escape.size() > 1 || options.quote.size() > 1; + if (null_or_empty || complex_options || options.new_line == NewLineIdentifier::MIX) { // not supported for parallel CSV reading single_threaded = true; } @@ -136258,6 +144543,7 @@ static unique_ptr ReadCSVBind(ClientContext &context, TableFunctio if (!config.options.enable_external_access) { throw PermissionException("Scanning CSV files is disabled through configuration"); } + auto result = make_unique(); auto &options = result->options; @@ -136274,9 +144560,11 @@ static unique_ptr ReadCSVBind(ClientContext &context, TableFunctio result->InitializeFiles(context, patterns); + bool explicitly_set_columns = false; for (auto &kv : input.named_parameters) { auto loption = StringUtil::Lower(kv.first); if (loption == "columns") { + explicitly_set_columns = true; auto &child_type = kv.second.type(); if (child_type.id() != LogicalTypeId::STRUCT) { throw BinderException("read_csv columns requires a struct as input"); @@ -136290,11 +144578,51 @@ static unique_ptr ReadCSVBind(ClientContext &context, TableFunctio if (val.type().id() != LogicalTypeId::VARCHAR) { throw BinderException("read_csv requires a type specification as string"); } - return_types.emplace_back(TransformStringToLogicalType(StringValue::Get(val))); + return_types.emplace_back(TransformStringToLogicalType(StringValue::Get(val), context)); } if (names.empty()) { throw BinderException("read_csv requires at least a single column as input!"); } + } else if (loption == "column_types" || loption == "types" || loption == "dtypes") { + auto &child_type = kv.second.type(); + if (child_type.id() != LogicalTypeId::STRUCT && child_type.id() != LogicalTypeId::LIST) { + throw BinderException("read_csv_auto %s requires a struct or list as input", kv.first); + } + if (!options.sql_type_list.empty()) { + throw BinderException("read_csv_auto column_types/types/dtypes can only be supplied once"); + } + vector sql_type_names; + if (child_type.id() == LogicalTypeId::STRUCT) { + auto &struct_children = StructValue::GetChildren(kv.second); + D_ASSERT(StructType::GetChildCount(child_type) == struct_children.size()); + for (idx_t i = 0; i < struct_children.size(); i++) { + auto &name = StructType::GetChildName(child_type, i); + auto &val = struct_children[i]; + if (val.type().id() != LogicalTypeId::VARCHAR) { + throw BinderException("read_csv_auto %s requires a type specification as string", kv.first); + } + sql_type_names.push_back(StringValue::Get(val)); + options.sql_types_per_column[name] = i; + } + } else { + auto &list_child = ListType::GetChildType(child_type); + if (list_child.id() != LogicalTypeId::VARCHAR) { + throw BinderException("read_csv_auto %s requires a list of types (varchar) as input", kv.first); + } + auto &children = ListValue::GetChildren(kv.second); + for (auto &child : children) { + sql_type_names.push_back(StringValue::Get(child)); + } + } + options.sql_type_list.reserve(sql_type_names.size()); + for (auto &sql_type : sql_type_names) { + auto def_type = TransformStringToLogicalType(sql_type); + if (def_type.id() == LogicalTypeId::USER) { + throw BinderException("Unrecognized type \"%s\" for read_csv_auto %s definition", sql_type, + kv.first); + } + options.sql_type_list.push_back(std::move(def_type)); + } } else if (loption == "all_varchar") { options.all_varchar = BooleanValue::Get(kv.second); } else if (loption == "normalize_names") { @@ -136315,15 +144643,24 @@ static unique_ptr ReadCSVBind(ClientContext &context, TableFunctio if (options.auto_detect) { options.file_path = result->files[0]; auto initial_reader = make_unique(context, options); - return_types.assign(initial_reader->sql_types.begin(), initial_reader->sql_types.end()); + return_types.assign(initial_reader->return_types.begin(), initial_reader->return_types.end()); if (names.empty()) { - names.assign(initial_reader->col_names.begin(), initial_reader->col_names.end()); + names.assign(initial_reader->names.begin(), initial_reader->names.end()); } else { - D_ASSERT(return_types.size() == names.size()); + if (explicitly_set_columns) { + // The user has influenced the names, can't assume they are valid anymore + if (return_types.size() != names.size()) { + throw BinderException("The amount of names specified (%d) and the observed amount of types (%d) in " + "the file don't match", + names.size(), return_types.size()); + } + } else { + D_ASSERT(return_types.size() == names.size()); + } } options = initial_reader->options; - result->sql_types = initial_reader->sql_types; - result->initial_reader = move(initial_reader); + result->sql_types = initial_reader->return_types; + result->initial_reader = std::move(initial_reader); } else { result->sql_types = return_types; D_ASSERT(return_types.size() == names.size()); @@ -136331,59 +144668,33 @@ static unique_ptr ReadCSVBind(ClientContext &context, TableFunctio // union_col_names will exclude filename and hivepartition if (options.union_by_name) { - idx_t union_names_index = 0; case_insensitive_map_t union_names_map; vector union_col_names; vector union_col_types; - for (idx_t file_idx = 0; file_idx < result->files.size(); ++file_idx) { - options.file_path = result->files[file_idx]; - auto reader = make_unique(context, options); - auto &col_names = reader->col_names; - auto &sql_types = reader->sql_types; - D_ASSERT(col_names.size() == sql_types.size()); - - for (idx_t col = 0; col < col_names.size(); ++col) { - auto union_find = union_names_map.find(col_names[col]); - - if (union_find != union_names_map.end()) { - // given same name , union_col's type must compatible with col's type - LogicalType compatible_type; - compatible_type = LogicalType::MaxLogicalType(union_col_types[union_find->second], sql_types[col]); - union_col_types[union_find->second] = compatible_type; - } else { - union_names_map[col_names[col]] = union_names_index; - union_names_index++; + auto dummy_readers = UnionByName::UnionCols( + context, result->files, union_col_types, union_col_names, union_names_map, options); - union_col_names.emplace_back(col_names[col]); - union_col_types.emplace_back(sql_types[col]); - } - } - result->union_readers.push_back(move(reader)); - } + dummy_readers = UnionByName::CreateUnionMap( + std::move(dummy_readers), union_col_types, union_col_names, union_names_map); + std::move(dummy_readers.begin(), dummy_readers.end(), std::back_inserter(result->union_readers)); for (auto &reader : result->union_readers) { - auto &col_names = reader->col_names; - vector is_null_cols(union_col_names.size(), true); - - for (idx_t col = 0; col < col_names.size(); ++col) { - idx_t remap_col = union_names_map[col_names[col]]; - reader->insert_cols_idx[col] = remap_col; - is_null_cols[remap_col] = false; - } - for (idx_t col = 0; col < union_col_names.size(); ++col) { - if (is_null_cols[col]) { - reader->insert_nulls_idx.push_back(col); - } - } + reader->insert_cols_idx = reader->union_idx_map; } - const idx_t first_file_index = 0; - result->initial_reader = move(result->union_readers[first_file_index]); - names.assign(union_col_names.begin(), union_col_names.end()); return_types.assign(union_col_types.begin(), union_col_types.end()); + const idx_t first_file_index = 0; + result->initial_reader = std::move(result->union_readers[first_file_index]); D_ASSERT(names.size() == return_types.size()); + + if (!options.sql_types_per_column.empty()) { + auto exception = BufferedCSVReader::ColumnTypesError(options.sql_types_per_column, names); + if (!exception.empty()) { + throw BinderException(exception); + } + } } if (result->options.include_file_name) { @@ -136402,7 +144713,7 @@ static unique_ptr ReadCSVBind(ClientContext &context, TableFunctio } result->options.names = names; result->FinalizeRead(context); - return move(result); + return std::move(result); } static unique_ptr ReadCSVAutoBind(ClientContext &context, TableFunctionBindInput &input, @@ -136421,8 +144732,10 @@ struct ParallelCSVGlobalState : public GlobalTableFunctionState { public: ParallelCSVGlobalState(ClientContext &context, unique_ptr file_handle_p, vector &files_path_p, idx_t system_threads_p, idx_t buffer_size_p, - idx_t rows_to_skip) - : file_handle(move(file_handle_p)), system_threads(system_threads_p), buffer_size(buffer_size_p) { + idx_t rows_to_skip, bool force_parallelism_p) + : file_handle(std::move(file_handle_p)), system_threads(system_threads_p), buffer_size(buffer_size_p), + force_parallelism(force_parallelism_p) { + current_file_path = files_path_p[0]; for (idx_t i = 0; i < rows_to_skip; i++) { file_handle->ReadLine(); } @@ -136431,46 +144744,74 @@ struct ParallelCSVGlobalState : public GlobalTableFunctionState { first_file_size = file_size; bytes_read = 0; if (buffer_size < file_size) { - bytes_per_local_state = buffer_size / MaxThreads(); + bytes_per_local_state = buffer_size / ParallelCSVGlobalState::MaxThreads(); } else { bytes_per_local_state = file_size / MaxThreads(); } - current_buffer = make_shared(context, buffer_size, *file_handle); - next_buffer = current_buffer->Next(*file_handle, buffer_size); + current_buffer = make_shared(context, buffer_size, *file_handle, current_csv_position); + next_buffer = current_buffer->Next(*file_handle, buffer_size, current_csv_position); + running_threads = MaxThreads(); } ParallelCSVGlobalState() { } + ~ParallelCSVGlobalState() override { + } + idx_t MaxThreads() const override; //! Returns buffer and index that caller thread should read. unique_ptr Next(ClientContext &context, ReadCSVData &bind_data); - //! If we finished reading all the CSV Files + //! Verify if the CSV File was read correctly + void Verify(); + + void UpdateVerification(VerificationPositions positions); + + void IncrementThread(); + + void DecrementThread(); + bool Finished(); + //! How many bytes were read up to this point atomic bytes_read; //! Size of current file idx_t file_size; + double GetProgress(ReadCSVData &bind_data) const { + idx_t total_files = bind_data.files.size(); + + // get the progress WITHIN the current file + double progress; + if (file_size == 0) { + progress = 1.0; + } else { + progress = double(bytes_read) / double(file_size); + } + // now get the total percentage of files read + double percentage = double(file_index) / total_files; + percentage += (double(1) / double(total_files)) * progress; + return percentage * 100; + } + private: //! File Handle for current file + unique_ptr prev_file_handle; unique_ptr file_handle; - shared_ptr current_buffer; shared_ptr next_buffer; + //! The index of the next file to read (i.e. current file + 1) idx_t file_index = 1; + string current_file_path; //! Mutex to lock when getting next batch of bytes (Parallel Only) mutex main_mutex; //! Byte set from for last thread idx_t next_byte = 0; - //! The current estimated line number idx_t estimated_linenr; - //! How many bytes we should execute per local state idx_t bytes_per_local_state; - //! Size of first file idx_t first_file_size; //! Basically max number of threads in DuckDB @@ -136479,27 +144820,89 @@ struct ParallelCSVGlobalState : public GlobalTableFunctionState { idx_t buffer_size; //! Current batch index idx_t batch_index = 0; + //! Forces parallelism for small CSV Files, should only be used for testing. + bool force_parallelism; + //! Current (Global) position of CSV + idx_t current_csv_position = 0; + idx_t max_tuple_end = 0; + //! the vector stores positions where threads ended the last line they read in the CSV File, and the set stores + //! positions where they started reading the first line. + vector tuple_end; + set tuple_start; + idx_t running_threads = 0; }; idx_t ParallelCSVGlobalState::MaxThreads() const { - // idx_t one_mb = 1000000; - // idx_t threads_per_mb = first_file_size / one_mb + 1; - // if (threads_per_mb < system_threads) { - // return threads_per_mb; - // } + if (force_parallelism) { + return system_threads; + } + + idx_t one_mb = 1000000; // We initialize max one thread per Mb + idx_t threads_per_mb = first_file_size / one_mb + 1; + if (threads_per_mb < system_threads) { + return threads_per_mb; + } + return system_threads; } +void ParallelCSVGlobalState::IncrementThread() { + lock_guard parallel_lock(main_mutex); + running_threads++; +} + +void ParallelCSVGlobalState::DecrementThread() { + lock_guard parallel_lock(main_mutex); + D_ASSERT(running_threads > 0); + running_threads--; +} + bool ParallelCSVGlobalState::Finished() { lock_guard parallel_lock(main_mutex); - return !current_buffer; + return running_threads == 0; +} + +void ParallelCSVGlobalState::Verify() { + // All threads are done, we run some magic sweet verification code + if (running_threads == 0) { + for (auto &last_pos : tuple_end) { + auto first_pos = tuple_start.find(last_pos); + if (first_pos == tuple_start.end()) { + // this might be necessary due to carriage returns outside buffer scopes. + first_pos = tuple_start.find(last_pos + 1); + } + if (first_pos == tuple_start.end() && last_pos != NumericLimits::Maximum()) { + string error = "Not possible to read this CSV File with multithreading. Tuple: " + to_string(last_pos) + + " does not have a match\n"; + error += "End Lines: \n"; + for (auto &end_line : tuple_end) { + error += to_string(end_line) + "\n"; + } + error += "Start Lines: \n"; + for (auto &start_line : tuple_start) { + error += to_string(start_line) + "\n"; + } + throw InvalidInputException( + "CSV File not supported for multithreading. Please run single-threaded CSV Reading"); + } + } + } } unique_ptr ParallelCSVGlobalState::Next(ClientContext &context, ReadCSVData &bind_data) { lock_guard parallel_lock(main_mutex); if (!current_buffer) { - // We are done scanning. - return nullptr; + // This means we are done with the current file, we need to go to the next one (if exists). + if (file_index < bind_data.files.size()) { + current_file_path = bind_data.files[file_index++]; + file_handle = ReadCSV::OpenCSV(current_file_path, bind_data.options.compression, context); + current_csv_position = 0; + current_buffer = make_shared(context, buffer_size, *file_handle, current_csv_position); + next_buffer = current_buffer->Next(*file_handle, buffer_size, current_csv_position); + } else { + // We are done scanning. + return nullptr; + } } // set up the current buffer auto result = make_unique(current_buffer, next_buffer, next_byte, next_byte + bytes_per_local_state, @@ -136514,19 +144917,22 @@ unique_ptr ParallelCSVGlobalState::Next(ClientContext &context, R current_buffer = next_buffer; if (next_buffer) { // Next buffer gets the next-next buffer - next_buffer = next_buffer->Next(*file_handle, buffer_size); + next_buffer = next_buffer->Next(*file_handle, buffer_size, current_csv_position); } } - if (current_buffer && !next_buffer) { - // This means we are done with the current file, we need to go to the next one (if exists). - if (file_index < bind_data.files.size()) { - bind_data.options.file_path = bind_data.files[file_index++]; - file_handle = ReadCSV::OpenCSV(bind_data.options, context); - next_buffer = make_shared(context, buffer_size, *file_handle); + return result; +} +void ParallelCSVGlobalState::UpdateVerification(VerificationPositions positions) { + lock_guard parallel_lock(main_mutex); + if (positions.beginning_of_first_line < positions.end_of_last_line) { + if (positions.end_of_last_line > max_tuple_end) { + max_tuple_end = positions.end_of_last_line; } + tuple_start.insert(positions.beginning_of_first_line); + tuple_end.push_back(positions.end_of_last_line); } - return result; } + static unique_ptr ParallelCSVInitGlobal(ClientContext &context, TableFunctionInitInput &input) { auto &bind_data = (ReadCSVData &)*input.bind_data; @@ -136537,12 +144943,12 @@ static unique_ptr ParallelCSVInitGlobal(ClientContext unique_ptr file_handle; bind_data.options.file_path = bind_data.files[0]; - file_handle = ReadCSV::OpenCSV(bind_data.options, context); - - idx_t rows_to_skip = bind_data.options.skip_rows + (bind_data.options.has_header ? 1 : 0); - return make_unique(context, move(file_handle), bind_data.files, + file_handle = ReadCSV::OpenCSV(bind_data.options.file_path, bind_data.options.compression, context); + idx_t rows_to_skip = + bind_data.options.skip_rows + (bind_data.options.has_header && bind_data.options.header ? 1 : 0); + return make_unique(context, std::move(file_handle), bind_data.files, context.db->NumberOfThreads(), bind_data.options.buffer_size, - rows_to_skip); + rows_to_skip, ClientConfig::GetConfig(context).verify_parallelism); } //===--------------------------------------------------------------------===// @@ -136550,29 +144956,28 @@ static unique_ptr ParallelCSVInitGlobal(ClientContext //===--------------------------------------------------------------------===// struct ParallelCSVLocalState : public LocalTableFunctionState { public: - explicit ParallelCSVLocalState(unique_ptr csv_reader_p) : csv_reader(move(csv_reader_p)) { + explicit ParallelCSVLocalState(unique_ptr csv_reader_p) : csv_reader(std::move(csv_reader_p)) { } //! The CSV reader unique_ptr csv_reader; CSVBufferRead previous_buffer; + bool done = false; }; -unique_ptr ReadCSVInitLocal(ExecutionContext &context, TableFunctionInitInput &input, - GlobalTableFunctionState *global_state_p) { +unique_ptr ParallelReadCSVInitLocal(ExecutionContext &context, TableFunctionInitInput &input, + GlobalTableFunctionState *global_state_p) { auto &csv_data = (ReadCSVData &)*input.bind_data; - if (csv_data.single_threaded) { - return nullptr; - } auto &global_state = (ParallelCSVGlobalState &)*global_state_p; auto next_local_buffer = global_state.Next(context.client, csv_data); unique_ptr csv_reader; if (next_local_buffer) { - csv_reader = make_unique(context.client, csv_data.options, move(next_local_buffer), + csv_reader = make_unique(context.client, csv_data.options, std::move(next_local_buffer), csv_data.sql_types); + } else { + global_state.DecrementThread(); } - auto new_local_state = make_unique(move(csv_reader)); - return move(new_local_state); + return make_unique(std::move(csv_reader)); } static void ParallelReadCSVFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { @@ -136586,22 +144991,29 @@ static void ParallelReadCSVFunction(ClientContext &context, TableFunctionInput & } do { - if (output.size() != 0 || (csv_global_state.Finished() && csv_local_state.csv_reader->position_buffer >= - csv_local_state.csv_reader->end_buffer)) { + if (output.size() != 0) { break; } - if (csv_local_state.csv_reader->position_buffer >= csv_local_state.csv_reader->end_buffer) { + if (csv_local_state.csv_reader->finished) { + auto verification_updates = csv_local_state.csv_reader->GetVerificationPositions(); + if (!csv_local_state.csv_reader->buffer->next_buffer) { + // if it's the last line of the file we mark as the maximum + verification_updates.end_of_last_line = NumericLimits::Maximum(); + } + csv_global_state.UpdateVerification(verification_updates); auto next_chunk = csv_global_state.Next(context, bind_data); if (!next_chunk) { + csv_global_state.DecrementThread(); break; } - // csv_local_state.previous_buffer = csv_local_state.csv_reader->buffer; - csv_local_state.csv_reader->SetBufferRead(move(next_chunk)); + csv_local_state.csv_reader->SetBufferRead(std::move(next_chunk)); } csv_local_state.csv_reader->ParseCSV(output); } while (true); - + if (csv_global_state.Finished()) { + csv_global_state.Verify(); + } if (bind_data.options.union_by_name) { throw InternalException("FIXME: union by name"); } @@ -136613,91 +145025,173 @@ static void ParallelReadCSVFunction(ClientContext &context, TableFunctionInput & } } -static idx_t CSVReaderGetBatchIndex(ClientContext &context, const FunctionData *bind_data_p, - LocalTableFunctionState *local_state, GlobalTableFunctionState *global_state) { - auto &bind_data = (ReadCSVData &)*bind_data_p; - if (bind_data.single_threaded) { - return 0; - } - auto &data = (ParallelCSVLocalState &)*local_state; - return data.csv_reader->buffer->batch_index; -} - //===--------------------------------------------------------------------===// // Single-Threaded CSV Reader //===--------------------------------------------------------------------===// struct SingleThreadedCSVState : public GlobalTableFunctionState { - //! The CSV reader - unique_ptr csv_reader; + explicit SingleThreadedCSVState(idx_t total_files) : total_files(total_files), next_file(0), progress_in_files(0) { + } + + mutex csv_lock; + unique_ptr initial_reader; + //! The total number of files to read from + idx_t total_files; //! The index of the next file to read (i.e. current file + 1) - idx_t file_index; - //! Total File Size - idx_t file_size; - //! How many bytes were read up to this point - atomic bytes_read; + atomic next_file; + //! How far along we are in reading the current set of open files + //! This goes from [0...next_file] * 100 + atomic progress_in_files; + //! The set of SQL types + vector sql_types; idx_t MaxThreads() const override { - return 1; + return total_files; + } + + double GetProgress(ReadCSVData &bind_data) const { + D_ASSERT(total_files == bind_data.files.size()); + D_ASSERT(progress_in_files <= total_files * 100); + return (double(progress_in_files) / double(total_files)); + } + + unique_ptr GetCSVReader(ClientContext &context, ReadCSVData &bind_data, idx_t &file_index, + idx_t &total_size) { + BufferedCSVReaderOptions options; + { + lock_guard l(csv_lock); + if (initial_reader) { + return std::move(initial_reader); + } + if (next_file >= total_files) { + return nullptr; + } + options = bind_data.options; + file_index = next_file; + next_file++; + } + // reuse csv_readers was created during binding + unique_ptr result; + if (options.union_by_name) { + result = std::move(bind_data.union_readers[file_index]); + } else { + options.file_path = bind_data.files[file_index]; + result = make_unique(context, std::move(options), sql_types); + } + total_size = result->file_handle->FileSize(); + return result; + } +}; + +struct SingleThreadedCSVLocalState : public LocalTableFunctionState { +public: + explicit SingleThreadedCSVLocalState() : bytes_read(0), total_size(0), current_progress(0), file_index(0) { } + + //! The CSV reader + unique_ptr csv_reader; + //! The current amount of bytes read by this reader + idx_t bytes_read; + //! The total amount of bytes in the file + idx_t total_size; + //! The current progress from 0..100 + idx_t current_progress; + //! The file index of this reader + idx_t file_index; }; static unique_ptr SingleThreadedCSVInit(ClientContext &context, TableFunctionInitInput &input) { auto &bind_data = (ReadCSVData &)*input.bind_data; - auto result = make_unique(); + auto result = make_unique(bind_data.files.size()); if (bind_data.initial_reader) { - result->csv_reader = move(bind_data.initial_reader); + result->initial_reader = std::move(bind_data.initial_reader); } else if (bind_data.files.empty()) { // This can happen when a filename based filter pushdown has eliminated all possible files for this scan. - return move(result); + return std::move(result); } else { bind_data.options.file_path = bind_data.files[0]; - result->csv_reader = make_unique(context, bind_data.options, bind_data.sql_types); + result->initial_reader = make_unique(context, bind_data.options, bind_data.sql_types); + if (bind_data.options.auto_detect) { + bind_data.options = result->initial_reader->options; + } + } + if (!bind_data.options.union_by_name) { + // if we are reading multiple files - run auto-detect only on the first file + // UNLESS union by name is turned on - in that case we assume that different files have different schemas + // as such, we need to re-run the auto detection on each file + bind_data.options.auto_detect = false; } - result->file_size = result->csv_reader->file_handle->FileSize(); - result->file_index = 1; - return move(result); + result->next_file = 1; + if (result->initial_reader) { + result->sql_types = result->initial_reader->return_types; + } + return std::move(result); +} + +unique_ptr SingleThreadedReadCSVInitLocal(ExecutionContext &context, + TableFunctionInitInput &input, + GlobalTableFunctionState *global_state_p) { + auto &bind_data = (ReadCSVData &)*input.bind_data; + auto &data = (SingleThreadedCSVState &)*global_state_p; + auto result = make_unique(); + result->csv_reader = data.GetCSVReader(context.client, bind_data, result->file_index, result->total_size); + return std::move(result); } static void SingleThreadedCSVFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { auto &bind_data = (ReadCSVData &)*data_p.bind_data; auto &data = (SingleThreadedCSVState &)*data_p.global_state; - - if (!data.csv_reader) { + auto &lstate = (SingleThreadedCSVLocalState &)*data_p.local_state; + if (!lstate.csv_reader) { // no csv_reader was set, this can happen when a filename-based filter has filtered out all possible files return; } do { - data.csv_reader->ParseCSV(output); - data.bytes_read = data.csv_reader->bytes_in_chunk; - if (output.size() == 0 && data.file_index < bind_data.files.size()) { - // exhausted this file, but we have more files we can read - // open the next file and increment the counter - bind_data.options.file_path = bind_data.files[data.file_index]; - // reuse csv_readers was created during binding - if (bind_data.options.union_by_name) { - data.csv_reader = move(bind_data.union_readers[data.file_index]); - } else { - data.csv_reader = - make_unique(context, bind_data.options, data.csv_reader->sql_types); + lstate.csv_reader->ParseCSV(output); + // update the number of bytes read + D_ASSERT(lstate.bytes_read <= lstate.csv_reader->bytes_in_chunk); + auto bytes_read = MinValue(lstate.total_size, lstate.csv_reader->bytes_in_chunk); + auto current_progress = lstate.total_size == 0 ? 100 : 100 * bytes_read / lstate.total_size; + if (current_progress > lstate.current_progress) { + if (current_progress > 100) { + throw InternalException("Progress should never exceed 100"); + } + data.progress_in_files += current_progress - lstate.current_progress; + lstate.current_progress = current_progress; + } + if (output.size() == 0) { + // exhausted this file, but we might have more files we can read + auto csv_reader = data.GetCSVReader(context, bind_data, lstate.file_index, lstate.total_size); + // add any left-over progress for this file to the progress bar + if (lstate.current_progress < 100) { + data.progress_in_files += 100 - lstate.current_progress; + } + // reset the current progress + lstate.current_progress = 0; + lstate.bytes_read = 0; + lstate.csv_reader = std::move(csv_reader); + if (!lstate.csv_reader) { + // no more files - we are done + return; } - data.file_index++; + lstate.bytes_read = 0; } else { break; } } while (true); if (bind_data.options.union_by_name) { - data.csv_reader->SetNullUnionCols(output); + UnionByName::SetNullUnionCols(output, + lstate.csv_reader->union_null_cols); } if (bind_data.options.include_file_name) { auto &col = output.data[bind_data.filename_col_idx]; - col.SetValue(0, Value(data.csv_reader->options.file_path)); + col.SetValue(0, Value(lstate.csv_reader->options.file_path)); col.SetVectorType(VectorType::CONSTANT_VECTOR); } if (bind_data.options.include_parsed_hive_partitions) { - auto partitions = HivePartitioning::Parse(data.csv_reader->options.file_path); + auto partitions = HivePartitioning::Parse(lstate.csv_reader->options.file_path); idx_t i = bind_data.hive_partition_col_idx; @@ -136710,7 +145204,7 @@ static void SingleThreadedCSVFunction(ClientContext &context, TableFunctionInput for (auto &part : partitions) { if (bind_data.options.names[i] != part.first) { throw IOException("Hive partition names mismatch, expected '" + bind_data.options.names[i] + - "' but found '" + part.first + "' for file '" + data.csv_reader->options.file_path + + "' but found '" + part.first + "' for file '" + lstate.csv_reader->options.file_path + "'"); } auto &col = output.data[i++]; @@ -136732,6 +145226,16 @@ static unique_ptr ReadCSVInitGlobal(ClientContext &con } } +unique_ptr ReadCSVInitLocal(ExecutionContext &context, TableFunctionInitInput &input, + GlobalTableFunctionState *global_state_p) { + auto &csv_data = (ReadCSVData &)*input.bind_data; + if (csv_data.single_threaded) { + return SingleThreadedReadCSVInitLocal(context, input, global_state_p); + } else { + return ParallelReadCSVInitLocal(context, input, global_state_p); + } +} + static void ReadCSVFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { auto &bind_data = (ReadCSVData &)*data_p.bind_data; if (bind_data.single_threaded) { @@ -136741,10 +145245,22 @@ static void ReadCSVFunction(ClientContext &context, TableFunctionInput &data_p, } } +static idx_t CSVReaderGetBatchIndex(ClientContext &context, const FunctionData *bind_data_p, + LocalTableFunctionState *local_state, GlobalTableFunctionState *global_state) { + auto &bind_data = (ReadCSVData &)*bind_data_p; + if (bind_data.single_threaded) { + auto &data = (SingleThreadedCSVLocalState &)*local_state; + return data.file_index; + } + auto &data = (ParallelCSVLocalState &)*local_state; + return data.csv_reader->buffer->batch_index; +} + static void ReadCSVAddNamedParameters(TableFunction &table_function) { table_function.named_parameters["sep"] = LogicalType::VARCHAR; table_function.named_parameters["delim"] = LogicalType::VARCHAR; table_function.named_parameters["quote"] = LogicalType::VARCHAR; + table_function.named_parameters["new_line"] = LogicalType::VARCHAR; table_function.named_parameters["escape"] = LogicalType::VARCHAR; table_function.named_parameters["nullstr"] = LogicalType::VARCHAR; table_function.named_parameters["columns"] = LogicalType::ANY; @@ -136766,26 +145282,20 @@ static void ReadCSVAddNamedParameters(TableFunction &table_function) { table_function.named_parameters["ignore_errors"] = LogicalType::BOOLEAN; table_function.named_parameters["union_by_name"] = LogicalType::BOOLEAN; table_function.named_parameters["buffer_size"] = LogicalType::UBIGINT; + table_function.named_parameters["decimal_separator"] = LogicalType::VARCHAR; + table_function.named_parameters["parallel"] = LogicalType::BOOLEAN; } double CSVReaderProgress(ClientContext &context, const FunctionData *bind_data_p, const GlobalTableFunctionState *global_state) { auto &bind_data = (ReadCSVData &)*bind_data_p; - idx_t file_size, bytes_read; if (bind_data.single_threaded) { - auto &data = (const SingleThreadedCSVState &)*global_state; - file_size = data.file_size; - bytes_read = data.bytes_read; + auto &data = (SingleThreadedCSVState &)*global_state; + return data.GetProgress(bind_data); } else { auto &data = (const ParallelCSVGlobalState &)*global_state; - file_size = data.file_size; - bytes_read = data.bytes_read; - } - if (file_size == 0) { - return 100; + return data.GetProgress(bind_data); } - auto percentage = (bytes_read * 100.0) / file_size; - return percentage; } void CSVComplexFilterPushdown(ClientContext &context, LogicalGet &get, FunctionData *bind_data_p, @@ -136851,6 +145361,7 @@ void BufferedCSVReaderOptions::Serialize(FieldWriter &writer) const { writer.WriteString(file_path); writer.WriteField(include_file_name); writer.WriteField(include_parsed_hive_partitions); + writer.WriteString(decimal_separator); // write options writer.WriteListNoReference(force_quote); } @@ -136883,6 +145394,7 @@ void BufferedCSVReaderOptions::Deserialize(FieldReader &reader) { file_path = reader.ReadRequired(); include_file_name = reader.ReadRequired(); include_parsed_hive_partitions = reader.ReadRequired(); + decimal_separator = reader.ReadRequired(); // write options force_quote = reader.ReadRequiredList(); } @@ -136906,7 +145418,7 @@ static unique_ptr CSVReaderDeserialize(ClientContext &context, Fie result_data->hive_partition_col_idx = reader.ReadRequired(); result_data->options.Deserialize(reader); result_data->single_threaded = reader.ReadField(true); - return move(result_data); + return std::move(result_data); } TableFunction ReadCSVTableFunction::GetFunction(bool list_parameter) { @@ -136933,6 +145445,9 @@ TableFunction ReadCSVTableFunction::GetAutoFunction(bool list_parameter) { read_csv_auto.get_batch_index = CSVReaderGetBatchIndex; read_csv_auto.cardinality = CSVReaderCardinality; ReadCSVAddNamedParameters(read_csv_auto); + read_csv_auto.named_parameters["column_types"] = LogicalType::ANY; + read_csv_auto.named_parameters["dtypes"] = LogicalType::ANY; + read_csv_auto.named_parameters["types"] = LogicalType::ANY; return read_csv_auto; } @@ -136948,8 +145463,7 @@ void ReadCSVTableFunction::RegisterFunction(BuiltinFunctions &set) { set.AddFunction(read_csv_auto); } -unique_ptr ReadCSVReplacement(ClientContext &context, const string &table_name, - ReplacementScanData *data) { +unique_ptr ReadCSVReplacement(ClientContext &context, const string &table_name, ReplacementScanData *data) { auto lower_name = StringUtil::Lower(table_name); // remove any compression if (StringUtil::EndsWith(lower_name, ".gz")) { @@ -136964,14 +145478,14 @@ unique_ptr ReadCSVReplacement(ClientContext &context, const st auto table_function = make_unique(); vector> children; children.push_back(make_unique(Value(table_name))); - table_function->function = make_unique("read_csv_auto", move(children)); - return table_function; + table_function->function = make_unique("read_csv_auto", std::move(children)); + return std::move(table_function); } void BuiltinFunctions::RegisterReadFunctions() { CSVCopyFunction::RegisterFunction(*this); ReadCSVTableFunction::RegisterFunction(*this); - auto &config = DBConfig::GetConfig(context); + auto &config = DBConfig::GetConfig(*transaction.db); config.replacement_scans.emplace_back(ReadCSVReplacement); } @@ -136982,7 +145496,7 @@ void BuiltinFunctions::RegisterReadFunctions() { namespace duckdb { struct RepeatFunctionData : public TableFunctionData { - RepeatFunctionData(Value value, idx_t target_count) : value(move(value)), target_count(target_count) { + RepeatFunctionData(Value value, idx_t target_count) : value(std::move(value)), target_count(target_count) { } Value value; @@ -137107,18 +145621,24 @@ struct DuckDBColumnsData : public GlobalTableFunctionState { static unique_ptr DuckDBColumnsBind(ClientContext &context, TableFunctionBindInput &input, vector &return_types, vector &names) { - names.emplace_back("schema_oid"); + names.emplace_back("database_name"); + return_types.emplace_back(LogicalType::VARCHAR); + + names.emplace_back("database_oid"); return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("schema_name"); return_types.emplace_back(LogicalType::VARCHAR); - names.emplace_back("table_oid"); + names.emplace_back("schema_oid"); return_types.emplace_back(LogicalType::BIGINT); names.emplace_back("table_name"); return_types.emplace_back(LogicalType::VARCHAR); + names.emplace_back("table_oid"); + return_types.emplace_back(LogicalType::BIGINT); + names.emplace_back("column_name"); return_types.emplace_back(LogicalType::VARCHAR); @@ -137159,15 +145679,11 @@ unique_ptr DuckDBColumnsInit(ClientContext &context, T auto result = make_unique(); // scan all the schemas for tables and views and collect them - auto schemas = Catalog::GetCatalog(context).schemas->GetEntries(context); + auto schemas = Catalog::GetAllSchemas(context); for (auto &schema : schemas) { schema->Scan(context, CatalogType::TABLE_ENTRY, [&](CatalogEntry *entry) { result->entries.push_back(entry); }); } - - // check the temp schema as well - SchemaCatalogEntry::GetTemporaryObjects(context)->Scan( - context, CatalogType::TABLE_ENTRY, [&](CatalogEntry *entry) { result->entries.push_back(entry); }); - return move(result); + return std::move(result); } class ColumnHelper { @@ -137190,7 +145706,7 @@ class ColumnHelper { class TableColumnHelper : public ColumnHelper { public: explicit TableColumnHelper(TableCatalogEntry *entry) : entry(entry) { - for (auto &constraint : entry->constraints) { + for (auto &constraint : entry->GetConstraints()) { if (constraint->type == ConstraintType::NOT_NULL) { auto ¬_null = *reinterpret_cast(constraint.get()); not_null_cols.insert(not_null.index.index); @@ -137202,16 +145718,16 @@ class TableColumnHelper : public ColumnHelper { return entry; } idx_t NumColumns() override { - return entry->columns.LogicalColumnCount(); + return entry->GetColumns().LogicalColumnCount(); } const string &ColumnName(idx_t col) override { - return entry->columns.GetColumn(LogicalIndex(col)).Name(); + return entry->GetColumn(LogicalIndex(col)).Name(); } const LogicalType &ColumnType(idx_t col) override { - return entry->columns.GetColumn(LogicalIndex(col)).Type(); + return entry->GetColumn(LogicalIndex(col)).Type(); } const Value ColumnDefault(idx_t col) override { - auto &column = entry->columns.GetColumn(LogicalIndex(col)); + auto &column = entry->GetColumn(LogicalIndex(col)); if (column.DefaultValue()) { return Value(column.DefaultValue()->ToString()); } @@ -137270,36 +145786,41 @@ void ColumnHelper::WriteColumns(idx_t start_index, idx_t start_col, idx_t end_co auto index = start_index + (i - start_col); auto &entry = *Entry(); - // schema_oid, BIGINT - output.SetValue(0, index, Value::BIGINT(entry.schema->oid)); + idx_t col = 0; + // database_name, VARCHAR + output.SetValue(col++, index, entry.catalog->GetName()); + // database_oid, BIGINT + output.SetValue(col++, index, Value::BIGINT(entry.catalog->GetOid())); // schema_name, VARCHAR - output.SetValue(1, index, entry.schema->name); - // table_oid, BIGINT - output.SetValue(2, index, Value::BIGINT(entry.oid)); + output.SetValue(col++, index, entry.schema->name); + // schema_oid, BIGINT + output.SetValue(col++, index, Value::BIGINT(entry.schema->oid)); // table_name, VARCHAR - output.SetValue(3, index, entry.name); + output.SetValue(col++, index, entry.name); + // table_oid, BIGINT + output.SetValue(col++, index, Value::BIGINT(entry.oid)); // column_name, VARCHAR - output.SetValue(4, index, Value(ColumnName(i))); + output.SetValue(col++, index, Value(ColumnName(i))); // column_index, INTEGER - output.SetValue(5, index, Value::INTEGER(i + 1)); + output.SetValue(col++, index, Value::INTEGER(i + 1)); // internal, BOOLEAN - output.SetValue(6, index, Value::BOOLEAN(entry.internal)); + output.SetValue(col++, index, Value::BOOLEAN(entry.internal)); // column_default, VARCHAR - output.SetValue(7, index, Value(ColumnDefault(i))); + output.SetValue(col++, index, Value(ColumnDefault(i))); // is_nullable, BOOLEAN - output.SetValue(8, index, Value::BOOLEAN(IsNullable(i))); + output.SetValue(col++, index, Value::BOOLEAN(IsNullable(i))); // data_type, VARCHAR const LogicalType &type = ColumnType(i); - output.SetValue(9, index, Value(type.ToString())); + output.SetValue(col++, index, Value(type.ToString())); // data_type_id, BIGINT - output.SetValue(10, index, Value::BIGINT(int(type.id()))); + output.SetValue(col++, index, Value::BIGINT(int(type.id()))); if (type == LogicalType::VARCHAR) { // FIXME: need check constraints in place to set this correctly // character_maximum_length, INTEGER - output.SetValue(11, index, Value()); + output.SetValue(col++, index, Value()); } else { // "character_maximum_length", PhysicalType::INTEGER - output.SetValue(11, index, Value()); + output.SetValue(col++, index, Value()); } Value numeric_precision, numeric_scale, numeric_precision_radix; @@ -137352,11 +145873,11 @@ void ColumnHelper::WriteColumns(idx_t start_index, idx_t start_col, idx_t end_co } // numeric_precision, INTEGER - output.SetValue(12, index, numeric_precision); + output.SetValue(col++, index, numeric_precision); // numeric_precision_radix, INTEGER - output.SetValue(13, index, numeric_precision_radix); + output.SetValue(col++, index, numeric_precision_radix); // numeric_scale, INTEGER - output.SetValue(14, index, numeric_scale); + output.SetValue(col++, index, numeric_scale); } } @@ -137423,6 +145944,7 @@ void DuckDBColumnsFun::RegisterFunction(BuiltinFunctions &set) { + namespace duckdb { struct UniqueKeyInfo { @@ -137468,6 +145990,12 @@ struct DuckDBConstraintsData : public GlobalTableFunctionState { static unique_ptr DuckDBConstraintsBind(ClientContext &context, TableFunctionBindInput &input, vector &return_types, vector &names) { + names.emplace_back("database_name"); + return_types.emplace_back(LogicalType::VARCHAR); + + names.emplace_back("database_oid"); + return_types.emplace_back(LogicalType::BIGINT); + names.emplace_back("schema_name"); return_types.emplace_back(LogicalType::VARCHAR); @@ -137506,13 +146034,7 @@ unique_ptr DuckDBConstraintsInit(ClientContext &contex auto result = make_unique(); // scan all the schemas for tables and collect them - auto schemas = Catalog::GetCatalog(context).schemas->GetEntries(context); - - sort(schemas.begin(), schemas.end(), [&](CatalogEntry *x, CatalogEntry *y) { return (x->name < y->name); }); - - // check the temp schema as well - auto temp_schema = SchemaCatalogEntry::GetTemporaryObjects(context); - schemas.push_back(temp_schema); + auto schemas = Catalog::GetAllSchemas(context); for (auto &schema : schemas) { vector entries; @@ -137528,7 +146050,7 @@ unique_ptr DuckDBConstraintsInit(ClientContext &contex result->entries.insert(result->entries.end(), entries.begin(), entries.end()); }; - return move(result); + return std::move(result); } void DuckDBConstraintsFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { @@ -137545,9 +146067,10 @@ void DuckDBConstraintsFunction(ClientContext &context, TableFunctionInput &data_ D_ASSERT(entry->type == CatalogType::TABLE_ENTRY); auto &table = (TableCatalogEntry &)*entry; - for (; data.constraint_offset < table.constraints.size() && count < STANDARD_VECTOR_SIZE; - data.constraint_offset++) { - auto &constraint = table.constraints[data.constraint_offset]; + auto &constraints = table.GetConstraints(); + bool is_duck_table = table.IsDuckTable(); + for (; data.constraint_offset < constraints.size() && count < STANDARD_VECTOR_SIZE; data.constraint_offset++) { + auto &constraint = constraints[data.constraint_offset]; // return values: // constraint_type, VARCHAR // Processing this first due to shortcut (early continue) @@ -137565,8 +146088,11 @@ void DuckDBConstraintsFunction(ClientContext &context, TableFunctionInput &data_ constraint_type = "NOT NULL"; break; case ConstraintType::FOREIGN_KEY: { - auto &bound_foreign_key = - (const BoundForeignKeyConstraint &)*table.bound_constraints[data.constraint_offset]; + if (!is_duck_table) { + continue; + } + auto &bound_constraints = table.GetBoundConstraints(); + auto &bound_foreign_key = (const BoundForeignKeyConstraint &)*bound_constraints[data.constraint_offset]; if (bound_foreign_key.info.type == ForeignKeyType::FK_TYPE_PRIMARY_KEY_TABLE) { // Those are already covered by PRIMARY KEY and UNIQUE entries continue; @@ -137577,63 +146103,70 @@ void DuckDBConstraintsFunction(ClientContext &context, TableFunctionInput &data_ default: throw NotImplementedException("Unimplemented constraint for duckdb_constraints"); } - output.SetValue(5, count, Value(constraint_type)); + idx_t col = 0; + // database_name, LogicalType::VARCHAR + output.SetValue(col++, count, Value(table.schema->catalog->GetName())); + // database_oid, LogicalType::BIGINT + output.SetValue(col++, count, Value::BIGINT(table.schema->catalog->GetOid())); // schema_name, LogicalType::VARCHAR - output.SetValue(0, count, Value(table.schema->name)); + output.SetValue(col++, count, Value(table.schema->name)); // schema_oid, LogicalType::BIGINT - output.SetValue(1, count, Value::BIGINT(table.schema->oid)); + output.SetValue(col++, count, Value::BIGINT(table.schema->oid)); // table_name, LogicalType::VARCHAR - output.SetValue(2, count, Value(table.name)); + output.SetValue(col++, count, Value(table.name)); // table_oid, LogicalType::BIGINT - output.SetValue(3, count, Value::BIGINT(table.oid)); + output.SetValue(col++, count, Value::BIGINT(table.oid)); // constraint_index, BIGINT - auto &bound_constraint = (BoundConstraint &)*table.bound_constraints[data.constraint_offset]; UniqueKeyInfo uk_info; - switch (bound_constraint.type) { - case ConstraintType::UNIQUE: { - auto &bound_unique = (BoundUniqueConstraint &)bound_constraint; - uk_info = {table.schema->name, table.name, bound_unique.keys}; - break; - } - case ConstraintType::FOREIGN_KEY: { - const auto &bound_foreign_key = (const BoundForeignKeyConstraint &)bound_constraint; - const auto &info = bound_foreign_key.info; - // find the other table - auto &catalog = Catalog::GetCatalog(context); - auto table_entry = (TableCatalogEntry *)catalog.GetEntry(context, CatalogType::TABLE_ENTRY, info.schema, - info.table, true); - if (!table_entry) { - throw InternalException("dukdb_constraints: entry %s.%s referenced in foreign key not found", - info.schema, info.table); + + if (is_duck_table) { + auto &bound_constraint = (BoundConstraint &)*table.GetBoundConstraints()[data.constraint_offset]; + switch (bound_constraint.type) { + case ConstraintType::UNIQUE: { + auto &bound_unique = (BoundUniqueConstraint &)bound_constraint; + uk_info = {table.schema->name, table.name, bound_unique.keys}; + break; } - vector index; - for (auto &key : info.pk_keys) { - index.push_back(table_entry->columns.PhysicalToLogical(key)); + case ConstraintType::FOREIGN_KEY: { + const auto &bound_foreign_key = (const BoundForeignKeyConstraint &)bound_constraint; + const auto &info = bound_foreign_key.info; + // find the other table + auto table_entry = + Catalog::GetEntry(context, INVALID_CATALOG, info.schema, info.table, true); + if (!table_entry) { + throw InternalException("dukdb_constraints: entry %s.%s referenced in foreign key not found", + info.schema, info.table); + } + vector index; + for (auto &key : info.pk_keys) { + index.push_back(table_entry->GetColumns().PhysicalToLogical(key)); + } + uk_info = {table_entry->schema->name, table_entry->name, index}; + break; + } + default: + break; } - uk_info = {table_entry->schema->name, table_entry->name, index}; - break; - } - default: - break; } if (uk_info.columns.empty()) { - output.SetValue(4, count, Value::BIGINT(data.unique_constraint_offset++)); + output.SetValue(col++, count, Value::BIGINT(data.unique_constraint_offset++)); } else { auto known_unique_constraint_offset = data.known_fk_unique_constraint_offsets.find(uk_info); if (known_unique_constraint_offset == data.known_fk_unique_constraint_offsets.end()) { data.known_fk_unique_constraint_offsets.insert(make_pair(uk_info, data.unique_constraint_offset)); - output.SetValue(4, count, Value::BIGINT(data.unique_constraint_offset)); + output.SetValue(col++, count, Value::BIGINT(data.unique_constraint_offset)); data.unique_constraint_offset++; } else { - output.SetValue(4, count, Value::BIGINT(known_unique_constraint_offset->second)); + output.SetValue(col++, count, Value::BIGINT(known_unique_constraint_offset->second)); } } + output.SetValue(col++, count, Value(constraint_type)); // constraint_text, VARCHAR - output.SetValue(6, count, Value(constraint->ToString())); + output.SetValue(col++, count, Value(constraint->ToString())); // expression, VARCHAR Value expression_text; @@ -137641,56 +146174,59 @@ void DuckDBConstraintsFunction(ClientContext &context, TableFunctionInput &data_ auto &check = (CheckConstraint &)*constraint; expression_text = Value(check.expression->ToString()); } - output.SetValue(7, count, expression_text); + output.SetValue(col++, count, expression_text); vector column_index_list; - switch (bound_constraint.type) { - case ConstraintType::CHECK: { - auto &bound_check = (BoundCheckConstraint &)bound_constraint; - for (auto &col_idx : bound_check.bound_columns) { - column_index_list.push_back(table.columns.PhysicalToLogical(col_idx)); + if (is_duck_table) { + auto &bound_constraint = (BoundConstraint &)*table.GetBoundConstraints()[data.constraint_offset]; + switch (bound_constraint.type) { + case ConstraintType::CHECK: { + auto &bound_check = (BoundCheckConstraint &)bound_constraint; + for (auto &col_idx : bound_check.bound_columns) { + column_index_list.push_back(table.GetColumns().PhysicalToLogical(col_idx)); + } + break; } - break; - } - case ConstraintType::UNIQUE: { - auto &bound_unique = (BoundUniqueConstraint &)bound_constraint; - for (auto &col_idx : bound_unique.keys) { - column_index_list.push_back(col_idx); + case ConstraintType::UNIQUE: { + auto &bound_unique = (BoundUniqueConstraint &)bound_constraint; + for (auto &col_idx : bound_unique.keys) { + column_index_list.push_back(col_idx); + } + break; } - break; - } - case ConstraintType::NOT_NULL: { - auto &bound_not_null = (BoundNotNullConstraint &)bound_constraint; - column_index_list.push_back(table.columns.PhysicalToLogical(bound_not_null.index)); - break; - } - case ConstraintType::FOREIGN_KEY: { - auto &bound_foreign_key = (const BoundForeignKeyConstraint &)bound_constraint; - for (auto &col_idx : bound_foreign_key.info.fk_keys) { - column_index_list.push_back(table.columns.PhysicalToLogical(col_idx)); + case ConstraintType::NOT_NULL: { + auto &bound_not_null = (BoundNotNullConstraint &)bound_constraint; + column_index_list.push_back(table.GetColumns().PhysicalToLogical(bound_not_null.index)); + break; + } + case ConstraintType::FOREIGN_KEY: { + auto &bound_foreign_key = (const BoundForeignKeyConstraint &)bound_constraint; + for (auto &col_idx : bound_foreign_key.info.fk_keys) { + column_index_list.push_back(table.GetColumns().PhysicalToLogical(col_idx)); + } + break; + } + default: + throw NotImplementedException("Unimplemented constraint for duckdb_constraints"); } - break; - } - default: - throw NotImplementedException("Unimplemented constraint for duckdb_constraints"); } vector index_list; vector column_name_list; for (auto column_index : column_index_list) { index_list.push_back(Value::BIGINT(column_index.index)); - column_name_list.emplace_back(table.columns.GetColumn(column_index).Name()); + column_name_list.emplace_back(table.GetColumn(column_index).Name()); } // constraint_column_indexes, LIST - output.SetValue(8, count, Value::LIST(move(index_list))); + output.SetValue(col++, count, Value::LIST(LogicalType::BIGINT, std::move(index_list))); // constraint_column_names, LIST - output.SetValue(9, count, Value::LIST(move(column_name_list))); + output.SetValue(col++, count, Value::LIST(LogicalType::VARCHAR, std::move(column_name_list))); count++; } - if (data.constraint_offset >= table.constraints.size()) { + if (data.constraint_offset >= constraints.size()) { data.constraint_offset = 0; data.offset++; } @@ -137708,6 +146244,96 @@ void DuckDBConstraintsFun::RegisterFunction(BuiltinFunctions &set) { +namespace duckdb { + +struct DuckDBDatabasesData : public GlobalTableFunctionState { + DuckDBDatabasesData() : offset(0) { + } + + vector entries; + idx_t offset; +}; + +static unique_ptr DuckDBDatabasesBind(ClientContext &context, TableFunctionBindInput &input, + vector &return_types, vector &names) { + names.emplace_back("database_name"); + return_types.emplace_back(LogicalType::VARCHAR); + + names.emplace_back("database_oid"); + return_types.emplace_back(LogicalType::BIGINT); + + names.emplace_back("path"); + return_types.emplace_back(LogicalType::VARCHAR); + + names.emplace_back("internal"); + return_types.emplace_back(LogicalType::BOOLEAN); + + names.emplace_back("type"); + return_types.emplace_back(LogicalType::VARCHAR); + + return nullptr; +} + +unique_ptr DuckDBDatabasesInit(ClientContext &context, TableFunctionInitInput &input) { + auto result = make_unique(); + + // scan all the schemas for tables and collect them and collect them + auto &db_manager = DatabaseManager::Get(context); + result->entries = db_manager.GetDatabases(context); + return std::move(result); +} + +void DuckDBDatabasesFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { + auto &data = (DuckDBDatabasesData &)*data_p.global_state; + if (data.offset >= data.entries.size()) { + // finished returning values + return; + } + // start returning values + // either fill up the chunk or return all the remaining columns + idx_t count = 0; + while (data.offset < data.entries.size() && count < STANDARD_VECTOR_SIZE) { + auto &entry = data.entries[data.offset++]; + + auto &attached = (AttachedDatabase &)*entry; + // return values: + + idx_t col = 0; + // database_name, VARCHAR + output.SetValue(col++, count, attached.GetName()); + // database_oid, BIGINT + output.SetValue(col++, count, Value::BIGINT(attached.oid)); + // path, VARCHAR + bool is_internal = attached.IsSystem() || attached.IsTemporary(); + Value db_path; + if (!is_internal) { + bool in_memory = attached.GetCatalog().InMemory(); + if (!in_memory) { + db_path = Value(attached.GetCatalog().GetDBPath()); + } + } + output.SetValue(col++, count, db_path); + // internal, BOOLEAN + output.SetValue(col++, count, Value::BOOLEAN(is_internal)); + // type, VARCHAR + output.SetValue(col++, count, Value(attached.GetCatalog().GetCatalogType())); + + count++; + } + output.SetCardinality(count); +} + +void DuckDBDatabasesFun::RegisterFunction(BuiltinFunctions &set) { + set.AddFunction( + TableFunction("duckdb_databases", {}, DuckDBDatabasesFunction, DuckDBDatabasesBind, DuckDBDatabasesInit)); +} + +} // namespace duckdb + + + + + @@ -137757,17 +146383,20 @@ unique_ptr DuckDBDependenciesInit(ClientContext &conte auto result = make_unique(); // scan all the schemas and collect them - auto &catalog = Catalog::GetCatalog(context); - auto &dependency_manager = catalog.GetDependencyManager(); - dependency_manager.Scan([&](CatalogEntry *obj, CatalogEntry *dependent, DependencyType type) { - DependencyInformation info; - info.object = obj; - info.dependent = dependent; - info.type = type; - result->entries.push_back(info); - }); + auto &catalog = Catalog::GetCatalog(context, INVALID_CATALOG); + if (catalog.IsDuckCatalog()) { + auto &duck_catalog = (DuckCatalog &)catalog; + auto &dependency_manager = duck_catalog.GetDependencyManager(); + dependency_manager.Scan([&](CatalogEntry *obj, CatalogEntry *dependent, DependencyType type) { + DependencyInformation info; + info.object = obj; + info.dependent = dependent; + info.type = type; + result->entries.push_back(info); + }); + } - return move(result); + return std::move(result); } void DuckDBDependenciesFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { @@ -137892,11 +146521,11 @@ unique_ptr DuckDBExtensionsInit(ClientContext &context info.description = extension.description; for (idx_t k = 0; k < alias_count; k++) { auto alias = ExtensionHelper::GetExtensionAlias(k); - if (alias.extension == extension.name) { + if (info.name == alias.extension) { info.aliases.emplace_back(alias.alias); } } - installed_extensions[info.name] = move(info); + installed_extensions[info.name] = std::move(info); } // scan the install directory for installed extensions @@ -137911,7 +146540,7 @@ unique_ptr DuckDBExtensionsInit(ClientContext &context info.file_path = fs.JoinPath(ext_directory, path); auto entry = installed_extensions.find(info.name); if (entry == installed_extensions.end()) { - installed_extensions[info.name] = move(info); + installed_extensions[info.name] = std::move(info); } else { if (!entry->second.loaded) { entry->second.file_path = info.file_path; @@ -137928,7 +146557,7 @@ unique_ptr DuckDBExtensionsInit(ClientContext &context ExtensionInformation info; info.name = ext_name; info.loaded = true; - installed_extensions[ext_name] = move(info); + installed_extensions[ext_name] = std::move(info); } else { entry->second.loaded = true; } @@ -137936,9 +146565,9 @@ unique_ptr DuckDBExtensionsInit(ClientContext &context result->entries.reserve(installed_extensions.size()); for (auto &kv : installed_extensions) { - result->entries.push_back(move(kv.second)); + result->entries.push_back(std::move(kv.second)); } - return move(result); + return std::move(result); } void DuckDBExtensionsFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { @@ -138010,6 +146639,9 @@ struct DuckDBFunctionsData : public GlobalTableFunctionState { static unique_ptr DuckDBFunctionsBind(ClientContext &context, TableFunctionBindInput &input, vector &return_types, vector &names) { + names.emplace_back("database_name"); + return_types.emplace_back(LogicalType::VARCHAR); + names.emplace_back("schema_name"); return_types.emplace_back(LogicalType::VARCHAR); @@ -138040,6 +146672,9 @@ static unique_ptr DuckDBFunctionsBind(ClientContext &context, Tabl names.emplace_back("has_side_effects"); return_types.emplace_back(LogicalType::BOOLEAN); + names.emplace_back("internal"); + return_types.emplace_back(LogicalType::BOOLEAN); + names.emplace_back("function_oid"); return_types.emplace_back(LogicalType::BIGINT); @@ -138060,15 +146695,14 @@ unique_ptr DuckDBFunctionsInit(ClientContext &context, auto result = make_unique(); // scan all the schemas for tables and collect themand collect them - auto schemas = Catalog::GetCatalog(context).schemas->GetEntries(context); + auto schemas = Catalog::GetAllSchemas(context); for (auto &schema : schemas) { ExtractFunctionsFromSchema(context, *schema, *result); }; - ExtractFunctionsFromSchema(context, *SchemaCatalogEntry::GetTemporaryObjects(context), *result); std::sort(result->entries.begin(), result->entries.end(), [&](CatalogEntry *a, CatalogEntry *b) { return (int)a->type < (int)b->type; }); - return move(result); + return std::move(result); } struct ScalarFunctionExtractor { @@ -138093,7 +146727,7 @@ struct ScalarFunctionExtractor { for (idx_t i = 0; i < entry.functions.GetFunctionByOffset(offset).arguments.size(); i++) { results.emplace_back("col" + to_string(i)); } - return Value::LIST(LogicalType::VARCHAR, move(results)); + return Value::LIST(LogicalType::VARCHAR, std::move(results)); } static Value GetParameterTypes(ScalarFunctionCatalogEntry &entry, idx_t offset) { @@ -138102,7 +146736,7 @@ struct ScalarFunctionExtractor { for (idx_t i = 0; i < fun.arguments.size(); i++) { results.emplace_back(fun.arguments[i].ToString()); } - return Value::LIST(LogicalType::VARCHAR, move(results)); + return Value::LIST(LogicalType::VARCHAR, std::move(results)); } static Value GetVarArgs(ScalarFunctionCatalogEntry &entry, idx_t offset) { @@ -138142,7 +146776,7 @@ struct AggregateFunctionExtractor { for (idx_t i = 0; i < entry.functions.GetFunctionByOffset(offset).arguments.size(); i++) { results.emplace_back("col" + to_string(i)); } - return Value::LIST(LogicalType::VARCHAR, move(results)); + return Value::LIST(LogicalType::VARCHAR, std::move(results)); } static Value GetParameterTypes(AggregateFunctionCatalogEntry &entry, idx_t offset) { @@ -138151,7 +146785,7 @@ struct AggregateFunctionExtractor { for (idx_t i = 0; i < fun.arguments.size(); i++) { results.emplace_back(fun.arguments[i].ToString()); } - return Value::LIST(LogicalType::VARCHAR, move(results)); + return Value::LIST(LogicalType::VARCHAR, std::move(results)); } static Value GetVarArgs(AggregateFunctionCatalogEntry &entry, idx_t offset) { @@ -138196,7 +146830,7 @@ struct MacroExtractor { for (auto ¶m_entry : entry.function->default_parameters) { results.emplace_back(param_entry.first); } - return Value::LIST(LogicalType::VARCHAR, move(results)); + return Value::LIST(LogicalType::VARCHAR, std::move(results)); } static Value GetParameterTypes(ScalarMacroCatalogEntry &entry, idx_t offset) { @@ -138207,7 +146841,7 @@ struct MacroExtractor { for (idx_t i = 0; i < entry.function->default_parameters.size(); i++) { results.emplace_back(LogicalType::VARCHAR); } - return Value::LIST(LogicalType::VARCHAR, move(results)); + return Value::LIST(LogicalType::VARCHAR, std::move(results)); } static Value GetVarArgs(ScalarMacroCatalogEntry &entry, idx_t offset) { @@ -138252,7 +146886,7 @@ struct TableMacroExtractor { for (auto ¶m_entry : entry.function->default_parameters) { results.emplace_back(param_entry.first); } - return Value::LIST(LogicalType::VARCHAR, move(results)); + return Value::LIST(LogicalType::VARCHAR, std::move(results)); } static Value GetParameterTypes(TableMacroCatalogEntry &entry, idx_t offset) { @@ -138263,7 +146897,7 @@ struct TableMacroExtractor { for (idx_t i = 0; i < entry.function->default_parameters.size(); i++) { results.emplace_back(LogicalType::VARCHAR); } - return Value::LIST(LogicalType::VARCHAR, move(results)); + return Value::LIST(LogicalType::VARCHAR, std::move(results)); } static Value GetVarArgs(TableMacroCatalogEntry &entry, idx_t offset) { @@ -138309,7 +146943,7 @@ struct TableFunctionExtractor { for (auto ¶m : fun.named_parameters) { results.emplace_back(param.first); } - return Value::LIST(LogicalType::VARCHAR, move(results)); + return Value::LIST(LogicalType::VARCHAR, std::move(results)); } static Value GetParameterTypes(TableFunctionCatalogEntry &entry, idx_t offset) { @@ -138322,7 +146956,7 @@ struct TableFunctionExtractor { for (auto ¶m : fun.named_parameters) { results.emplace_back(param.second.ToString()); } - return Value::LIST(LogicalType::VARCHAR, move(results)); + return Value::LIST(LogicalType::VARCHAR, std::move(results)); } static Value GetVarArgs(TableFunctionCatalogEntry &entry, idx_t offset) { @@ -138366,7 +147000,7 @@ struct PragmaFunctionExtractor { for (auto ¶m : fun.named_parameters) { results.emplace_back(param.first); } - return Value::LIST(LogicalType::VARCHAR, move(results)); + return Value::LIST(LogicalType::VARCHAR, std::move(results)); } static Value GetParameterTypes(PragmaFunctionCatalogEntry &entry, idx_t offset) { @@ -138379,7 +147013,7 @@ struct PragmaFunctionExtractor { for (auto ¶m : fun.named_parameters) { results.emplace_back(param.second.ToString()); } - return Value::LIST(LogicalType::VARCHAR, move(results)); + return Value::LIST(LogicalType::VARCHAR, std::move(results)); } static Value GetVarArgs(PragmaFunctionCatalogEntry &entry, idx_t offset) { @@ -138399,38 +147033,46 @@ struct PragmaFunctionExtractor { template bool ExtractFunctionData(StandardEntry *entry, idx_t function_idx, DataChunk &output, idx_t output_offset) { auto &function = (T &)*entry; + idx_t col = 0; + + // database_name, LogicalType::VARCHAR + output.SetValue(col++, output_offset, Value(entry->schema->catalog->GetName())); + // schema_name, LogicalType::VARCHAR - output.SetValue(0, output_offset, Value(entry->schema->name)); + output.SetValue(col++, output_offset, Value(entry->schema->name)); // function_name, LogicalType::VARCHAR - output.SetValue(1, output_offset, Value(entry->name)); + output.SetValue(col++, output_offset, Value(entry->name)); // function_type, LogicalType::VARCHAR - output.SetValue(2, output_offset, Value(OP::GetFunctionType())); + output.SetValue(col++, output_offset, Value(OP::GetFunctionType())); // function_description, LogicalType::VARCHAR - output.SetValue(3, output_offset, OP::GetFunctionDescription(function, function_idx)); + output.SetValue(col++, output_offset, OP::GetFunctionDescription(function, function_idx)); // return_type, LogicalType::VARCHAR - output.SetValue(4, output_offset, OP::GetReturnType(function, function_idx)); + output.SetValue(col++, output_offset, OP::GetReturnType(function, function_idx)); // parameters, LogicalType::LIST(LogicalType::VARCHAR) - output.SetValue(5, output_offset, OP::GetParameters(function, function_idx)); + output.SetValue(col++, output_offset, OP::GetParameters(function, function_idx)); // parameter_types, LogicalType::LIST(LogicalType::VARCHAR) - output.SetValue(6, output_offset, OP::GetParameterTypes(function, function_idx)); + output.SetValue(col++, output_offset, OP::GetParameterTypes(function, function_idx)); // varargs, LogicalType::VARCHAR - output.SetValue(7, output_offset, OP::GetVarArgs(function, function_idx)); + output.SetValue(col++, output_offset, OP::GetVarArgs(function, function_idx)); // macro_definition, LogicalType::VARCHAR - output.SetValue(8, output_offset, OP::GetMacroDefinition(function, function_idx)); + output.SetValue(col++, output_offset, OP::GetMacroDefinition(function, function_idx)); // has_side_effects, LogicalType::BOOLEAN - output.SetValue(9, output_offset, OP::HasSideEffects(function, function_idx)); + output.SetValue(col++, output_offset, OP::HasSideEffects(function, function_idx)); + + // internal, LogicalType::BOOLEAN + output.SetValue(col++, output_offset, Value::BOOLEAN(entry->internal)); // function_oid, LogicalType::BIGINT - output.SetValue(10, output_offset, Value::BIGINT(entry->oid)); + output.SetValue(col++, output_offset, Value::BIGINT(entry->oid)); return function_idx + 1 == OP::FunctionCount(function); } @@ -138447,7 +147089,7 @@ void DuckDBFunctionsFunction(ClientContext &context, TableFunctionInput &data_p, while (data.offset < data.entries.size() && count < STANDARD_VECTOR_SIZE) { auto &entry = data.entries[data.offset]; auto standard_entry = (StandardEntry *)entry; - bool finished = false; + bool finished; switch (entry->type) { case CatalogType::SCALAR_FUNCTION_ENTRY: @@ -138507,6 +147149,7 @@ void DuckDBFunctionsFun::RegisterFunction(BuiltinFunctions &set) { + namespace duckdb { struct DuckDBIndexesData : public GlobalTableFunctionState { @@ -138519,6 +147162,12 @@ struct DuckDBIndexesData : public GlobalTableFunctionState { static unique_ptr DuckDBIndexesBind(ClientContext &context, TableFunctionBindInput &input, vector &return_types, vector &names) { + names.emplace_back("database_name"); + return_types.emplace_back(LogicalType::VARCHAR); + + names.emplace_back("database_oid"); + return_types.emplace_back(LogicalType::BIGINT); + names.emplace_back("schema_name"); return_types.emplace_back(LogicalType::VARCHAR); @@ -138555,16 +147204,12 @@ static unique_ptr DuckDBIndexesBind(ClientContext &context, TableF unique_ptr DuckDBIndexesInit(ClientContext &context, TableFunctionInitInput &input) { auto result = make_unique(); - // scan all the schemas for tables and collect themand collect them - auto schemas = Catalog::GetCatalog(context).schemas->GetEntries(context); + // scan all the schemas for tables and collect them and collect them + auto schemas = Catalog::GetAllSchemas(context); for (auto &schema : schemas) { schema->Scan(context, CatalogType::INDEX_ENTRY, [&](CatalogEntry *entry) { result->entries.push_back(entry); }); }; - - // check the temp schema as well - SchemaCatalogEntry::GetTemporaryObjects(context)->Scan( - context, CatalogType::INDEX_ENTRY, [&](CatalogEntry *entry) { result->entries.push_back(entry); }); - return move(result); + return std::move(result); } void DuckDBIndexesFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { @@ -138582,29 +147227,40 @@ void DuckDBIndexesFunction(ClientContext &context, TableFunctionInput &data_p, D auto &index = (IndexCatalogEntry &)*entry; // return values: + idx_t col = 0; + // database_name, VARCHAR + output.SetValue(col++, count, index.catalog->GetName()); + // database_oid, BIGINT + output.SetValue(col++, count, Value::BIGINT(index.catalog->GetOid())); // schema_name, VARCHAR - output.SetValue(0, count, Value(index.schema->name)); + output.SetValue(col++, count, Value(index.schema->name)); // schema_oid, BIGINT - output.SetValue(1, count, Value::BIGINT(index.schema->oid)); + output.SetValue(col++, count, Value::BIGINT(index.schema->oid)); // index_name, VARCHAR - output.SetValue(2, count, Value(index.name)); + output.SetValue(col++, count, Value(index.name)); // index_oid, BIGINT - output.SetValue(3, count, Value::BIGINT(index.oid)); + output.SetValue(col++, count, Value::BIGINT(index.oid)); + // find the table in the catalog + auto table_entry = + index.schema->catalog->GetEntry(context, index.GetSchemaName(), index.GetTableName()); // table_name, VARCHAR - output.SetValue(4, count, Value(index.info->table)); + output.SetValue(col++, count, Value(table_entry->name)); // table_oid, BIGINT - // find the table in the catalog - auto &catalog = Catalog::GetCatalog(context); - auto table_entry = catalog.GetEntry(context, CatalogType::TABLE_ENTRY, index.info->schema, index.info->table); - output.SetValue(5, count, Value::BIGINT(table_entry->oid)); - // is_unique, BOOLEAN - output.SetValue(6, count, Value::BOOLEAN(index.index->IsUnique())); - // is_primary, BOOLEAN - output.SetValue(7, count, Value::BOOLEAN(index.index->IsPrimary())); + output.SetValue(col++, count, Value::BIGINT(table_entry->oid)); + if (index.index) { + // is_unique, BOOLEAN + output.SetValue(col++, count, Value::BOOLEAN(index.index->IsUnique())); + // is_primary, BOOLEAN + output.SetValue(col++, count, Value::BOOLEAN(index.index->IsPrimary())); + } else { + output.SetValue(col++, count, Value()); + output.SetValue(col++, count, Value()); + } // expressions, VARCHAR - output.SetValue(8, count, Value()); + output.SetValue(col++, count, Value()); // sql, VARCHAR - output.SetValue(9, count, Value(index.ToSQL())); + auto sql = index.ToSQL(); + output.SetValue(col++, count, sql.empty() ? Value() : Value(std::move(sql))); count++; } @@ -138646,7 +147302,7 @@ static unique_ptr DuckDBKeywordsBind(ClientContext &context, Table unique_ptr DuckDBKeywordsInit(ClientContext &context, TableFunctionInitInput &input) { auto result = make_unique(); result->entries = Parser::KeywordList(); - return move(result); + return std::move(result); } void DuckDBKeywordsFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { @@ -138681,7 +147337,7 @@ void DuckDBKeywordsFunction(ClientContext &context, TableFunctionInput &data_p, default: throw InternalException("Unrecognized keyword category"); } - output.SetValue(1, count, Value(move(category_name))); + output.SetValue(1, count, Value(std::move(category_name))); count++; } @@ -138717,6 +147373,12 @@ static unique_ptr DuckDBSchemasBind(ClientContext &context, TableF names.emplace_back("oid"); return_types.emplace_back(LogicalType::BIGINT); + names.emplace_back("database_name"); + return_types.emplace_back(LogicalType::VARCHAR); + + names.emplace_back("database_oid"); + return_types.emplace_back(LogicalType::BIGINT); + names.emplace_back("schema_name"); return_types.emplace_back(LogicalType::VARCHAR); @@ -138733,12 +147395,9 @@ unique_ptr DuckDBSchemasInit(ClientContext &context, T auto result = make_unique(); // scan all the schemas and collect them - Catalog::GetCatalog(context).ScanSchemas( - context, [&](CatalogEntry *entry) { result->entries.push_back((SchemaCatalogEntry *)entry); }); - // get the temp schema as well - result->entries.push_back(SchemaCatalogEntry::GetTemporaryObjects(context)); + result->entries = Catalog::GetAllSchemas(context); - return move(result); + return std::move(result); } void DuckDBSchemasFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { @@ -138754,14 +147413,19 @@ void DuckDBSchemasFunction(ClientContext &context, TableFunctionInput &data_p, D auto &entry = data.entries[data.offset]; // return values: + idx_t col = 0; // "oid", PhysicalType::BIGINT - output.SetValue(0, count, Value::BIGINT(entry->oid)); + output.SetValue(col++, count, Value::BIGINT(entry->oid)); + // database_name, VARCHAR + output.SetValue(col++, count, entry->catalog->GetName()); + // database_oid, BIGINT + output.SetValue(col++, count, Value::BIGINT(entry->catalog->GetOid())); // "schema_name", PhysicalType::VARCHAR - output.SetValue(1, count, Value(entry->name)); + output.SetValue(col++, count, Value(entry->name)); // "internal", PhysicalType::BOOLEAN - output.SetValue(2, count, Value::BOOLEAN(entry->internal)); + output.SetValue(col++, count, Value::BOOLEAN(entry->internal)); // "sql", PhysicalType::VARCHAR - output.SetValue(3, count, Value()); + output.SetValue(col++, count, Value()); data.offset++; count++; @@ -138789,12 +147453,18 @@ struct DuckDBSequencesData : public GlobalTableFunctionState { DuckDBSequencesData() : offset(0) { } - vector entries; + vector entries; idx_t offset; }; static unique_ptr DuckDBSequencesBind(ClientContext &context, TableFunctionBindInput &input, vector &return_types, vector &names) { + names.emplace_back("database_name"); + return_types.emplace_back(LogicalType::VARCHAR); + + names.emplace_back("database_oid"); + return_types.emplace_back(LogicalType::BIGINT); + names.emplace_back("schema_name"); return_types.emplace_back(LogicalType::VARCHAR); @@ -138838,16 +147508,12 @@ unique_ptr DuckDBSequencesInit(ClientContext &context, auto result = make_unique(); // scan all the schemas for tables and collect themand collect them - auto schemas = Catalog::GetCatalog(context).schemas->GetEntries(context); + auto schemas = Catalog::GetAllSchemas(context); for (auto &schema : schemas) { schema->Scan(context, CatalogType::SEQUENCE_ENTRY, - [&](CatalogEntry *entry) { result->entries.push_back(entry); }); + [&](CatalogEntry *entry) { result->entries.push_back((SequenceCatalogEntry *)entry); }); }; - - // check the temp schema as well - SchemaCatalogEntry::GetTemporaryObjects(context)->Scan( - context, CatalogType::SEQUENCE_ENTRY, [&](CatalogEntry *entry) { result->entries.push_back(entry); }); - return move(result); + return std::move(result); } void DuckDBSequencesFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { @@ -138864,30 +147530,35 @@ void DuckDBSequencesFunction(ClientContext &context, TableFunctionInput &data_p, auto &seq = (SequenceCatalogEntry &)*entry; // return values: + idx_t col = 0; + // database_name, VARCHAR + output.SetValue(col++, count, entry->catalog->GetName()); + // database_oid, BIGINT + output.SetValue(col++, count, Value::BIGINT(entry->catalog->GetOid())); // schema_name, VARCHAR - output.SetValue(0, count, Value(seq.schema->name)); + output.SetValue(col++, count, Value(seq.schema->name)); // schema_oid, BIGINT - output.SetValue(1, count, Value::BIGINT(seq.schema->oid)); + output.SetValue(col++, count, Value::BIGINT(seq.schema->oid)); // sequence_name, VARCHAR - output.SetValue(2, count, Value(seq.name)); + output.SetValue(col++, count, Value(seq.name)); // sequence_oid, BIGINT - output.SetValue(3, count, Value::BIGINT(seq.oid)); + output.SetValue(col++, count, Value::BIGINT(seq.oid)); // temporary, BOOLEAN - output.SetValue(4, count, Value::BOOLEAN(seq.temporary)); + output.SetValue(col++, count, Value::BOOLEAN(seq.temporary)); // start_value, BIGINT - output.SetValue(5, count, Value::BIGINT(seq.start_value)); + output.SetValue(col++, count, Value::BIGINT(seq.start_value)); // min_value, BIGINT - output.SetValue(6, count, Value::BIGINT(seq.min_value)); + output.SetValue(col++, count, Value::BIGINT(seq.min_value)); // max_value, BIGINT - output.SetValue(7, count, Value::BIGINT(seq.max_value)); + output.SetValue(col++, count, Value::BIGINT(seq.max_value)); // increment_by, BIGINT - output.SetValue(8, count, Value::BIGINT(seq.increment)); + output.SetValue(col++, count, Value::BIGINT(seq.increment)); // cycle, BOOLEAN - output.SetValue(9, count, Value::BOOLEAN(seq.cycle)); + output.SetValue(col++, count, Value::BOOLEAN(seq.cycle)); // last_value, BIGINT - output.SetValue(10, count, seq.usage_count == 0 ? Value() : Value::BOOLEAN(seq.last_value)); + output.SetValue(col++, count, seq.usage_count == 0 ? Value() : Value::BOOLEAN(seq.last_value)); // sql, LogicalType::VARCHAR - output.SetValue(11, count, Value(seq.ToSQL())); + output.SetValue(col++, count, Value(seq.ToSQL())); count++; } @@ -138953,7 +147624,7 @@ unique_ptr DuckDBSettingsInit(ClientContext &context, value.description = option->description; value.input_type = LogicalTypeIdToString(option->parameter_type); - result->settings.push_back(move(value)); + result->settings.push_back(std::move(value)); } for (auto &ext_param : config.extension_parameters) { Value setting_val; @@ -138963,13 +147634,13 @@ unique_ptr DuckDBSettingsInit(ClientContext &context, } DuckDBSettingValue value; value.name = ext_param.first; - value.value = move(setting_str_val); + value.value = std::move(setting_str_val); value.description = ext_param.second.description; value.input_type = ext_param.second.type.ToString(); - result->settings.push_back(move(value)); + result->settings.push_back(std::move(value)); } - return move(result); + return std::move(result); } void DuckDBSettingsFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { @@ -139016,6 +147687,7 @@ void DuckDBSettingsFun::RegisterFunction(BuiltinFunctions &set) { + namespace duckdb { struct DuckDBTablesData : public GlobalTableFunctionState { @@ -139028,6 +147700,12 @@ struct DuckDBTablesData : public GlobalTableFunctionState { static unique_ptr DuckDBTablesBind(ClientContext &context, TableFunctionBindInput &input, vector &return_types, vector &names) { + names.emplace_back("database_name"); + return_types.emplace_back(LogicalType::VARCHAR); + + names.emplace_back("database_oid"); + return_types.emplace_back(LogicalType::BIGINT); + names.emplace_back("schema_name"); return_types.emplace_back(LogicalType::VARCHAR); @@ -139071,19 +147749,15 @@ unique_ptr DuckDBTablesInit(ClientContext &context, Ta auto result = make_unique(); // scan all the schemas for tables and collect themand collect them - auto schemas = Catalog::GetCatalog(context).schemas->GetEntries(context); + auto schemas = Catalog::GetAllSchemas(context); for (auto &schema : schemas) { schema->Scan(context, CatalogType::TABLE_ENTRY, [&](CatalogEntry *entry) { result->entries.push_back(entry); }); }; - - // check the temp schema as well - SchemaCatalogEntry::GetTemporaryObjects(context)->Scan( - context, CatalogType::TABLE_ENTRY, [&](CatalogEntry *entry) { result->entries.push_back(entry); }); - return move(result); + return std::move(result); } static bool TableHasPrimaryKey(TableCatalogEntry &table) { - for (auto &constraint : table.constraints) { + for (auto &constraint : table.GetConstraints()) { if (constraint->type == ConstraintType::UNIQUE) { auto &unique = (UniqueConstraint &)*constraint; if (unique.is_primary_key) { @@ -139096,7 +147770,7 @@ static bool TableHasPrimaryKey(TableCatalogEntry &table) { static idx_t CheckConstraintCount(TableCatalogEntry &table) { idx_t check_count = 0; - for (auto &constraint : table.constraints) { + for (auto &constraint : table.GetConstraints()) { if (constraint->type == ConstraintType::CHECK) { check_count++; } @@ -139120,31 +147794,39 @@ void DuckDBTablesFunction(ClientContext &context, TableFunctionInput &data_p, Da continue; } auto &table = (TableCatalogEntry &)*entry; + auto storage_info = table.GetStorageInfo(context); // return values: + idx_t col = 0; + // database_name, VARCHAR + output.SetValue(col++, count, entry->catalog->GetName()); + // database_oid, BIGINT + output.SetValue(col++, count, Value::BIGINT(entry->catalog->GetOid())); // schema_name, LogicalType::VARCHAR - output.SetValue(0, count, Value(table.schema->name)); + output.SetValue(col++, count, Value(table.schema->name)); // schema_oid, LogicalType::BIGINT - output.SetValue(1, count, Value::BIGINT(table.schema->oid)); + output.SetValue(col++, count, Value::BIGINT(table.schema->oid)); // table_name, LogicalType::VARCHAR - output.SetValue(2, count, Value(table.name)); + output.SetValue(col++, count, Value(table.name)); // table_oid, LogicalType::BIGINT - output.SetValue(3, count, Value::BIGINT(table.oid)); + output.SetValue(col++, count, Value::BIGINT(table.oid)); // internal, LogicalType::BOOLEAN - output.SetValue(4, count, Value::BOOLEAN(table.internal)); + output.SetValue(col++, count, Value::BOOLEAN(table.internal)); // temporary, LogicalType::BOOLEAN - output.SetValue(5, count, Value::BOOLEAN(table.temporary)); + output.SetValue(col++, count, Value::BOOLEAN(table.temporary)); // has_primary_key, LogicalType::BOOLEAN - output.SetValue(6, count, Value::BOOLEAN(TableHasPrimaryKey(table))); + output.SetValue(col++, count, Value::BOOLEAN(TableHasPrimaryKey(table))); // estimated_size, LogicalType::BIGINT - output.SetValue(7, count, Value::BIGINT(table.storage->info->cardinality.load())); + Value card_val = + storage_info.cardinality == DConstants::INVALID_INDEX ? Value() : Value::BIGINT(storage_info.cardinality); + output.SetValue(col++, count, card_val); // column_count, LogicalType::BIGINT - output.SetValue(8, count, Value::BIGINT(table.columns.LogicalColumnCount())); + output.SetValue(col++, count, Value::BIGINT(table.GetColumns().LogicalColumnCount())); // index_count, LogicalType::BIGINT - output.SetValue(9, count, Value::BIGINT(table.storage->info->indexes.Count())); + output.SetValue(col++, count, Value::BIGINT(storage_info.index_info.size())); // check_constraint_count, LogicalType::BIGINT - output.SetValue(10, count, Value::BIGINT(CheckConstraintCount(table))); + output.SetValue(col++, count, Value::BIGINT(CheckConstraintCount(table))); // sql, LogicalType::VARCHAR - output.SetValue(11, count, Value(table.ToSQL())); + output.SetValue(col++, count, Value(table.ToSQL())); count++; } @@ -139178,6 +147860,12 @@ struct DuckDBTypesData : public GlobalTableFunctionState { static unique_ptr DuckDBTypesBind(ClientContext &context, TableFunctionBindInput &input, vector &return_types, vector &names) { + names.emplace_back("database_name"); + return_types.emplace_back(LogicalType::VARCHAR); + + names.emplace_back("database_oid"); + return_types.emplace_back(LogicalType::BIGINT); + names.emplace_back("schema_name"); return_types.emplace_back(LogicalType::VARCHAR); @@ -139203,22 +147891,20 @@ static unique_ptr DuckDBTypesBind(ClientContext &context, TableFun names.emplace_back("internal"); return_types.emplace_back(LogicalType::BOOLEAN); + names.emplace_back("labels"); + return_types.emplace_back(LogicalType::LIST(LogicalType::VARCHAR)); + return nullptr; } unique_ptr DuckDBTypesInit(ClientContext &context, TableFunctionInitInput &input) { auto result = make_unique(); - auto schemas = Catalog::GetCatalog(context).schemas->GetEntries(context); + auto schemas = Catalog::GetAllSchemas(context); for (auto &schema : schemas) { schema->Scan(context, CatalogType::TYPE_ENTRY, [&](CatalogEntry *entry) { result->entries.push_back((TypeCatalogEntry *)entry); }); }; - - // check the temp schema as well - SchemaCatalogEntry::GetTemporaryObjects(context)->Scan(context, CatalogType::TYPE_ENTRY, [&](CatalogEntry *entry) { - result->entries.push_back((TypeCatalogEntry *)entry); - }); - return move(result); + return std::move(result); } void DuckDBTypesFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { @@ -139235,10 +147921,15 @@ void DuckDBTypesFunction(ClientContext &context, TableFunctionInput &data_p, Dat auto &type = type_entry->user_type; // return values: + idx_t col = 0; + // database_name, VARCHAR + output.SetValue(col++, count, type_entry->catalog->GetName()); + // database_oid, BIGINT + output.SetValue(col++, count, Value::BIGINT(type_entry->catalog->GetOid())); // schema_name, LogicalType::VARCHAR - output.SetValue(0, count, Value(type_entry->schema->name)); + output.SetValue(col++, count, Value(type_entry->schema->name)); // schema_oid, LogicalType::BIGINT - output.SetValue(1, count, Value::BIGINT(type_entry->schema->oid)); + output.SetValue(col++, count, Value::BIGINT(type_entry->schema->oid)); // type_oid, BIGINT int64_t oid; if (type_entry->internal) { @@ -139253,15 +147944,15 @@ void DuckDBTypesFunction(ClientContext &context, TableFunctionInput &data_p, Dat } else { oid_val = Value(); } - output.SetValue(2, count, oid_val); + output.SetValue(col++, count, oid_val); // type_name, VARCHAR - output.SetValue(3, count, Value(type_entry->name)); + output.SetValue(col++, count, Value(type_entry->name)); // type_size, BIGINT auto internal_type = type.InternalType(); - output.SetValue(4, count, + output.SetValue(col++, count, internal_type == PhysicalType::INVALID ? Value() : Value::BIGINT(GetTypeIdSize(internal_type))); // logical_type, VARCHAR - output.SetValue(5, count, Value(LogicalTypeIdToString(type.id()))); + output.SetValue(col++, count, Value(LogicalTypeIdToString(type.id()))); // type_category, VARCHAR string category; switch (type.id()) { @@ -139306,9 +147997,23 @@ void DuckDBTypesFunction(ClientContext &context, TableFunctionInput &data_p, Dat default: break; } - output.SetValue(6, count, category.empty() ? Value() : Value(category)); + output.SetValue(col++, count, category.empty() ? Value() : Value(category)); // internal, BOOLEAN - output.SetValue(7, count, Value::BOOLEAN(type_entry->internal)); + output.SetValue(col++, count, Value::BOOLEAN(type_entry->internal)); + // labels, VARCHAR[] + if (type.id() == LogicalTypeId::ENUM && type.AuxInfo()) { + auto data = FlatVector::GetData(EnumType::GetValuesInsertOrder(type)); + idx_t size = EnumType::GetSize(type); + + vector labels; + for (idx_t i = 0; i < size; i++) { + labels.emplace_back(data[i]); + } + + output.SetValue(col++, count, Value::LIST(labels)); + } else { + output.SetValue(col++, count, Value()); + } count++; } @@ -139341,6 +148046,12 @@ struct DuckDBViewsData : public GlobalTableFunctionState { static unique_ptr DuckDBViewsBind(ClientContext &context, TableFunctionBindInput &input, vector &return_types, vector &names) { + names.emplace_back("database_name"); + return_types.emplace_back(LogicalType::VARCHAR); + + names.emplace_back("database_oid"); + return_types.emplace_back(LogicalType::BIGINT); + names.emplace_back("schema_name"); return_types.emplace_back(LogicalType::VARCHAR); @@ -139371,16 +148082,12 @@ static unique_ptr DuckDBViewsBind(ClientContext &context, TableFun unique_ptr DuckDBViewsInit(ClientContext &context, TableFunctionInitInput &input) { auto result = make_unique(); - // scan all the schemas for tables and collect themand collect them - auto schemas = Catalog::GetCatalog(context).schemas->GetEntries(context); + // scan all the schemas for tables and collect them and collect them + auto schemas = Catalog::GetAllSchemas(context); for (auto &schema : schemas) { schema->Scan(context, CatalogType::VIEW_ENTRY, [&](CatalogEntry *entry) { result->entries.push_back(entry); }); }; - - // check the temp schema as well - SchemaCatalogEntry::GetTemporaryObjects(context)->Scan( - context, CatalogType::VIEW_ENTRY, [&](CatalogEntry *entry) { result->entries.push_back(entry); }); - return move(result); + return std::move(result); } void DuckDBViewsFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { @@ -139401,22 +148108,27 @@ void DuckDBViewsFunction(ClientContext &context, TableFunctionInput &data_p, Dat auto &view = (ViewCatalogEntry &)*entry; // return values: + idx_t col = 0; + // database_name, VARCHAR + output.SetValue(col++, count, entry->catalog->GetName()); + // database_oid, BIGINT + output.SetValue(col++, count, Value::BIGINT(entry->catalog->GetOid())); // schema_name, LogicalType::VARCHAR - output.SetValue(0, count, Value(view.schema->name)); + output.SetValue(col++, count, Value(view.schema->name)); // schema_oid, LogicalType::BIGINT - output.SetValue(1, count, Value::BIGINT(view.schema->oid)); + output.SetValue(col++, count, Value::BIGINT(view.schema->oid)); // view_name, LogicalType::VARCHAR - output.SetValue(2, count, Value(view.name)); + output.SetValue(col++, count, Value(view.name)); // view_oid, LogicalType::BIGINT - output.SetValue(3, count, Value::BIGINT(view.oid)); + output.SetValue(col++, count, Value::BIGINT(view.oid)); // internal, LogicalType::BOOLEAN - output.SetValue(4, count, Value::BOOLEAN(view.internal)); + output.SetValue(col++, count, Value::BOOLEAN(view.internal)); // temporary, LogicalType::BOOLEAN - output.SetValue(5, count, Value::BOOLEAN(view.temporary)); + output.SetValue(col++, count, Value::BOOLEAN(view.temporary)); // column_count, LogicalType::BIGINT - output.SetValue(6, count, Value::BIGINT(view.types.size())); + output.SetValue(col++, count, Value::BIGINT(view.types.size())); // sql, LogicalType::VARCHAR - output.SetValue(7, count, Value(view.ToSQL())); + output.SetValue(col++, count, Value(view.ToSQL())); count++; } @@ -139456,13 +148168,12 @@ static unique_ptr PragmaCollateBind(ClientContext &context, TableF unique_ptr PragmaCollateInit(ClientContext &context, TableFunctionInitInput &input) { auto result = make_unique(); - Catalog::GetCatalog(context).schemas->Scan(context, [&](CatalogEntry *entry) { - auto schema = (SchemaCatalogEntry *)entry; + auto schemas = Catalog::GetAllSchemas(context); + for (auto schema : schemas) { schema->Scan(context, CatalogType::COLLATION_ENTRY, [&](CatalogEntry *entry) { result->entries.push_back(entry->name); }); - }); - - return move(result); + } + return std::move(result); } static void PragmaCollateFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { @@ -139491,55 +148202,6 @@ void PragmaCollations::RegisterFunction(BuiltinFunctions &set) { -namespace duckdb { - -struct PragmaDatabaseListData : public GlobalTableFunctionState { - PragmaDatabaseListData() : finished(false) { - } - - bool finished; -}; - -static unique_ptr PragmaDatabaseListBind(ClientContext &context, TableFunctionBindInput &input, - vector &return_types, vector &names) { - names.emplace_back("seq"); - return_types.emplace_back(LogicalType::INTEGER); - - names.emplace_back("name"); - return_types.emplace_back(LogicalType::VARCHAR); - - names.emplace_back("file"); - return_types.emplace_back(LogicalType::VARCHAR); - - return nullptr; -} - -unique_ptr PragmaDatabaseListInit(ClientContext &context, TableFunctionInitInput &input) { - return make_unique(); -} - -void PragmaDatabaseListFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { - auto &data = (PragmaDatabaseListData &)*data_p.global_state; - if (data.finished) { - return; - } - - output.SetCardinality(1); - output.data[0].SetValue(0, Value::INTEGER(0)); - output.data[1].SetValue(0, Value("main")); - output.data[2].SetValue(0, Value(StorageManager::GetStorageManager(context).GetDBPath())); - - data.finished = true; -} - -void PragmaDatabaseList::RegisterFunction(BuiltinFunctions &set) { - set.AddFunction(TableFunction("pragma_database_list", {}, PragmaDatabaseListFunction, PragmaDatabaseListBind, - PragmaDatabaseListInit)); -} - -} // namespace duckdb - - @@ -139549,14 +148211,20 @@ void PragmaDatabaseList::RegisterFunction(BuiltinFunctions &set) { namespace duckdb { struct PragmaDatabaseSizeData : public GlobalTableFunctionState { - PragmaDatabaseSizeData() : finished(false) { + PragmaDatabaseSizeData() : index(0) { } - bool finished; + idx_t index; + vector databases; + Value memory_usage; + Value memory_limit; }; static unique_ptr PragmaDatabaseSizeBind(ClientContext &context, TableFunctionBindInput &input, vector &return_types, vector &names) { + names.emplace_back("database_name"); + return_types.emplace_back(LogicalType::VARCHAR); + names.emplace_back("database_size"); return_types.emplace_back(LogicalType::VARCHAR); @@ -139585,33 +148253,40 @@ static unique_ptr PragmaDatabaseSizeBind(ClientContext &context, T } unique_ptr PragmaDatabaseSizeInit(ClientContext &context, TableFunctionInitInput &input) { - return make_unique(); + auto result = make_unique(); + result->databases = DatabaseManager::Get(context).GetDatabases(context); + auto &buffer_manager = BufferManager::GetBufferManager(context); + result->memory_usage = Value(StringUtil::BytesToHumanReadableString(buffer_manager.GetUsedMemory())); + auto max_memory = buffer_manager.GetMaxMemory(); + result->memory_limit = + max_memory == (idx_t)-1 ? Value("Unlimited") : Value(StringUtil::BytesToHumanReadableString(max_memory)); + + return std::move(result); } void PragmaDatabaseSizeFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { auto &data = (PragmaDatabaseSizeData &)*data_p.global_state; - if (data.finished) { - return; + idx_t row = 0; + for (; data.index < data.databases.size() && row < STANDARD_VECTOR_SIZE; data.index++) { + auto db = data.databases[data.index]; + if (db->IsSystem() || db->IsTemporary()) { + continue; + } + auto ds = db->GetCatalog().GetDatabaseSize(context); + idx_t col = 0; + output.data[col++].SetValue(row, Value(db->GetName())); + output.data[col++].SetValue(row, Value(StringUtil::BytesToHumanReadableString(ds.bytes))); + output.data[col++].SetValue(row, Value::BIGINT(ds.block_size)); + output.data[col++].SetValue(row, Value::BIGINT(ds.total_blocks)); + output.data[col++].SetValue(row, Value::BIGINT(ds.used_blocks)); + output.data[col++].SetValue(row, Value::BIGINT(ds.free_blocks)); + output.data[col++].SetValue( + row, ds.wal_size == idx_t(-1) ? Value() : Value(StringUtil::BytesToHumanReadableString(ds.wal_size))); + output.data[col++].SetValue(row, data.memory_usage); + output.data[col++].SetValue(row, data.memory_limit); + row++; } - auto &storage = StorageManager::GetStorageManager(context); - auto &buffer_manager = BufferManager::GetBufferManager(context); - - auto ds = storage.GetDatabaseSize(); - - output.SetCardinality(1); - output.data[0].SetValue(0, Value(StringUtil::BytesToHumanReadableString(ds.bytes))); - output.data[1].SetValue(0, Value::BIGINT(ds.block_size)); - output.data[2].SetValue(0, Value::BIGINT(ds.total_blocks)); - output.data[3].SetValue(0, Value::BIGINT(ds.used_blocks)); - output.data[4].SetValue(0, Value::BIGINT(ds.free_blocks)); - output.data[5].SetValue(0, Value(StringUtil::BytesToHumanReadableString(ds.wal_size))); - - output.data[6].SetValue(0, Value(StringUtil::BytesToHumanReadableString(buffer_manager.GetUsedMemory()))); - auto max_memory = buffer_manager.GetMaxMemory(); - output.data[7].SetValue(0, max_memory == (idx_t)-1 ? Value("Unlimited") - : Value(StringUtil::BytesToHumanReadableString(max_memory))); - - data.finished = true; + output.SetCardinality(row); } void PragmaDatabaseSize::RegisterFunction(BuiltinFunctions &set) { @@ -139629,125 +148304,6 @@ void PragmaDatabaseSize::RegisterFunction(BuiltinFunctions &set) { -namespace duckdb { - -struct PragmaFunctionsData : public GlobalTableFunctionState { - PragmaFunctionsData() : offset(0), offset_in_entry(0) { - } - - vector entries; - idx_t offset; - idx_t offset_in_entry; -}; - -static unique_ptr PragmaFunctionsBind(ClientContext &context, TableFunctionBindInput &input, - vector &return_types, vector &names) { - names.emplace_back("name"); - return_types.emplace_back(LogicalType::VARCHAR); - - names.emplace_back("type"); - return_types.emplace_back(LogicalType::VARCHAR); - - names.emplace_back("parameters"); - return_types.push_back(LogicalType::LIST(LogicalType::VARCHAR)); - - names.emplace_back("varargs"); - return_types.emplace_back(LogicalType::VARCHAR); - - names.emplace_back("return_type"); - return_types.emplace_back(LogicalType::VARCHAR); - - names.emplace_back("side_effects"); - return_types.emplace_back(LogicalType::BOOLEAN); - - return nullptr; -} - -unique_ptr PragmaFunctionsInit(ClientContext &context, TableFunctionInitInput &input) { - auto result = make_unique(); - - Catalog::GetCatalog(context).schemas->Scan(context, [&](CatalogEntry *entry) { - auto schema = (SchemaCatalogEntry *)entry; - schema->Scan(context, CatalogType::SCALAR_FUNCTION_ENTRY, - [&](CatalogEntry *entry) { result->entries.push_back(entry); }); - }); - - return move(result); -} - -void AddFunction(BaseScalarFunction &f, idx_t &count, DataChunk &output, bool is_aggregate) { - output.SetValue(0, count, Value(f.name)); - output.SetValue(1, count, Value(is_aggregate ? "AGGREGATE" : "SCALAR")); - auto result_data = FlatVector::GetData(output.data[2]); - result_data[count].offset = ListVector::GetListSize(output.data[2]); - result_data[count].length = f.arguments.size(); - string parameters; - for (idx_t i = 0; i < f.arguments.size(); i++) { - auto val = Value(f.arguments[i].ToString()); - ListVector::PushBack(output.data[2], val); - } - - output.SetValue(3, count, f.varargs.id() != LogicalTypeId::INVALID ? Value(f.varargs.ToString()) : Value()); - output.SetValue(4, count, f.return_type.ToString()); - output.SetValue(5, count, Value::BOOLEAN(f.side_effects == FunctionSideEffects::HAS_SIDE_EFFECTS)); - - count++; -} - -static void PragmaFunctionsFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { - auto &data = (PragmaFunctionsData &)*data_p.global_state; - if (data.offset >= data.entries.size()) { - // finished returning values - return; - } - idx_t count = 0; - while (count < STANDARD_VECTOR_SIZE && data.offset < data.entries.size()) { - auto &entry = data.entries[data.offset]; - switch (entry->type) { - case CatalogType::SCALAR_FUNCTION_ENTRY: { - auto &func = (ScalarFunctionCatalogEntry &)*entry; - if (data.offset_in_entry >= func.functions.Size()) { - data.offset++; - data.offset_in_entry = 0; - break; - } - auto entry = func.functions.GetFunctionByOffset(data.offset_in_entry++); - AddFunction(entry, count, output, false); - break; - } - case CatalogType::AGGREGATE_FUNCTION_ENTRY: { - auto &aggr = (AggregateFunctionCatalogEntry &)*entry; - if (data.offset_in_entry >= aggr.functions.Size()) { - data.offset++; - data.offset_in_entry = 0; - break; - } - auto entry = aggr.functions.GetFunctionByOffset(data.offset_in_entry++); - AddFunction(entry, count, output, true); - break; - } - default: - data.offset++; - break; - } - } - output.SetCardinality(count); -} - -void PragmaFunctionPragma::RegisterFunction(BuiltinFunctions &set) { - set.AddFunction( - TableFunction("pragma_functions", {}, PragmaFunctionsFunction, PragmaFunctionsBind, PragmaFunctionsInit)); -} - -} // namespace duckdb - - - - - - - - @@ -139762,7 +148318,7 @@ struct PragmaStorageFunctionData : public TableFunctionData { } TableCatalogEntry *table_entry; - vector> storage_info; + TableStorageInfo storage_info; }; struct PragmaStorageOperatorData : public GlobalTableFunctionState { @@ -139819,16 +148375,10 @@ static unique_ptr PragmaStorageInfoBind(ClientContext &context, Ta auto qname = QualifiedName::Parse(input.inputs[0].GetValue()); // look up the table name in the catalog - auto &catalog = Catalog::GetCatalog(context); - auto entry = catalog.GetEntry(context, CatalogType::TABLE_ENTRY, qname.schema, qname.name); - if (entry->type != CatalogType::TABLE_ENTRY) { - throw Exception("storage_info requires a table as parameter"); - } - auto table_entry = (TableCatalogEntry *)entry; - + auto table_entry = Catalog::GetEntry(context, qname.catalog, qname.schema, qname.name); auto result = make_unique(table_entry); - result->storage_info = table_entry->storage->GetStorageInfo(); - return move(result); + result->storage_info = table_entry->GetStorageInfo(context); + return std::move(result); } unique_ptr PragmaStorageInfoInit(ClientContext &context, TableFunctionInitInput &input) { @@ -139839,23 +148389,45 @@ static void PragmaStorageInfoFunction(ClientContext &context, TableFunctionInput auto &bind_data = (PragmaStorageFunctionData &)*data_p.bind_data; auto &data = (PragmaStorageOperatorData &)*data_p.global_state; idx_t count = 0; - auto &columns = bind_data.table_entry->columns; - while (data.offset < bind_data.storage_info.size() && count < STANDARD_VECTOR_SIZE) { - auto &entry = bind_data.storage_info[data.offset++]; - D_ASSERT(entry.size() + 1 == output.ColumnCount()); - idx_t result_idx = 0; - for (idx_t col_idx = 0; col_idx < entry.size(); col_idx++, result_idx++) { - if (col_idx == 1) { - // write the column name - auto storage_column_index = entry[col_idx].GetValue(); - auto &col = columns.GetColumn(PhysicalIndex(storage_column_index)); + auto &columns = bind_data.table_entry->GetColumns(); + while (data.offset < bind_data.storage_info.column_segments.size() && count < STANDARD_VECTOR_SIZE) { + auto &entry = bind_data.storage_info.column_segments[data.offset++]; - output.SetValue(result_idx, count, Value(col.Name())); - result_idx++; - } - output.SetValue(result_idx, count, entry[col_idx]); + idx_t col_idx = 0; + // row_group_id + output.SetValue(col_idx++, count, Value::BIGINT(entry.row_group_index)); + // column_name + auto &col = columns.GetColumn(PhysicalIndex(entry.column_id)); + output.SetValue(col_idx++, count, Value(col.Name())); + // column_id + output.SetValue(col_idx++, count, Value::BIGINT(entry.column_id)); + // column_path + output.SetValue(col_idx++, count, Value(entry.column_path)); + // segment_id + output.SetValue(col_idx++, count, Value::BIGINT(entry.segment_idx)); + // segment_type + output.SetValue(col_idx++, count, Value(entry.segment_type)); + // start + output.SetValue(col_idx++, count, Value::BIGINT(entry.segment_start)); + // count + output.SetValue(col_idx++, count, Value::BIGINT(entry.segment_count)); + // compression + output.SetValue(col_idx++, count, Value(entry.compression_type)); + // stats + output.SetValue(col_idx++, count, Value(entry.segment_stats)); + // has_updates + output.SetValue(col_idx++, count, Value::BOOLEAN(entry.has_updates)); + // persistent + output.SetValue(col_idx++, count, Value::BOOLEAN(entry.persistent)); + // block_id + // block_offset + if (entry.persistent) { + output.SetValue(col_idx++, count, Value::BIGINT(entry.block_id)); + output.SetValue(col_idx++, count, Value::BIGINT(entry.block_offset)); + } else { + output.SetValue(col_idx++, count, Value()); + output.SetValue(col_idx++, count, Value()); } - count++; } output.SetCardinality(count); @@ -139880,6 +148452,7 @@ void PragmaStorageInfo::RegisterFunction(BuiltinFunctions &set) { + #include namespace duckdb { @@ -139921,8 +148494,8 @@ static unique_ptr PragmaTableInfoBind(ClientContext &context, Tabl auto qname = QualifiedName::Parse(input.inputs[0].GetValue()); // look up the table name in the catalog - auto &catalog = Catalog::GetCatalog(context); - auto entry = catalog.GetEntry(context, CatalogType::TABLE_ENTRY, qname.schema, qname.name); + Binder::BindSchemaOrCatalog(context, qname.catalog, qname.schema); + auto entry = Catalog::GetEntry(context, CatalogType::TABLE_ENTRY, qname.catalog, qname.schema, qname.name); return make_unique(entry); } @@ -139936,19 +148509,25 @@ static void CheckConstraints(TableCatalogEntry *table, const ColumnDefinition &c out_pk = false; // check all constraints // FIXME: this is pretty inefficient, it probably doesn't matter - for (auto &constraint : table->bound_constraints) { + for (auto &constraint : table->GetConstraints()) { switch (constraint->type) { case ConstraintType::NOT_NULL: { - auto ¬_null = (BoundNotNullConstraint &)*constraint; - if (not_null.index == column.Physical()) { + auto ¬_null = (NotNullConstraint &)*constraint; + if (not_null.index == column.Logical()) { out_not_null = true; } break; } case ConstraintType::UNIQUE: { - auto &unique = (BoundUniqueConstraint &)*constraint; - if (unique.is_primary_key && unique.key_set.find(column.Logical()) != unique.key_set.end()) { - out_pk = true; + auto &unique = (UniqueConstraint &)*constraint; + + if (unique.is_primary_key) { + if (unique.index == column.Logical()) { + out_pk = true; + } + if (std::find(unique.columns.begin(), unique.columns.end(), column.GetName()) != unique.columns.end()) { + out_pk = true; + } } break; } @@ -139959,19 +148538,19 @@ static void CheckConstraints(TableCatalogEntry *table, const ColumnDefinition &c } static void PragmaTableInfoTable(PragmaTableOperatorData &data, TableCatalogEntry *table, DataChunk &output) { - if (data.offset >= table->columns.LogicalColumnCount()) { + if (data.offset >= table->GetColumns().LogicalColumnCount()) { // finished returning values return; } // start returning values // either fill up the chunk or return all the remaining columns - idx_t next = MinValue(data.offset + STANDARD_VECTOR_SIZE, table->columns.LogicalColumnCount()); + idx_t next = MinValue(data.offset + STANDARD_VECTOR_SIZE, table->GetColumns().LogicalColumnCount()); output.SetCardinality(next - data.offset); for (idx_t i = data.offset; i < next; i++) { bool not_null, pk; auto index = i - data.offset; - auto &column = table->columns.GetColumn(LogicalIndex(i)); + auto &column = table->GetColumn(LogicalIndex(i)); D_ASSERT(column.Oid() < (idx_t)NumericLimits::Maximum()); CheckConstraints(table, column, not_null, pk); @@ -140050,6 +148629,8 @@ void PragmaTableInfo::RegisterFunction(BuiltinFunctions &set) { + + #include #include @@ -140104,12 +148685,12 @@ vector TestAllTypesFun::GetTestTypes() { max_interval.micros = 999999999; result.emplace_back(LogicalType::INTERVAL, "interval", Value::INTERVAL(min_interval), Value::INTERVAL(max_interval)); - // strings/blobs + // strings/blobs/bitstrings result.emplace_back(LogicalType::VARCHAR, "varchar", Value("🦆🦆🦆🦆🦆🦆"), Value(string("goo\x00se", 6))); - result.emplace_back(LogicalType::JSON, "json", Value("🦆🦆🦆🦆🦆🦆"), Value("goose")); result.emplace_back(LogicalType::BLOB, "blob", Value::BLOB("thisisalongblob\\x00withnullbytes"), Value::BLOB("\\x00\\x00\\x00a")); + result.emplace_back(LogicalType::BIT, "bit", Value::BIT("0010001001011100010101011010111"), Value::BIT("10101")); // enums Vector small_enum(LogicalType::VARCHAR, 2); @@ -140184,17 +148765,17 @@ vector TestAllTypesFun::GetTestTypes() { child_list_t struct_type_list; struct_type_list.push_back(make_pair("a", LogicalType::INTEGER)); struct_type_list.push_back(make_pair("b", LogicalType::VARCHAR)); - auto struct_type = LogicalType::STRUCT(move(struct_type_list)); + auto struct_type = LogicalType::STRUCT(std::move(struct_type_list)); child_list_t min_struct_list; min_struct_list.push_back(make_pair("a", Value(LogicalType::INTEGER))); min_struct_list.push_back(make_pair("b", Value(LogicalType::VARCHAR))); - auto min_struct_val = Value::STRUCT(move(min_struct_list)); + auto min_struct_val = Value::STRUCT(std::move(min_struct_list)); child_list_t max_struct_list; max_struct_list.push_back(make_pair("a", Value::INTEGER(42))); max_struct_list.push_back(make_pair("b", Value("🦆🦆🦆🦆🦆🦆"))); - auto max_struct_val = Value::STRUCT(move(max_struct_list)); + auto max_struct_val = Value::STRUCT(std::move(max_struct_list)); result.emplace_back(struct_type, "struct", min_struct_val, max_struct_val); @@ -140202,33 +148783,45 @@ vector TestAllTypesFun::GetTestTypes() { child_list_t struct_list_type_list; struct_list_type_list.push_back(make_pair("a", int_list_type)); struct_list_type_list.push_back(make_pair("b", varchar_list_type)); - auto struct_list_type = LogicalType::STRUCT(move(struct_list_type_list)); + auto struct_list_type = LogicalType::STRUCT(std::move(struct_list_type_list)); child_list_t min_struct_vl_list; min_struct_vl_list.push_back(make_pair("a", Value(int_list_type))); min_struct_vl_list.push_back(make_pair("b", Value(varchar_list_type))); - auto min_struct_val_list = Value::STRUCT(move(min_struct_vl_list)); + auto min_struct_val_list = Value::STRUCT(std::move(min_struct_vl_list)); child_list_t max_struct_vl_list; max_struct_vl_list.push_back(make_pair("a", int_list)); max_struct_vl_list.push_back(make_pair("b", varchar_list)); - auto max_struct_val_list = Value::STRUCT(move(max_struct_vl_list)); + auto max_struct_val_list = Value::STRUCT(std::move(max_struct_vl_list)); - result.emplace_back(struct_list_type, "struct_of_arrays", move(min_struct_val_list), move(max_struct_val_list)); + result.emplace_back(struct_list_type, "struct_of_arrays", std::move(min_struct_val_list), + std::move(max_struct_val_list)); // array of structs auto array_of_structs_type = LogicalType::LIST(struct_type); auto min_array_of_struct_val = Value::EMPTYLIST(struct_type); auto max_array_of_struct_val = Value::LIST({min_struct_val, max_struct_val, Value(struct_type)}); - result.emplace_back(array_of_structs_type, "array_of_structs", move(min_array_of_struct_val), - move(max_array_of_struct_val)); + result.emplace_back(array_of_structs_type, "array_of_structs", std::move(min_array_of_struct_val), + std::move(max_array_of_struct_val)); // map auto map_type = LogicalType::MAP(LogicalType::VARCHAR, LogicalType::VARCHAR); - auto min_map_value = Value::MAP(Value::EMPTYLIST(LogicalType::VARCHAR), Value::EMPTYLIST(LogicalType::VARCHAR)); - auto max_map_value = Value::MAP(Value::LIST({Value("key1"), Value("key2")}), - Value::LIST({Value("🦆🦆🦆🦆🦆🦆"), Value("goose")})); - result.emplace_back(map_type, "map", move(min_map_value), move(max_map_value)); + auto min_map_value = Value::MAP(ListType::GetChildType(map_type), std::vector()); + + child_list_t map_struct1; + map_struct1.push_back(make_pair("key", Value("key1"))); + map_struct1.push_back(make_pair("value", Value("🦆🦆🦆🦆🦆🦆"))); + child_list_t map_struct2; + map_struct2.push_back(make_pair("key", Value("key2"))); + map_struct2.push_back(make_pair("key", Value("goose"))); + + std::vector map_values; + map_values.push_back(Value::STRUCT(map_struct1)); + map_values.push_back(Value::STRUCT(map_struct2)); + + auto max_map_value = Value::MAP(ListType::GetChildType(map_type), map_values); + result.emplace_back(map_type, "map", std::move(min_map_value), std::move(max_map_value)); return result; } @@ -140237,8 +148830,8 @@ static unique_ptr TestAllTypesBind(ClientContext &context, TableFu vector &return_types, vector &names) { auto test_types = TestAllTypesFun::GetTestTypes(); for (auto &test_type : test_types) { - return_types.push_back(move(test_type.type)); - names.push_back(move(test_type.name)); + return_types.push_back(std::move(test_type.type)); + names.push_back(std::move(test_type.name)); } return nullptr; } @@ -140250,11 +148843,11 @@ unique_ptr TestAllTypesInit(ClientContext &context, Ta result->entries.resize(3); // initialize the values for (auto &test_type : test_types) { - result->entries[0].push_back(move(test_type.min_value)); - result->entries[1].push_back(move(test_type.max_value)); - result->entries[2].emplace_back(move(test_type.type)); + result->entries[0].push_back(std::move(test_type.min_value)); + result->entries[1].push_back(std::move(test_type.max_value)); + result->entries[2].emplace_back(std::move(test_type.type)); } - return move(result); + return std::move(result); } void TestAllTypesFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { @@ -140327,11 +148920,11 @@ struct TestVectorFlat { auto child_values = GenerateValues(info, child_type.second); for (idx_t i = 0; i < child_values.size(); i++) { - struct_children[i].push_back(make_pair(child_type.first, move(child_values[i]))); + struct_children[i].push_back(make_pair(child_type.first, std::move(child_values[i]))); } } for (auto &struct_child : struct_children) { - result.push_back(Value::STRUCT(move(struct_child))); + result.push_back(Value::STRUCT(std::move(struct_child))); } break; } @@ -140368,7 +148961,7 @@ struct TestVectorFlat { result->data[0].SetValue(i, result_values[cur_row + i]); } result->SetCardinality(cardinality); - info.entries.push_back(move(result)); + info.entries.push_back(std::move(result)); } } }; @@ -140384,7 +148977,7 @@ struct TestVectorConstant { result->data[0].SetVectorType(VectorType::CONSTANT_VECTOR); result->SetCardinality(cardinality); - info.entries.push_back(move(result)); + info.entries.push_back(std::move(result)); } } }; @@ -140447,7 +149040,7 @@ struct TestVectorSequence { GenerateVector(info, info.type, result->data[0]); result->SetCardinality(3); - info.entries.push_back(move(result)); + info.entries.push_back(std::move(result)); #endif } }; @@ -140483,7 +149076,7 @@ static unique_ptr TestVectorTypesBind(ClientContext &context, Tabl return_types.push_back(result->type); names.emplace_back("test_vector"); - return move(result); + return std::move(result); } unique_ptr TestVectorTypesInit(ClientContext &context, TableFunctionInitInput &input) { @@ -140495,7 +149088,7 @@ unique_ptr TestVectorTypesInit(ClientContext &context, map test_type_map; for (auto &test_type : test_types) { - test_type_map.insert(make_pair(test_type.type.id(), move(test_type))); + test_type_map.insert(make_pair(test_type.type.id(), std::move(test_type))); } TestVectorInfo info(bind_data.type, test_type_map, result->entries); @@ -140512,7 +149105,7 @@ unique_ptr TestVectorTypesInit(ClientContext &context, entry->Verify(); } } - return move(result); + return std::move(result); } void TestVectorTypesFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { @@ -140651,7 +149244,7 @@ class StarExpression : public ParsedExpression { public: string ToString() const override; - static bool Equals(const StarExpression *a, const StarExpression *b); + static bool Equal(const StarExpression *a, const StarExpression *b); unique_ptr Copy() const override; @@ -140668,17 +149261,16 @@ namespace duckdb { void BuiltinFunctions::RegisterSQLiteFunctions() { PragmaVersion::RegisterFunction(*this); - PragmaFunctionPragma::RegisterFunction(*this); PragmaCollations::RegisterFunction(*this); PragmaTableInfo::RegisterFunction(*this); PragmaStorageInfo::RegisterFunction(*this); PragmaDatabaseSize::RegisterFunction(*this); - PragmaDatabaseList::RegisterFunction(*this); PragmaLastProfilingOutput::RegisterFunction(*this); PragmaDetailedProfilingOutput::RegisterFunction(*this); DuckDBColumnsFun::RegisterFunction(*this); DuckDBConstraintsFun::RegisterFunction(*this); + DuckDBDatabasesFun::RegisterFunction(*this); DuckDBFunctionsFun::RegisterFunction(*this); DuckDBKeywordsFun::RegisterFunction(*this); DuckDBIndexesFun::RegisterFunction(*this); @@ -140710,6 +149302,9 @@ void BuiltinFunctions::RegisterSQLiteFunctions() { + + + namespace duckdb { //===--------------------------------------------------------------------===// @@ -140729,7 +149324,7 @@ static storage_t GetStorageIndex(TableCatalogEntry &table, column_t column_id) { if (column_id == DConstants::INVALID_INDEX) { return column_id; } - auto &col = table.columns.GetColumn(LogicalIndex(column_id)); + auto &col = table.GetColumn(LogicalIndex(column_id)); return col.StorageOid(); } @@ -140737,7 +149332,7 @@ struct TableScanGlobalState : public GlobalTableFunctionState { TableScanGlobalState(ClientContext &context, const FunctionData *bind_data_p) : row_count(0) { D_ASSERT(bind_data_p); auto &bind_data = (const TableScanBindData &)*bind_data_p; - max_threads = bind_data.table->storage->MaxThreads(context); + max_threads = bind_data.table->GetStorage().MaxThreads(context); } ParallelTableScanState state; @@ -140767,13 +149362,13 @@ static unique_ptr TableScanInitLocal(ExecutionContext & auto storage_idx = GetStorageIndex(*bind_data.table, col); col = storage_idx; } - result->scan_state.Initialize(move(column_ids), input.filters); + result->scan_state.Initialize(std::move(column_ids), input.filters); TableScanParallelStateNext(context.client, input.bind_data, result.get(), gstate); if (input.CanRemoveFilterColumns()) { auto &tsgs = (TableScanGlobalState &)*gstate; result->all_columns.Initialize(context.client, tsgs.scanned_types); } - return move(result); + return std::move(result); } unique_ptr TableScanInitGlobal(ClientContext &context, TableFunctionInitInput &input) { @@ -140781,10 +149376,10 @@ unique_ptr TableScanInitGlobal(ClientContext &context, D_ASSERT(input.bind_data); auto &bind_data = (const TableScanBindData &)*input.bind_data; auto result = make_unique(context, input.bind_data); - bind_data.table->storage->InitializeParallelScan(context, result->state); + bind_data.table->GetStorage().InitializeParallelScan(context, result->state); if (input.CanRemoveFilterColumns()) { result->projection_ids = input.projection_ids; - const auto &columns = bind_data.table->columns; + const auto &columns = bind_data.table->GetColumns(); for (const auto &col_idx : input.column_ids) { if (col_idx == COLUMN_IDENTIFIER_ROW_ID) { result->scanned_types.emplace_back(LogicalType::ROW_TYPE); @@ -140793,14 +149388,14 @@ unique_ptr TableScanInitGlobal(ClientContext &context, } } } - return move(result); + return std::move(result); } static unique_ptr TableScanStatistics(ClientContext &context, const FunctionData *bind_data_p, column_t column_id) { auto &bind_data = (const TableScanBindData &)*bind_data_p; - auto &local_storage = LocalStorage::Get(context); - if (local_storage.Find(bind_data.table->storage.get())) { + auto &local_storage = LocalStorage::Get(context, *bind_data.table->catalog); + if (local_storage.Find(bind_data.table->GetStoragePtr())) { // we don't emit any statistics for tables that have outstanding transaction-local data return nullptr; } @@ -140811,17 +149406,18 @@ static void TableScanFunc(ClientContext &context, TableFunctionInput &data_p, Da auto &bind_data = (TableScanBindData &)*data_p.bind_data; auto &gstate = (TableScanGlobalState &)*data_p.global_state; auto &state = (TableScanLocalState &)*data_p.local_state; - auto &transaction = Transaction::GetTransaction(context); + auto &transaction = DuckTransaction::Get(context, *bind_data.table->catalog); + auto &storage = bind_data.table->GetStorage(); do { if (bind_data.is_create_index) { - bind_data.table->storage->CreateIndexScan( - state.scan_state, output, TableScanType::TABLE_SCAN_COMMITTED_ROWS_OMIT_PERMANENTLY_DELETED); + storage.CreateIndexScan(state.scan_state, output, + TableScanType::TABLE_SCAN_COMMITTED_ROWS_OMIT_PERMANENTLY_DELETED); } else if (gstate.CanRemoveFilterColumns()) { state.all_columns.Reset(); - bind_data.table->storage->Scan(transaction, state.all_columns, state.scan_state); + storage.Scan(transaction, state.all_columns, state.scan_state); output.ReferenceColumns(state.all_columns, gstate.projection_ids); } else { - bind_data.table->storage->Scan(transaction, output, state.scan_state); + storage.Scan(transaction, output, state.scan_state); } if (output.size() > 0) { gstate.row_count += output.size(); @@ -140838,16 +149434,18 @@ bool TableScanParallelStateNext(ClientContext &context, const FunctionData *bind auto &bind_data = (const TableScanBindData &)*bind_data_p; auto ¶llel_state = (TableScanGlobalState &)*global_state; auto &state = (TableScanLocalState &)*local_state; + auto &storage = bind_data.table->GetStorage(); lock_guard parallel_lock(parallel_state.lock); - return bind_data.table->storage->NextParallelScan(context, parallel_state.state, state.scan_state); + return storage.NextParallelScan(context, parallel_state.state, state.scan_state); } double TableScanProgress(ClientContext &context, const FunctionData *bind_data_p, const GlobalTableFunctionState *gstate_p) { auto &bind_data = (TableScanBindData &)*bind_data_p; auto &gstate = (TableScanGlobalState &)*gstate_p; - idx_t total_rows = bind_data.table->storage->GetTotalRows(); + auto &storage = bind_data.table->GetStorage(); + idx_t total_rows = storage.GetTotalRows(); if (total_rows == 0) { //! Table is either empty or smaller than a vector size, so it is finished return 100; @@ -140873,17 +149471,21 @@ idx_t TableScanGetBatchIndex(ClientContext &context, const FunctionData *bind_da return 0; } -void TableScanDependency(unordered_set &entries, const FunctionData *bind_data_p) { +BindInfo TableScanGetBindInfo(const FunctionData *bind_data) { + return BindInfo(ScanType::TABLE); +} + +void TableScanDependency(DependencyList &entries, const FunctionData *bind_data_p) { auto &bind_data = (const TableScanBindData &)*bind_data_p; - entries.insert(bind_data.table); + entries.AddDependency(bind_data.table); } unique_ptr TableScanCardinality(ClientContext &context, const FunctionData *bind_data_p) { auto &bind_data = (const TableScanBindData &)*bind_data_p; - auto &local_storage = LocalStorage::Get(context); - idx_t estimated_cardinality = - bind_data.table->storage->info->cardinality + local_storage.AddedRows(bind_data.table->storage.get()); - return make_unique(bind_data.table->storage->info->cardinality, estimated_cardinality); + auto &local_storage = LocalStorage::Get(context, *bind_data.table->catalog); + auto &storage = bind_data.table->GetStorage(); + idx_t estimated_cardinality = storage.info->cardinality + local_storage.AddedRows(bind_data.table->GetStoragePtr()); + return make_unique(storage.info->cardinality, estimated_cardinality); } //===--------------------------------------------------------------------===// @@ -140907,25 +149509,25 @@ static unique_ptr IndexScanInitGlobal(ClientContext &c row_id_data = (data_ptr_t)&bind_data.result_ids[0]; } auto result = make_unique(row_id_data); - auto &local_storage = LocalStorage::Get(context); + auto &local_storage = LocalStorage::Get(context, *bind_data.table->catalog); result->column_ids = input.column_ids; result->local_storage_state.Initialize(input.column_ids, input.filters); - local_storage.InitializeScan(bind_data.table->storage.get(), result->local_storage_state.local_state, + local_storage.InitializeScan(bind_data.table->GetStoragePtr(), result->local_storage_state.local_state, input.filters); result->finished = false; - return move(result); + return std::move(result); } static void IndexScanFunction(ClientContext &context, TableFunctionInput &data_p, DataChunk &output) { auto &bind_data = (const TableScanBindData &)*data_p.bind_data; auto &state = (IndexScanGlobalState &)*data_p.global_state; - auto &transaction = Transaction::GetTransaction(context); + auto &transaction = DuckTransaction::Get(context, *bind_data.table->catalog); auto &local_storage = LocalStorage::Get(transaction); if (!state.finished) { - bind_data.table->storage->Fetch(transaction, output, state.column_ids, state.row_ids, - bind_data.result_ids.size(), state.fetch_state); + bind_data.table->GetStorage().Fetch(transaction, output, state.column_ids, state.row_ids, + bind_data.result_ids.size(), state.fetch_state); state.finished = true; } if (output.size() == 0) { @@ -140957,7 +149559,7 @@ void TableScanPushdownComplexFilter(ClientContext &context, LogicalGet &get, Fun vector> &filters) { auto &bind_data = (TableScanBindData &)*bind_data_p; auto table = bind_data.table; - auto &storage = *table->storage; + auto &storage = table->GetStorage(); auto &config = ClientConfig::GetConfig(context); if (!config.enable_optimizer) { @@ -141056,7 +149658,7 @@ void TableScanPushdownComplexFilter(ClientContext &context, LogicalGet &get, Fun } if (!equal_value.IsNull() || !low_value.IsNull() || !high_value.IsNull()) { // we can scan this index using this predicate: try a scan - auto &transaction = Transaction::GetTransaction(context); + auto &transaction = Transaction::Get(context, *bind_data.table->catalog); unique_ptr index_state; if (!equal_value.IsNull()) { // equality predicate @@ -141100,6 +149702,7 @@ static void TableScanSerialize(FieldWriter &writer, const FunctionData *bind_dat writer.WriteField(bind_data.is_index_scan); writer.WriteField(bind_data.is_create_index); writer.WriteList(bind_data.result_ids); + writer.WriteString(bind_data.table->schema->catalog->GetName()); } static unique_ptr TableScanDeserialize(ClientContext &context, FieldReader &reader, @@ -141109,18 +149712,18 @@ static unique_ptr TableScanDeserialize(ClientContext &context, Fie auto is_index_scan = reader.ReadRequired(); auto is_create_index = reader.ReadRequired(); auto result_ids = reader.ReadRequiredList(); + auto catalog_name = reader.ReadField(INVALID_CATALOG); - auto &catalog = Catalog::GetCatalog(context); - auto catalog_entry = catalog.GetEntry(context, CatalogType::TABLE_ENTRY, schema_name, table_name); + auto catalog_entry = Catalog::GetEntry(context, catalog_name, schema_name, table_name); if (!catalog_entry || catalog_entry->type != CatalogType::TABLE_ENTRY) { throw SerializationException("Cant find table for %s.%s", schema_name, table_name); } - auto result = make_unique((TableCatalogEntry *)catalog_entry); + auto result = make_unique((DuckTableEntry *)catalog_entry); result->is_index_scan = is_index_scan; result->is_create_index = is_create_index; - result->result_ids = move(result_ids); - return move(result); + result->result_ids = std::move(result_ids); + return std::move(result); } TableFunction TableScanFunction::GetIndexScanFunction() { @@ -141152,6 +149755,7 @@ TableFunction TableScanFunction::GetFunction() { scan_function.to_string = TableScanToString; scan_function.table_scan_progress = TableScanProgress; scan_function.get_batch_index = TableScanGetBatchIndex; + scan_function.get_batch_info = TableScanGetBindInfo; scan_function.projection_pushdown = true; scan_function.filter_pushdown = true; scan_function.filter_prune = true; @@ -141171,7 +149775,7 @@ TableCatalogEntry *TableScanFunction::GetTableEntry(const TableFunction &functio void TableScanFunction::RegisterFunction(BuiltinFunctions &set) { TableFunctionSet table_scan_set("seq_scan"); table_scan_set.AddFunction(GetFunction()); - set.AddFunction(move(table_scan_set)); + set.AddFunction(std::move(table_scan_set)); set.AddFunction(GetIndexScanFunction()); } @@ -141190,7 +149794,7 @@ void BuiltinFunctions::RegisterTableScanFunctions() { namespace duckdb { struct UnnestBindData : public FunctionData { - explicit UnnestBindData(LogicalType input_type_p) : input_type(move(input_type_p)) { + explicit UnnestBindData(LogicalType input_type_p) : input_type(std::move(input_type_p)) { } LogicalType input_type; @@ -141240,7 +149844,7 @@ static unique_ptr UnnestLocalInit(ExecutionContext &con auto result = make_unique(); result->operator_state = PhysicalUnnest::GetState(context, gstate.select_list); - return move(result); + return std::move(result); } static unique_ptr UnnestInit(ClientContext &context, TableFunctionInitInput &input) { @@ -141248,9 +149852,9 @@ static unique_ptr UnnestInit(ClientContext &context, T auto result = make_unique(); auto ref = make_unique(bind_data.input_type, 0); auto bound_unnest = make_unique(ListType::GetChildType(bind_data.input_type)); - bound_unnest->child = move(ref); - result->select_list.push_back(move(bound_unnest)); - return move(result); + bound_unnest->child = std::move(ref); + result->select_list.push_back(std::move(bound_unnest)); + return std::move(result); } static OperatorResultType UnnestFunction(ExecutionContext &context, TableFunctionInput &data_p, DataChunk &input, @@ -141313,6 +149917,10 @@ void PragmaVersion::RegisterFunction(BuiltinFunctions &set) { set.AddFunction(pragma_version); } +idx_t DuckDB::StandardVectorSize() { + return STANDARD_VECTOR_SIZE; +} + const char *DuckDB::SourceID() { return DUCKDB_SOURCE_ID; } @@ -141367,11 +149975,12 @@ TableFunctionInfo::~TableFunctionInfo() { TableFunction::TableFunction(string name, vector arguments, table_function_t function, table_function_bind_t bind, table_function_init_global_t init_global, table_function_init_local_t init_local) - : SimpleNamedParameterFunction(move(name), move(arguments)), bind(bind), init_global(init_global), + : SimpleNamedParameterFunction(std::move(name), std::move(arguments)), bind(bind), init_global(init_global), init_local(init_local), function(function), in_out_function(nullptr), in_out_function_final(nullptr), statistics(nullptr), dependency(nullptr), cardinality(nullptr), pushdown_complex_filter(nullptr), - to_string(nullptr), table_scan_progress(nullptr), get_batch_index(nullptr), serialize(nullptr), - deserialize(nullptr), projection_pushdown(false), filter_pushdown(false), filter_prune(false) { + to_string(nullptr), table_scan_progress(nullptr), get_batch_index(nullptr), get_batch_info(nullptr), + serialize(nullptr), deserialize(nullptr), projection_pushdown(false), filter_pushdown(false), + filter_prune(false) { } TableFunction::TableFunction(const vector &arguments, table_function_t function, @@ -141383,8 +149992,8 @@ TableFunction::TableFunction() : SimpleNamedParameterFunction("", {}), bind(nullptr), init_global(nullptr), init_local(nullptr), function(nullptr), in_out_function(nullptr), statistics(nullptr), dependency(nullptr), cardinality(nullptr), pushdown_complex_filter(nullptr), to_string(nullptr), table_scan_progress(nullptr), get_batch_index(nullptr), - serialize(nullptr), deserialize(nullptr), projection_pushdown(false), filter_pushdown(false), - filter_prune(false) { + get_batch_info(nullptr), serialize(nullptr), deserialize(nullptr), projection_pushdown(false), + filter_pushdown(false), filter_prune(false) { } } // namespace duckdb @@ -141404,7 +150013,7 @@ TableFunction::TableFunction() namespace duckdb { TableMacroFunction::TableMacroFunction(unique_ptr query_node) - : MacroFunction(MacroType::TABLE_MACRO), query_node(move(query_node)) { + : MacroFunction(MacroType::TABLE_MACRO), query_node(std::move(query_node)) { } TableMacroFunction::TableMacroFunction(void) : MacroFunction(MacroType::TABLE_MACRO) { @@ -141414,7 +150023,7 @@ unique_ptr TableMacroFunction::Copy() { auto result = make_unique(); result->query_node = query_node->Copy(); this->CopyProperties(*result); - return move(result); + return std::move(result); } string TableMacroFunction::ToSQL(const string &schema, const string &name) { @@ -141434,8 +150043,8 @@ namespace duckdb { void UDFWrapper::RegisterFunction(string name, vector args, LogicalType ret_type, scalar_function_t udf_function, ClientContext &context, LogicalType varargs) { - ScalarFunction scalar_function(move(name), move(args), move(ret_type), move(udf_function)); - scalar_function.varargs = move(varargs); + ScalarFunction scalar_function(std::move(name), std::move(args), std::move(ret_type), std::move(udf_function)); + scalar_function.varargs = std::move(varargs); scalar_function.null_handling = FunctionNullHandling::SPECIAL_HANDLING; CreateScalarFunctionInfo info(scalar_function); info.schema = DEFAULT_SCHEMA; @@ -141443,8 +150052,8 @@ void UDFWrapper::RegisterFunction(string name, vector args, Logical } void UDFWrapper::RegisterAggrFunction(AggregateFunction aggr_function, ClientContext &context, LogicalType varargs) { - aggr_function.varargs = move(varargs); - CreateAggregateFunctionInfo info(move(aggr_function)); + aggr_function.varargs = std::move(varargs); + CreateAggregateFunctionInfo info(std::move(aggr_function)); context.RegisterFunction(&info); } @@ -141463,6 +150072,7 @@ void UDFWrapper::RegisterAggrFunction(AggregateFunction aggr_function, ClientCon + namespace duckdb { BaseAppender::BaseAppender(Allocator &allocator, AppenderType type_p) @@ -141470,8 +150080,8 @@ BaseAppender::BaseAppender(Allocator &allocator, AppenderType type_p) } BaseAppender::BaseAppender(Allocator &allocator_p, vector types_p, AppenderType type_p) - : allocator(allocator_p), types(move(types_p)), collection(make_unique(allocator, types)), - column(0), appender_type(type_p) { + : allocator(allocator_p), types(std::move(types_p)), + collection(make_unique(allocator, types)), column(0), appender_type(type_p) { InitializeChunk(); } @@ -141808,7 +150418,7 @@ void Appender::FlushInternal(ColumnDataCollection &collection) { } void InternalAppender::FlushInternal(ColumnDataCollection &collection) { - table.storage->LocalAppend(table, context, collection); + table.GetStorage().LocalAppend(table, context, collection); } void BaseAppender::Close() { @@ -141817,6 +150427,201 @@ void BaseAppender::Close() { } } +} // namespace duckdb + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/transaction/duck_transaction_manager.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { +class DuckTransaction; + +//! The Transaction Manager is responsible for creating and managing +//! transactions +class DuckTransactionManager : public TransactionManager { + friend struct CheckpointLock; + +public: + explicit DuckTransactionManager(AttachedDatabase &db); + ~DuckTransactionManager(); + +public: + static DuckTransactionManager &Get(AttachedDatabase &db); + + //! Start a new transaction + Transaction *StartTransaction(ClientContext &context) override; + //! Commit the given transaction + string CommitTransaction(ClientContext &context, Transaction *transaction) override; + //! Rollback the given transaction + void RollbackTransaction(Transaction *transaction) override; + + void Checkpoint(ClientContext &context, bool force = false) override; + + transaction_t LowestActiveId() { + return lowest_active_id; + } + transaction_t LowestActiveStart() { + return lowest_active_start; + } + + bool IsDuckTransactionManager() override { + return true; + } + +private: + bool CanCheckpoint(DuckTransaction *current = nullptr); + //! Remove the given transaction from the list of active transactions + void RemoveTransaction(DuckTransaction *transaction) noexcept; + void LockClients(vector &client_locks, ClientContext &context); + +private: + //! The current start timestamp used by transactions + transaction_t current_start_timestamp; + //! The current transaction ID used by transactions + transaction_t current_transaction_id; + //! The lowest active transaction id + atomic lowest_active_id; + //! The lowest active transaction timestamp + atomic lowest_active_start; + //! Set of currently running transactions + vector> active_transactions; + //! Set of recently committed transactions + vector> recently_committed_transactions; + //! Transactions awaiting GC + vector> old_transactions; + //! The lock used for transaction operations + mutex transaction_lock; + + bool thread_is_checkpointing; +}; + +} // namespace duckdb + + + + + +namespace duckdb { + +AttachedDatabase::AttachedDatabase(DatabaseInstance &db, AttachedDatabaseType type) + : CatalogEntry(CatalogType::DATABASE_ENTRY, nullptr, + type == AttachedDatabaseType::SYSTEM_DATABASE ? SYSTEM_CATALOG : TEMP_CATALOG), + db(db), type(type) { + D_ASSERT(type == AttachedDatabaseType::TEMP_DATABASE || type == AttachedDatabaseType::SYSTEM_DATABASE); + if (type == AttachedDatabaseType::TEMP_DATABASE) { + storage = make_unique(*this, ":memory:", false); + } + catalog = make_unique(*this); + transaction_manager = make_unique(*this); + internal = true; +} + +AttachedDatabase::AttachedDatabase(DatabaseInstance &db, Catalog &catalog_p, string name_p, string file_path_p, + AccessMode access_mode) + : CatalogEntry(CatalogType::DATABASE_ENTRY, &catalog_p, std::move(name_p)), db(db), + type(access_mode == AccessMode::READ_ONLY ? AttachedDatabaseType::READ_ONLY_DATABASE + : AttachedDatabaseType::READ_WRITE_DATABASE) { + storage = + make_unique(*this, std::move(file_path_p), access_mode == AccessMode::READ_ONLY); + catalog = make_unique(*this); + transaction_manager = make_unique(*this); + internal = true; +} + +AttachedDatabase::AttachedDatabase(DatabaseInstance &db, Catalog &catalog_p, StorageExtension &storage_extension, + string name_p, AttachInfo &info, AccessMode access_mode) + : CatalogEntry(CatalogType::DATABASE_ENTRY, &catalog_p, std::move(name_p)), db(db), + type(access_mode == AccessMode::READ_ONLY ? AttachedDatabaseType::READ_ONLY_DATABASE + : AttachedDatabaseType::READ_WRITE_DATABASE) { + catalog = storage_extension.attach(storage_extension.storage_info.get(), *this, name, info, access_mode); + if (!catalog) { + throw InternalException("AttachedDatabase - attach function did not return a catalog"); + } + transaction_manager = + storage_extension.create_transaction_manager(storage_extension.storage_info.get(), *this, *catalog); + if (!transaction_manager) { + throw InternalException( + "AttachedDatabase - create_transaction_manager function did not return a transaction manager"); + } + internal = true; +} + +AttachedDatabase::~AttachedDatabase() { + if (Exception::UncaughtException()) { + return; + } + if (!storage) { + return; + } + + // shutting down: attempt to checkpoint the database + // but only if we are not cleaning up as part of an exception unwind + try { + if (!storage->InMemory()) { + auto &config = DBConfig::GetConfig(db); + if (!config.options.checkpoint_on_shutdown) { + return; + } + storage->CreateCheckpoint(true); + } + } catch (...) { + } +} + +bool AttachedDatabase::IsSystem() const { + D_ASSERT(!storage || type != AttachedDatabaseType::SYSTEM_DATABASE); + return type == AttachedDatabaseType::SYSTEM_DATABASE; +} + +bool AttachedDatabase::IsTemporary() const { + return type == AttachedDatabaseType::TEMP_DATABASE; +} +bool AttachedDatabase::IsReadOnly() const { + return type == AttachedDatabaseType::READ_ONLY_DATABASE; +} + +string AttachedDatabase::ExtractDatabaseName(const string &dbpath) { + if (dbpath.empty() || dbpath == ":memory:") { + return "memory"; + } + return FileSystem::ExtractBaseName(dbpath); +} + +void AttachedDatabase::Initialize() { + if (IsSystem()) { + catalog->Initialize(true); + } else { + catalog->Initialize(false); + } + if (storage) { + storage->Initialize(); + } +} + +StorageManager &AttachedDatabase::GetStorageManager() { + if (!storage) { + throw InternalException("Internal system catalog does not have storage"); + } + return *storage; +} + +Catalog &AttachedDatabase::GetCatalog() { + return *catalog; +} + +TransactionManager &AttachedDatabase::GetTransactionManager() { + return *transaction_manager; +} + } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB @@ -141853,6 +150658,11 @@ struct PreparedStatementWrapper { vector values; }; +struct ExtractStatementsWrapper { + vector> statements; + string error; +}; + struct PendingStatementWrapper { unique_ptr statement; }; @@ -142203,7 +151013,7 @@ duckdb_state duckdb_execute_prepared_arrow(duckdb_prepared_statement prepared_st auto result = wrapper->statement->Execute(wrapper->values, false); D_ASSERT(result->type == QueryResultType::MATERIALIZED_RESULT); - arrow_wrapper->result = duckdb::unique_ptr_cast(move(result)); + arrow_wrapper->result = duckdb::unique_ptr_cast(std::move(result)); *out_result = (duckdb_arrow)arrow_wrapper; return !arrow_wrapper->result->HasError() ? DuckDBSuccess : DuckDBError; } @@ -142683,6 +151493,7 @@ void duckdb_destroy_config(duckdb_config *config) { + #include duckdb_data_chunk duckdb_create_data_chunk(duckdb_logical_type *ctypes, idx_t column_count) { @@ -142697,7 +151508,7 @@ duckdb_data_chunk duckdb_create_data_chunk(duckdb_logical_type *ctypes, idx_t co auto result = new duckdb::DataChunk(); result->Initialize(duckdb::Allocator::DefaultAllocator(), types); - return result; + return reinterpret_cast(result); } void duckdb_destroy_data_chunk(duckdb_data_chunk *chunk) { @@ -142729,7 +151540,7 @@ duckdb_vector duckdb_data_chunk_get_vector(duckdb_data_chunk chunk, idx_t col_id return nullptr; } auto dchunk = (duckdb::DataChunk *)chunk; - return &dchunk->data[col_idx]; + return reinterpret_cast(&dchunk->data[col_idx]); } idx_t duckdb_data_chunk_get_size(duckdb_data_chunk chunk) { @@ -142753,7 +151564,7 @@ duckdb_logical_type duckdb_vector_get_column_type(duckdb_vector vector) { return nullptr; } auto v = (duckdb::Vector *)vector; - return new duckdb::LogicalType(v->GetType()); + return reinterpret_cast(new duckdb::LogicalType(v->GetType())); } void *duckdb_vector_get_data(duckdb_vector vector) { @@ -142799,7 +151610,7 @@ duckdb_vector duckdb_list_vector_get_child(duckdb_vector vector) { return nullptr; } auto v = (duckdb::Vector *)vector; - return &duckdb::ListVector::GetEntry(*v); + return reinterpret_cast(&duckdb::ListVector::GetEntry(*v)); } idx_t duckdb_list_vector_get_size(duckdb_vector vector) { @@ -142810,12 +151621,30 @@ idx_t duckdb_list_vector_get_size(duckdb_vector vector) { return duckdb::ListVector::GetListSize(*v); } +duckdb_state duckdb_list_vector_set_size(duckdb_vector vector, idx_t size) { + if (!vector) { + return duckdb_state::DuckDBError; + } + auto v = (duckdb::Vector *)vector; + duckdb::ListVector::SetListSize(*v, size); + return duckdb_state::DuckDBSuccess; +} + +duckdb_state duckdb_list_vector_reserve(duckdb_vector vector, idx_t required_capacity) { + if (!vector) { + return duckdb_state::DuckDBError; + } + auto v = (duckdb::Vector *)vector; + duckdb::ListVector::Reserve(*v, required_capacity); + return duckdb_state::DuckDBSuccess; +} + duckdb_vector duckdb_struct_vector_get_child(duckdb_vector vector, idx_t index) { if (!vector) { return nullptr; } auto v = (duckdb::Vector *)vector; - return duckdb::StructVector::GetEntries(*v)[index].get(); + return reinterpret_cast(duckdb::StructVector::GetEntries(*v)[index].get()); } bool duckdb_validity_row_is_valid(uint64_t *validity, idx_t row) { @@ -142992,7 +151821,7 @@ void duckdb_disconnect(duckdb_connection *connection) { duckdb_state duckdb_query(duckdb_connection connection, const char *query, duckdb_result *out) { Connection *conn = (Connection *)connection; auto result = conn->Query(query); - return duckdb_translate_result(move(result), out); + return duckdb_translate_result(std::move(result), out); } const char *duckdb_library_version() { @@ -143009,7 +151838,7 @@ void duckdb_destroy_value(duckdb_value *value) { } duckdb_value duckdb_create_varchar_length(const char *text, idx_t length) { - return (duckdb_value) new duckdb::Value(std::string(text, length)); + return reinterpret_cast(new duckdb::Value(std::string(text, length))); } duckdb_value duckdb_create_varchar(const char *text) { @@ -143018,7 +151847,7 @@ duckdb_value duckdb_create_varchar(const char *text) { duckdb_value duckdb_create_int64(int64_t input) { auto val = duckdb::Value::BIGINT(input); - return (duckdb_value) new duckdb::Value(val); + return reinterpret_cast(new duckdb::Value(val)); } char *duckdb_get_varchar(duckdb_value value) { @@ -143077,8 +151906,6 @@ LogicalTypeId ConvertCTypeToCPP(duckdb_type c_type) { return LogicalTypeId::TIME; case DUCKDB_TYPE_VARCHAR: return LogicalTypeId::VARCHAR; - case DUCKDB_TYPE_JSON: - return LogicalTypeId::JSON; case DUCKDB_TYPE_BLOB: return LogicalTypeId::BLOB; case DUCKDB_TYPE_INTERVAL: @@ -143139,10 +151966,10 @@ duckdb_type ConvertCPPTypeToC(const LogicalType &sql_type) { return DUCKDB_TYPE_TIME; case LogicalTypeId::VARCHAR: return DUCKDB_TYPE_VARCHAR; - case LogicalTypeId::JSON: - return DUCKDB_TYPE_JSON; case LogicalTypeId::BLOB: return DUCKDB_TYPE_BLOB; + case LogicalTypeId::BIT: + return DUCKDB_TYPE_BIT; case LogicalTypeId::INTERVAL: return DUCKDB_TYPE_INTERVAL; case LogicalTypeId::DECIMAL: @@ -143424,8 +152251,30 @@ double duckdb_decimal_to_double(duckdb_decimal val) { } +static bool AssertLogicalTypeId(duckdb_logical_type type, duckdb::LogicalTypeId type_id) { + if (!type) { + return false; + } + auto <ype = *((duckdb::LogicalType *)type); + if (ltype.id() != type_id) { + return false; + } + return true; +} + +static bool AssertInternalType(duckdb_logical_type type, duckdb::PhysicalType physical_type) { + if (!type) { + return false; + } + auto <ype = *((duckdb::LogicalType *)type); + if (ltype.InternalType() != physical_type) { + return false; + } + return true; +} + duckdb_logical_type duckdb_create_logical_type(duckdb_type type) { - return new duckdb::LogicalType(duckdb::ConvertCTypeToCPP(type)); + return reinterpret_cast(new duckdb::LogicalType(duckdb::ConvertCTypeToCPP(type))); } duckdb_logical_type duckdb_create_list_type(duckdb_logical_type type) { @@ -143434,7 +152283,23 @@ duckdb_logical_type duckdb_create_list_type(duckdb_logical_type type) { } duckdb::LogicalType *ltype = new duckdb::LogicalType; *ltype = duckdb::LogicalType::LIST(*(duckdb::LogicalType *)type); - return ltype; + return reinterpret_cast(ltype); +} + +duckdb_logical_type duckdb_create_union_type(duckdb_logical_type member_types_p, const char **member_names, + idx_t member_count) { + if (!member_types_p || !member_names) { + return nullptr; + } + duckdb::LogicalType *member_types = (duckdb::LogicalType *)member_types_p; + duckdb::LogicalType *mtype = new duckdb::LogicalType; + duckdb::child_list_t members; + + for (idx_t i = 0; i < member_count; i++) { + members.push_back(make_pair(member_names[i], member_types[i])); + } + *mtype = duckdb::LogicalType::UNION(members); + return reinterpret_cast(mtype); } duckdb_logical_type duckdb_create_map_type(duckdb_logical_type key_type, duckdb_logical_type value_type) { @@ -143443,11 +152308,11 @@ duckdb_logical_type duckdb_create_map_type(duckdb_logical_type key_type, duckdb_ } duckdb::LogicalType *mtype = new duckdb::LogicalType; *mtype = duckdb::LogicalType::MAP(*(duckdb::LogicalType *)key_type, *(duckdb::LogicalType *)value_type); - return mtype; + return reinterpret_cast(mtype); } duckdb_logical_type duckdb_create_decimal_type(uint8_t width, uint8_t scale) { - return new duckdb::LogicalType(duckdb::LogicalType::DECIMAL(width, scale)); + return reinterpret_cast(new duckdb::LogicalType(duckdb::LogicalType::DECIMAL(width, scale))); } duckdb_type duckdb_get_type_id(duckdb_logical_type type) { @@ -143467,35 +152332,26 @@ void duckdb_destroy_logical_type(duckdb_logical_type *type) { } uint8_t duckdb_decimal_width(duckdb_logical_type type) { - if (!type) { + if (!AssertLogicalTypeId(type, duckdb::LogicalTypeId::DECIMAL)) { return 0; } auto <ype = *((duckdb::LogicalType *)type); - if (ltype.id() != duckdb::LogicalTypeId::DECIMAL) { - return 0; - } return duckdb::DecimalType::GetWidth(ltype); } uint8_t duckdb_decimal_scale(duckdb_logical_type type) { - if (!type) { + if (!AssertLogicalTypeId(type, duckdb::LogicalTypeId::DECIMAL)) { return 0; } auto <ype = *((duckdb::LogicalType *)type); - if (ltype.id() != duckdb::LogicalTypeId::DECIMAL) { - return 0; - } return duckdb::DecimalType::GetScale(ltype); } duckdb_type duckdb_decimal_internal_type(duckdb_logical_type type) { - if (!type) { + if (!AssertLogicalTypeId(type, duckdb::LogicalTypeId::DECIMAL)) { return DUCKDB_TYPE_INVALID; } auto <ype = *((duckdb::LogicalType *)type); - if (ltype.id() != duckdb::LogicalTypeId::DECIMAL) { - return DUCKDB_TYPE_INVALID; - } switch (ltype.InternalType()) { case duckdb::PhysicalType::INT16: return DUCKDB_TYPE_SMALLINT; @@ -143511,13 +152367,10 @@ duckdb_type duckdb_decimal_internal_type(duckdb_logical_type type) { } duckdb_type duckdb_enum_internal_type(duckdb_logical_type type) { - if (!type) { + if (!AssertLogicalTypeId(type, duckdb::LogicalTypeId::ENUM)) { return DUCKDB_TYPE_INVALID; } auto <ype = *((duckdb::LogicalType *)type); - if (ltype.id() != duckdb::LogicalTypeId::ENUM) { - return DUCKDB_TYPE_INVALID; - } switch (ltype.InternalType()) { case duckdb::PhysicalType::UINT8: return DUCKDB_TYPE_UTINYINT; @@ -143531,93 +152384,117 @@ duckdb_type duckdb_enum_internal_type(duckdb_logical_type type) { } uint32_t duckdb_enum_dictionary_size(duckdb_logical_type type) { - if (!type) { + if (!AssertLogicalTypeId(type, duckdb::LogicalTypeId::ENUM)) { return 0; } auto <ype = *((duckdb::LogicalType *)type); - if (ltype.id() != duckdb::LogicalTypeId::ENUM) { - return 0; - } return duckdb::EnumType::GetSize(ltype); } char *duckdb_enum_dictionary_value(duckdb_logical_type type, idx_t index) { - if (!type) { + if (!AssertLogicalTypeId(type, duckdb::LogicalTypeId::ENUM)) { return nullptr; } auto <ype = *((duckdb::LogicalType *)type); - if (ltype.id() != duckdb::LogicalTypeId::ENUM) { - return nullptr; - } auto &vector = duckdb::EnumType::GetValuesInsertOrder(ltype); auto value = vector.GetValue(index); return strdup(duckdb::StringValue::Get(value).c_str()); } duckdb_logical_type duckdb_list_type_child_type(duckdb_logical_type type) { - if (!type) { + if (!AssertLogicalTypeId(type, duckdb::LogicalTypeId::LIST) && + !AssertLogicalTypeId(type, duckdb::LogicalTypeId::MAP)) { return nullptr; } auto <ype = *((duckdb::LogicalType *)type); - if (ltype.id() != duckdb::LogicalTypeId::LIST) { + if (ltype.id() != duckdb::LogicalTypeId::LIST && ltype.id() != duckdb::LogicalTypeId::MAP) { return nullptr; } - return new duckdb::LogicalType(duckdb::ListType::GetChildType(ltype)); + return reinterpret_cast(new duckdb::LogicalType(duckdb::ListType::GetChildType(ltype))); } duckdb_logical_type duckdb_map_type_key_type(duckdb_logical_type type) { - if (!type) { + if (!AssertLogicalTypeId(type, duckdb::LogicalTypeId::MAP)) { return nullptr; } auto &mtype = *((duckdb::LogicalType *)type); if (mtype.id() != duckdb::LogicalTypeId::MAP) { return nullptr; } - return new duckdb::LogicalType(duckdb::MapType::KeyType(mtype)); + return reinterpret_cast(new duckdb::LogicalType(duckdb::MapType::KeyType(mtype))); } duckdb_logical_type duckdb_map_type_value_type(duckdb_logical_type type) { - if (!type) { + if (!AssertLogicalTypeId(type, duckdb::LogicalTypeId::MAP)) { return nullptr; } auto &mtype = *((duckdb::LogicalType *)type); if (mtype.id() != duckdb::LogicalTypeId::MAP) { return nullptr; } - return new duckdb::LogicalType(duckdb::MapType::ValueType(mtype)); + return reinterpret_cast(new duckdb::LogicalType(duckdb::MapType::ValueType(mtype))); } idx_t duckdb_struct_type_child_count(duckdb_logical_type type) { - if (!type) { + if (!AssertInternalType(type, duckdb::PhysicalType::STRUCT)) { return 0; } auto <ype = *((duckdb::LogicalType *)type); - if (ltype.InternalType() != duckdb::PhysicalType::STRUCT) { + return duckdb::StructType::GetChildCount(ltype); +} + +idx_t duckdb_union_type_member_count(duckdb_logical_type type) { + if (!AssertLogicalTypeId(type, duckdb::LogicalTypeId::UNION)) { return 0; } - return duckdb::StructType::GetChildCount(ltype); + idx_t member_count = duckdb_struct_type_child_count(type); + if (member_count != 0) { + member_count--; + } + return member_count; } -char *duckdb_struct_type_child_name(duckdb_logical_type type, idx_t index) { - if (!type) { +char *duckdb_union_type_member_name(duckdb_logical_type type, idx_t index) { + if (!AssertInternalType(type, duckdb::PhysicalType::STRUCT)) { + return nullptr; + } + if (!AssertLogicalTypeId(type, duckdb::LogicalTypeId::UNION)) { return nullptr; } auto <ype = *((duckdb::LogicalType *)type); - if (ltype.InternalType() != duckdb::PhysicalType::STRUCT) { + return strdup(duckdb::UnionType::GetMemberName(ltype, index).c_str()); +} + +duckdb_logical_type duckdb_union_type_member_type(duckdb_logical_type type, idx_t index) { + if (!AssertInternalType(type, duckdb::PhysicalType::STRUCT)) { + return nullptr; + } + if (!AssertLogicalTypeId(type, duckdb::LogicalTypeId::UNION)) { return nullptr; } + auto <ype = *((duckdb::LogicalType *)type); + return reinterpret_cast( + new duckdb::LogicalType(duckdb::UnionType::GetMemberType(ltype, index))); +} + +char *duckdb_struct_type_child_name(duckdb_logical_type type, idx_t index) { + if (!AssertInternalType(type, duckdb::PhysicalType::STRUCT)) { + return nullptr; + } + auto <ype = *((duckdb::LogicalType *)type); return strdup(duckdb::StructType::GetChildName(ltype, index).c_str()); } duckdb_logical_type duckdb_struct_type_child_type(duckdb_logical_type type, idx_t index) { - if (!type) { + if (!AssertInternalType(type, duckdb::PhysicalType::STRUCT)) { return nullptr; } auto <ype = *((duckdb::LogicalType *)type); if (ltype.InternalType() != duckdb::PhysicalType::STRUCT) { return nullptr; } - return new duckdb::LogicalType(duckdb::StructType::GetChildType(ltype, index)); + return reinterpret_cast( + new duckdb::LogicalType(duckdb::StructType::GetChildType(ltype, index))); } @@ -143713,7 +152590,7 @@ duckdb_state duckdb_execute_pending(duckdb_pending_result pending_result, duckdb } auto result = wrapper->statement->Execute(); wrapper->statement.reset(); - return duckdb_translate_result(move(result), out_result); + return duckdb_translate_result(std::move(result), out_result); } @@ -143723,6 +152600,7 @@ duckdb_state duckdb_execute_pending(duckdb_pending_result pending_result, duckdb using duckdb::Connection; using duckdb::date_t; using duckdb::dtime_t; +using duckdb::ExtractStatementsWrapper; using duckdb::hugeint_t; using duckdb::LogicalType; using duckdb::MaterializedQueryResult; @@ -143731,6 +152609,47 @@ using duckdb::QueryResultType; using duckdb::timestamp_t; using duckdb::Value; +idx_t duckdb_extract_statements(duckdb_connection connection, const char *query, + duckdb_extracted_statements *out_extracted_statements) { + if (!connection || !query || !out_extracted_statements) { + return 0; + } + auto wrapper = new ExtractStatementsWrapper(); + Connection *conn = (Connection *)connection; + try { + wrapper->statements = conn->ExtractStatements(query); + } catch (const duckdb::ParserException &e) { + wrapper->error = e.what(); + } + + *out_extracted_statements = (duckdb_extracted_statements)wrapper; + return wrapper->statements.size(); +} + +duckdb_state duckdb_prepare_extracted_statement(duckdb_connection connection, + duckdb_extracted_statements extracted_statements, idx_t index, + duckdb_prepared_statement *out_prepared_statement) { + Connection *conn = (Connection *)connection; + auto source_wrapper = (ExtractStatementsWrapper *)extracted_statements; + + if (!connection || !out_prepared_statement || index >= source_wrapper->statements.size()) { + return DuckDBError; + } + auto wrapper = new PreparedStatementWrapper(); + wrapper->statement = conn->Prepare(std::move(source_wrapper->statements[index])); + + *out_prepared_statement = (duckdb_prepared_statement)wrapper; + return wrapper->statement->HasError() ? DuckDBError : DuckDBSuccess; +} + +const char *duckdb_extract_statements_error(duckdb_extracted_statements extracted_statements) { + auto wrapper = (ExtractStatementsWrapper *)extracted_statements; + if (!wrapper || wrapper->error.empty()) { + return nullptr; + } + return wrapper->error.c_str(); +} + duckdb_state duckdb_prepare(duckdb_connection connection, const char *query, duckdb_prepared_statement *out_prepared_statement) { if (!connection || !query || !out_prepared_statement) { @@ -143908,18 +152827,28 @@ duckdb_state duckdb_execute_prepared(duckdb_prepared_statement prepared_statemen return DuckDBError; } auto result = wrapper->statement->Execute(wrapper->values, false); - return duckdb_translate_result(move(result), out_result); + return duckdb_translate_result(std::move(result), out_result); } -void duckdb_destroy_prepare(duckdb_prepared_statement *prepared_statement) { - if (!prepared_statement) { +template +void duckdb_destroy(void **wrapper) { + if (!wrapper) { return; } - auto wrapper = (PreparedStatementWrapper *)*prepared_statement; - if (wrapper) { - delete wrapper; + + auto casted = (T *)*wrapper; + if (casted) { + delete casted; } - *prepared_statement = nullptr; + *wrapper = nullptr; +} + +void duckdb_destroy_extracted(duckdb_extracted_statements *extracted_statements) { + duckdb_destroy(reinterpret_cast(extracted_statements)); +} + +void duckdb_destroy_prepare(duckdb_prepared_statement *prepared_statement) { + duckdb_destroy(reinterpret_cast(prepared_statement)); } @@ -143951,8 +152880,8 @@ struct CAPIReplacementScanInfo { string error; }; -unique_ptr duckdb_capi_replacement_callback(ClientContext &context, const string &table_name, - ReplacementScanData *data) { +unique_ptr duckdb_capi_replacement_callback(ClientContext &context, const string &table_name, + ReplacementScanData *data) { auto &scan_data = (CAPIReplacementScanData &)*data; CAPIReplacementScanInfo info(&scan_data); @@ -143967,10 +152896,10 @@ unique_ptr duckdb_capi_replacement_callback(ClientContext &con auto table_function = make_unique(); vector> children; for (auto ¶m : info.parameters) { - children.push_back(make_unique(move(param))); + children.push_back(make_unique(std::move(param))); } - table_function->function = make_unique(info.function_name, move(children)); - return table_function; + table_function->function = make_unique(info.function_name, std::move(children)); + return std::move(table_function); } } // namespace duckdb @@ -143988,7 +152917,7 @@ void duckdb_add_replacement_scan(duckdb_database db, duckdb_replacement_callback auto &config = duckdb::DBConfig::GetConfig(*wrapper->database->instance); config.replacement_scans.push_back( - duckdb::ReplacementScan(duckdb::duckdb_capi_replacement_callback, move(scan_info))); + duckdb::ReplacementScan(duckdb::duckdb_capi_replacement_callback, std::move(scan_info))); } void duckdb_replacement_scan_set_function_name(duckdb_replacement_scan_info info_p, const char *function_name) { @@ -144277,7 +153206,7 @@ duckdb_state duckdb_translate_result(unique_ptr result_p, duckdb_re // initialize the result_data object auto result_data = new DuckDBResultData(); - result_data->result = move(result_p); + result_data->result = std::move(result_p); result_data->result_set_type = CAPIResultSetType::CAPI_RESULT_TYPE_NONE; out->internal_data = result_data; @@ -144414,7 +153343,7 @@ duckdb_logical_type duckdb_column_logical_type(duckdb_result *result, idx_t col) return nullptr; } auto &result_data = *((duckdb::DuckDBResultData *)result->internal_data); - return new duckdb::LogicalType(result_data.result->types[col]); + return reinterpret_cast(new duckdb::LogicalType(result_data.result->types[col])); } idx_t duckdb_column_count(duckdb_result *result) { @@ -144502,7 +153431,7 @@ duckdb_data_chunk duckdb_result_get_chunk(duckdb_result result, idx_t chunk_idx) auto chunk = duckdb::make_unique(); chunk->Initialize(duckdb::Allocator::DefaultAllocator(), collection.Types()); collection.FetchChunk(chunk_idx, *chunk); - return chunk.release(); + return reinterpret_cast(chunk.release()); } @@ -144626,7 +153555,7 @@ unique_ptr CTableFunctionBind(ClientContext &context, TableFunctio } result->info = info; - return move(result); + return std::move(result); } unique_ptr CTableFunctionInit(ClientContext &context, TableFunctionInitInput &data_p) { @@ -144638,7 +153567,7 @@ unique_ptr CTableFunctionInit(ClientContext &context, if (!init_info.success) { throw Exception(init_info.error); } - return move(result); + return std::move(result); } unique_ptr CTableFunctionLocalInit(ExecutionContext &context, TableFunctionInitInput &data_p, @@ -144646,7 +153575,7 @@ unique_ptr CTableFunctionLocalInit(ExecutionContext &co auto &bind_data = (CTableBindData &)*data_p.bind_data; auto result = make_unique(); if (!bind_data.info->local_init) { - return move(result); + return std::move(result); } CTableInternalInitInfo init_info(bind_data, result->init_data, data_p.column_ids, data_p.filters); @@ -144654,7 +153583,7 @@ unique_ptr CTableFunctionLocalInit(ExecutionContext &co if (!init_info.success) { throw Exception(init_info.error); } - return move(result); + return std::move(result); } unique_ptr CTableFunctionCardinality(ClientContext &context, const FunctionData *bind_data_p) { @@ -144670,7 +153599,7 @@ void CTableFunction(ClientContext &context, TableFunctionInput &data_p, DataChun auto &global_data = (CTableGlobalInitData &)*data_p.global_state; auto &local_data = (CTableLocalInitData &)*data_p.local_state; CTableInternalFunctionInfo function_info(bind_data, global_data.init_data, local_data.init_data); - bind_data.info->function(&function_info, &output); + bind_data.info->function(&function_info, reinterpret_cast(&output)); if (!function_info.success) { throw Exception(function_info.error); } @@ -144780,7 +153709,7 @@ duckdb_state duckdb_register_table_function(duckdb_connection connection, duckdb return DuckDBError; } con->context->RunFunctionInTransaction([&]() { - auto &catalog = duckdb::Catalog::GetCatalog(*con->context); + auto &catalog = duckdb::Catalog::GetSystemCatalog(*con->context); duckdb::CreateTableFunctionInfo tf_info(*tf); // create the function in the catalog @@ -144822,7 +153751,7 @@ duckdb_value duckdb_bind_get_parameter(duckdb_bind_info info, idx_t index) { return nullptr; } auto bind_info = (duckdb::CTableInternalBindInfo *)info; - return new duckdb::Value(bind_info->input.inputs[index]); + return reinterpret_cast(new duckdb::Value(bind_info->input.inputs[index])); } void duckdb_bind_set_bind_data(duckdb_bind_info info, void *bind_data, duckdb_delete_callback_t destroy) { @@ -145043,6 +153972,14 @@ void duckdb_destroy_task_state(duckdb_task_state state_p) { delete state; } +bool duckdb_execution_is_finished(duckdb_connection con) { + if (!con) { + return false; + } + duckdb::Connection *conn = (duckdb::Connection *)con; + return conn->context->ExecutionIsFinished(); +} + @@ -145301,7 +154238,7 @@ namespace duckdb { class ClientContext; -//! ClientContext-specific FileOpener implemenation. +//! ClientContext-specific FileOpener implementation. //! This object is owned by ClientContext and never outlives it. class ClientContextFileOpener : public FileOpener { public: @@ -145310,6 +154247,10 @@ class ClientContextFileOpener : public FileOpener { bool TryGetCurrentSetting(const string &key, Value &result) override; + ClientContext *TryGetClientContext() override { + return &context; + }; + private: ClientContext &context; }; @@ -145520,7 +154461,7 @@ class ParameterExpression : public ParsedExpression { string ToString() const override; - static bool Equals(const ParameterExpression *a, const ParameterExpression *b); + static bool Equal(const ParameterExpression *a, const ParameterExpression *b); unique_ptr Copy() const override; hash_t Hash() const override; @@ -145789,6 +154730,61 @@ class ExecuteStatement : public SQLStatement { + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/http_stats.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + + +namespace duckdb { + +class HTTPStats { +public: + atomic head_count {0}; + atomic get_count {0}; + atomic put_count {0}; + atomic post_count {0}; + atomic total_bytes_received {0}; + atomic total_bytes_sent {0}; + + void Reset() { + head_count = 0; + get_count = 0; + put_count = 0; + post_count = 0; + total_bytes_received = 0; + total_bytes_sent = 0; + } + + //! helper function to get the HTTP + static HTTPStats *TryGetStats(FileOpener *opener) { + auto client_context = FileOpener::TryGetClientContext(opener); + if (client_context) { + return client_context->client_data->http_stats.get(); + } + return nullptr; + } + + bool IsEmpty() { + return head_count == 0 && get_count == 0 && put_count == 0 && post_count == 0 && total_bytes_received == 0 && + total_bytes_sent == 0; + } +}; + +} // namespace duckdb + + + namespace duckdb { struct ActiveQueryContext { @@ -145805,8 +154801,7 @@ struct ActiveQueryContext { }; ClientContext::ClientContext(shared_ptr database) - : db(move(database)), transaction(db->GetTransactionManager(), *this), interrupted(false), - client_data(make_unique(*this)) { + : db(std::move(database)), interrupted(false), client_data(make_unique(*this)), transaction(*this) { } ClientContext::~ClientContext() { @@ -145825,7 +154820,7 @@ unique_ptr ClientContext::LockContext() { void ClientContext::Destroy() { auto lock = LockContext(); if (transaction.HasActiveTransaction()) { - ActiveTransaction().active_query = MAXIMUM_QUERY_ID; + transaction.ResetActiveQuery(); if (!transaction.IsAutoCommit()) { transaction.Rollback(); } @@ -145892,19 +154887,30 @@ void ClientContext::BeginQueryInternal(ClientContextLock &lock, const string &qu LogQueryInternal(lock, query); active_query->query = query; query_progress = -1; - ActiveTransaction().active_query = db->GetTransactionManager().GetQueryNumber(); + transaction.SetActiveQuery(db->GetDatabaseManager().GetNewQueryNumber()); } PreservedError ClientContext::EndQueryInternal(ClientContextLock &lock, bool success, bool invalidate_transaction) { client_data->profiler->EndQuery(); + if (client_data->http_stats) { + client_data->http_stats->Reset(); + } + + // Notify any registered state of query end + for (auto const &s : registered_state) { + s.second->QueryEnd(); + } + D_ASSERT(active_query.get()); + active_query.reset(); + query_progress = -1; PreservedError error; try { if (transaction.HasActiveTransaction()) { // Move the query profiler into the history auto &prev_profilers = client_data->query_profiler_history->GetPrevProfilers(); - prev_profilers.emplace_back(transaction.ActiveTransaction().active_query, move(client_data->profiler)); + prev_profilers.emplace_back(transaction.GetActiveQuery(), std::move(client_data->profiler)); // Reinitialize the query profiler client_data->profiler = make_shared(*this); // Propagate settings of the saved query into the new profiler. @@ -145913,7 +154919,7 @@ PreservedError ClientContext::EndQueryInternal(ClientContextLock &lock, bool suc prev_profilers.pop_front(); } - ActiveTransaction().active_query = MAXIMUM_QUERY_ID; + transaction.ResetActiveQuery(); if (transaction.IsAutoCommit()) { if (success) { transaction.Commit(); @@ -145936,8 +154942,6 @@ PreservedError ClientContext::EndQueryInternal(ClientContextLock &lock, bool suc } catch (...) { // LCOV_EXCL_START error = PreservedError("Unhandled exception!"); } // LCOV_EXCL_STOP - active_query.reset(); - query_progress = -1; return error; } @@ -145969,10 +154973,6 @@ FileOpener *FileOpener::Get(ClientContext &context) { return ClientData::Get(context).file_opener.get(); } -SchemaCatalogEntry *SchemaCatalogEntry::GetTemporaryObjects(ClientContext &context) { - return context.client_data->temporary_objects.get(); -} - const string &ClientContext::GetCurrentQuery() { D_ASSERT(active_query); return active_query->query; @@ -145995,7 +154995,7 @@ unique_ptr ClientContext::FetchResultInternal(ClientContextLock &lo auto stream_result = make_unique(pending.statement_type, pending.properties, shared_from_this(), pending.types, pending.names); active_query->open_result = stream_result.get(); - return move(stream_result); + return std::move(stream_result); } unique_ptr result; if (executor.HasResultCollector()) { @@ -146006,8 +155006,9 @@ unique_ptr ClientContext::FetchResultInternal(ClientContextLock &lo // no result collector - create a materialized result by continuously fetching auto result_collection = make_unique(Allocator::DefaultAllocator(), pending.types); D_ASSERT(!result_collection->Types().empty()); - auto materialized_result = make_unique( - pending.statement_type, pending.properties, pending.names, move(result_collection), GetClientProperties()); + auto materialized_result = + make_unique(pending.statement_type, pending.properties, pending.names, + std::move(result_collection), GetClientProperties()); auto &collection = materialized_result->Collection(); D_ASSERT(!collection.Types().empty()); @@ -146027,7 +155028,7 @@ unique_ptr ClientContext::FetchResultInternal(ClientContextLock &lo #endif collection.Append(append_state, *chunk); } - result = move(materialized_result); + result = std::move(materialized_result); } return result; } @@ -146058,17 +155059,17 @@ shared_ptr ClientContext::CreatePreparedStatement(ClientC planner.parameter_data.emplace_back(value); } } - planner.CreatePlan(move(statement)); + planner.CreatePlan(std::move(statement)); D_ASSERT(planner.plan || !planner.properties.bound_all_parameters); profiler.EndPhase(); - auto plan = move(planner.plan); + auto plan = std::move(planner.plan); // extract the result column names from the plan result->properties = planner.properties; result->names = planner.names; result->types = planner.types; - result->value_map = move(planner.value_map); - result->catalog_version = Transaction::GetTransaction(*this).catalog_version; + result->value_map = std::move(planner.value_map); + result->catalog_version = MetaTransaction::Get(*this).catalog_version; if (!planner.properties.bound_all_parameters) { return result; @@ -146079,7 +155080,7 @@ shared_ptr ClientContext::CreatePreparedStatement(ClientC if (config.enable_optimizer && plan->RequireOptimizer()) { profiler.StartPhase("optimizer"); Optimizer optimizer(*planner.binder, *this); - plan = optimizer.Optimize(move(plan)); + plan = optimizer.Optimize(std::move(plan)); D_ASSERT(plan); profiler.EndPhase(); @@ -146091,13 +155092,13 @@ shared_ptr ClientContext::CreatePreparedStatement(ClientC profiler.StartPhase("physical_planner"); // now convert logical query plan into a physical query plan PhysicalPlanGenerator physical_planner(*this); - auto physical_plan = physical_planner.CreatePlan(move(plan)); + auto physical_plan = physical_planner.CreatePlan(std::move(plan)); profiler.EndPhase(); #ifdef DEBUG D_ASSERT(!physical_plan->ToString().empty()); #endif - result->plan = move(physical_plan); + result->plan = std::move(physical_plan); return result; } @@ -146113,10 +155114,19 @@ unique_ptr ClientContext::PendingPreparedStatement(ClientCon if (ValidChecker::IsInvalidated(ActiveTransaction()) && statement.properties.requires_valid_transaction) { throw Exception(ErrorManager::FormatException(*this, ErrorType::INVALIDATED_TRANSACTION)); } - auto &db_config = DBConfig::GetConfig(*this); - if (db_config.options.access_mode == AccessMode::READ_ONLY && !statement.properties.read_only) { - throw Exception(StringUtil::Format("Cannot execute statement of type \"%s\" in read-only mode!", - StatementTypeToString(statement.statement_type))); + auto &transaction = MetaTransaction::Get(*this); + auto &manager = DatabaseManager::Get(*this); + for (auto &modified_database : statement.properties.modified_databases) { + auto entry = manager.GetDatabase(*this, modified_database); + if (!entry) { + throw InternalException("Database \"%s\" not found", modified_database); + } + if (entry->IsReadOnly()) { + throw Exception(StringUtil::Format( + "Cannot execute statement of type \"%s\" on database \"%s\" which is attached in read-only mode!", + StatementTypeToString(statement.statement_type), modified_database)); + } + transaction.ModifyDatabase(entry); } // bind the bound values before execution @@ -146125,7 +155135,13 @@ unique_ptr ClientContext::PendingPreparedStatement(ClientCon active_query->executor = make_unique(*this); auto &executor = *active_query->executor; if (config.enable_progress_bar) { - active_query->progress_bar = make_unique(executor, config.wait_time, config.print_progress_bar); + progress_bar_display_create_func_t display_create_func = nullptr; + if (config.print_progress_bar) { + // If a custom display is set, use that, otherwise just use the default + display_create_func = + config.display_create_func ? config.display_create_func : ProgressBar::DefaultProgressBarDisplay; + } + active_query->progress_bar = make_unique(executor, config.wait_time, display_create_func); active_query->progress_bar->Start(); query_progress = 0; } @@ -146137,7 +155153,7 @@ unique_ptr ClientContext::PendingPreparedStatement(ClientCon config.result_collector ? config.result_collector : PhysicalResultCollector::GetResultCollector; collector = get_method(*this, statement); D_ASSERT(collector->type == PhysicalOperatorType::RESULT_COLLECTOR); - executor.Initialize(move(collector)); + executor.Initialize(std::move(collector)); } else { executor.Initialize(statement.plan.get()); } @@ -146145,8 +155161,9 @@ unique_ptr ClientContext::PendingPreparedStatement(ClientCon D_ASSERT(types == statement.types); D_ASSERT(!active_query->open_result); - auto pending_result = make_unique(shared_from_this(), *statement_p, move(types), stream_result); - active_query->prepared = move(statement_p); + auto pending_result = + make_unique(shared_from_this(), *statement_p, std::move(types), stream_result); + active_query->prepared = std::move(statement_p); active_query->open_result = pending_result.get(); return pending_result; } @@ -146195,7 +155212,7 @@ vector> ClientContext::ParseStatementsInternal(ClientCo PragmaHandler handler(*this); handler.HandlePragmaStatements(lock, parser.statements); - return move(parser.statements); + return std::move(parser.statements); } void ClientContext::HandlePragmaStatements(vector> &statements) { @@ -146216,14 +155233,14 @@ unique_ptr ClientContext::ExtractPlan(const string &query) { unique_ptr plan; RunFunctionInTransactionInternal(*lock, [&]() { Planner planner(*this); - planner.CreatePlan(move(statements[0])); + planner.CreatePlan(std::move(statements[0])); D_ASSERT(planner.plan); - plan = move(planner.plan); + plan = std::move(planner.plan); if (config.enable_optimizer) { Optimizer optimizer(*planner.binder, *this); - plan = optimizer.Optimize(move(plan)); + plan = optimizer.Optimize(std::move(plan)); } ColumnBindingResolver resolver; @@ -146238,13 +155255,15 @@ unique_ptr ClientContext::ExtractPlan(const string &query) { unique_ptr ClientContext::PrepareInternal(ClientContextLock &lock, unique_ptr statement) { auto n_param = statement->n_param; + auto named_param_map = std::move(statement->named_param_map); auto statement_query = statement->query; shared_ptr prepared_data; auto unbound_statement = statement->Copy(); RunFunctionInTransactionInternal( - lock, [&]() { prepared_data = CreatePreparedStatement(lock, statement_query, move(statement)); }, false); - prepared_data->unbound_statement = move(unbound_statement); - return make_unique(shared_from_this(), move(prepared_data), move(statement_query), n_param); + lock, [&]() { prepared_data = CreatePreparedStatement(lock, statement_query, std::move(statement)); }, false); + prepared_data->unbound_statement = std::move(unbound_statement); + return make_unique(shared_from_this(), std::move(prepared_data), std::move(statement_query), + n_param, std::move(named_param_map)); } unique_ptr ClientContext::Prepare(unique_ptr statement) { @@ -146252,7 +155271,7 @@ unique_ptr ClientContext::Prepare(unique_ptr st // prepare the query try { InitialCleanup(*lock); - return PrepareInternal(*lock, move(statement)); + return PrepareInternal(*lock, std::move(statement)); } catch (const Exception &ex) { return make_unique(PreservedError(ex)); } catch (std::exception &ex) { @@ -146274,7 +155293,7 @@ unique_ptr ClientContext::Prepare(const string &query) { if (statements.size() > 1) { throw Exception("Cannot prepare multiple statements at once!"); } - return PrepareInternal(*lock, move(statements[0])); + return PrepareInternal(*lock, std::move(statements[0])); } catch (const Exception &ex) { return make_unique(PreservedError(ex)); } catch (std::exception &ex) { @@ -146324,7 +155343,7 @@ unique_ptr ClientContext::PendingStatementInternal(ClientCon unique_ptr statement, PendingQueryParameters parameters) { // prepare the query for execution - auto prepared = CreatePreparedStatement(lock, query, move(statement), parameters.parameters); + auto prepared = CreatePreparedStatement(lock, query, std::move(statement), parameters.parameters); if (prepared->properties.parameter_count > 0 && !parameters.parameters) { string error_message = StringUtil::Format("Expected %lld parameters, but none were supplied", prepared->properties.parameter_count); @@ -146334,7 +155353,7 @@ unique_ptr ClientContext::PendingStatementInternal(ClientCon return make_unique(PreservedError("Not all parameters were bound")); } // execute the prepared statement - return PendingPreparedStatement(lock, move(prepared), parameters); + return PendingPreparedStatement(lock, std::move(prepared), parameters); } unique_ptr ClientContext::RunStatementInternal(ClientContextLock &lock, const string &query, @@ -146342,7 +155361,7 @@ unique_ptr ClientContext::RunStatementInternal(ClientContextLock &l bool allow_stream_result, bool verify) { PendingQueryParameters parameters; parameters.allow_stream_result = allow_stream_result; - auto pending = PendingQueryInternal(lock, move(statement), parameters, verify); + auto pending = PendingQueryInternal(lock, std::move(statement), parameters, verify); if (pending->HasError()) { return make_unique(pending->GetErrorObject()); } @@ -146370,7 +155389,7 @@ unique_ptr ClientContext::PendingStatementOrPreparedStatemen // in case this is a select query, we verify the original statement PreservedError error; try { - error = VerifyQuery(lock, query, move(statement)); + error = VerifyQuery(lock, query, std::move(statement)); } catch (const Exception &ex) { error = PreservedError(ex); } catch (std::exception &ex) { @@ -146380,9 +155399,10 @@ unique_ptr ClientContext::PendingStatementOrPreparedStatemen // error in verifying query return make_unique(error); } - statement = move(copied_statement); + statement = std::move(copied_statement); break; } + case StatementType::COPY_STATEMENT: case StatementType::INSERT_STATEMENT: case StatementType::DELETE_STATEMENT: case StatementType::UPDATE_STATEMENT: { @@ -146399,15 +155419,15 @@ unique_ptr ClientContext::PendingStatementOrPreparedStatemen // error in verifying query return make_unique(error); } - statement = move(parser.statements[0]); + statement = std::move(parser.statements[0]); break; } default: - statement = move(copied_statement); + statement = std::move(copied_statement); break; } } - return PendingStatementOrPreparedStatement(lock, query, move(statement), prepared, parameters); + return PendingStatementOrPreparedStatement(lock, query, std::move(statement), prepared, parameters); } unique_ptr ClientContext::PendingStatementOrPreparedStatement( @@ -146431,18 +155451,23 @@ unique_ptr ClientContext::PendingStatementOrPreparedStatemen // start the profiler auto &profiler = QueryProfiler::Get(*this); profiler.StartQuery(query, IsExplainAnalyze(statement ? statement.get() : prepared->unbound_statement.get())); + + if (IsExplainAnalyze(statement ? statement.get() : prepared->unbound_statement.get())) { + client_data->http_stats = make_unique(); + } + bool invalidate_query = true; try { if (statement) { - result = PendingStatementInternal(lock, query, move(statement), parameters); + result = PendingStatementInternal(lock, query, std::move(statement), parameters); } else { if (prepared->RequireRebind(*this, *parameters.parameters)) { // catalog was modified: rebind the statement before execution auto new_prepared = CreatePreparedStatement(lock, query, prepared->unbound_statement->Copy(), parameters.parameters); D_ASSERT(new_prepared->properties.bound_all_parameters); - new_prepared->unbound_statement = move(prepared->unbound_statement); - prepared = move(new_prepared); + new_prepared->unbound_statement = std::move(prepared->unbound_statement); + prepared = std::move(new_prepared); prepared->properties.bound_all_parameters = false; } result = PendingPreparedStatement(lock, prepared, parameters); @@ -146497,7 +155522,7 @@ void ClientContext::LogQueryInternal(ClientContextLock &, const string &query) { } unique_ptr ClientContext::Query(unique_ptr statement, bool allow_stream_result) { - auto pending_query = PendingQuery(move(statement), allow_stream_result); + auto pending_query = PendingQuery(std::move(statement), allow_stream_result); if (pending_query->HasError()) { return make_unique(pending_query->GetErrorObject()); } @@ -146510,15 +155535,15 @@ unique_ptr ClientContext::Query(const string &query, bool allow_str PreservedError error; vector> statements; if (!ParseStatements(*lock, query, statements, error)) { - return make_unique(move(error)); + return make_unique(std::move(error)); } if (statements.empty()) { // no statements, return empty successful result StatementProperties properties; vector names; auto collection = make_unique(Allocator::DefaultAllocator()); - return make_unique(StatementType::INVALID_STATEMENT, properties, move(names), - move(collection), GetClientProperties()); + return make_unique(StatementType::INVALID_STATEMENT, properties, std::move(names), + std::move(collection), GetClientProperties()); } unique_ptr result; @@ -146528,7 +155553,7 @@ unique_ptr ClientContext::Query(const string &query, bool allow_str bool is_last_statement = i + 1 == statements.size(); PendingQueryParameters parameters; parameters.allow_stream_result = allow_stream_result && is_last_statement; - auto pending_query = PendingQueryInternal(*lock, move(statement), parameters); + auto pending_query = PendingQueryInternal(*lock, std::move(statement), parameters); unique_ptr current_result; if (pending_query->HasError()) { current_result = make_unique(pending_query->GetErrorObject()); @@ -146538,11 +155563,11 @@ unique_ptr ClientContext::Query(const string &query, bool allow_str // now append the result to the list of results if (!last_result) { // first result of the query - result = move(current_result); + result = std::move(current_result); last_result = result.get(); } else { // later results; attach to the result chain - last_result->next = move(current_result); + last_result->next = std::move(current_result); last_result = last_result->next.get(); } } @@ -146571,14 +155596,14 @@ unique_ptr ClientContext::PendingQuery(const string &query, PreservedError error; vector> statements; if (!ParseStatements(*lock, query, statements, error)) { - return make_unique(move(error)); + return make_unique(std::move(error)); } if (statements.size() != 1) { return make_unique(PreservedError("PendingQuery can only take a single statement")); } PendingQueryParameters parameters; parameters.allow_stream_result = allow_stream_result; - return PendingQueryInternal(*lock, move(statements[0]), parameters); + return PendingQueryInternal(*lock, std::move(statements[0]), parameters); } unique_ptr ClientContext::PendingQuery(unique_ptr statement, @@ -146586,7 +155611,7 @@ unique_ptr ClientContext::PendingQuery(unique_ptr ClientContext::PendingQueryInternal(ClientContextLock &lock, @@ -146595,9 +155620,9 @@ unique_ptr ClientContext::PendingQueryInternal(ClientContext auto query = statement->query; shared_ptr prepared; if (verify) { - return PendingStatementOrPreparedStatementInternal(lock, query, move(statement), prepared, parameters); + return PendingStatementOrPreparedStatementInternal(lock, query, std::move(statement), prepared, parameters); } else { - return PendingStatementOrPreparedStatement(lock, query, move(statement), prepared, parameters); + return PendingStatementOrPreparedStatement(lock, query, std::move(statement), prepared, parameters); } } @@ -146624,9 +155649,8 @@ void ClientContext::DisableProfiling() { void ClientContext::RegisterFunction(CreateFunctionInfo *info) { RunFunctionInTransaction([&]() { - auto &catalog = Catalog::GetCatalog(*this); - auto existing_function = (ScalarFunctionCatalogEntry *)catalog.GetEntry( - *this, CatalogType::SCALAR_FUNCTION_ENTRY, info->schema, info->name, true); + auto existing_function = + Catalog::GetEntry(*this, INVALID_CATALOG, info->schema, info->name, true); if (existing_function) { auto new_info = (CreateScalarFunctionInfo *)info; if (new_info->functions.MergeFunctionSet(existing_function->functions)) { @@ -146635,6 +155659,7 @@ void ClientContext::RegisterFunction(CreateFunctionInfo *info) { } } // create function + auto &catalog = Catalog::GetSystemCatalog(*this); catalog.CreateFunction(*this, info); }); } @@ -146684,8 +155709,7 @@ unique_ptr ClientContext::TableInfo(const string &schema_name, unique_ptr result; RunFunctionInTransaction([&]() { // obtain the table info - auto &catalog = Catalog::GetCatalog(*this); - auto table = catalog.GetEntry(*this, schema_name, table_name, true); + auto table = Catalog::GetEntry(*this, INVALID_CATALOG, schema_name, table_name, true); if (!table) { return; } @@ -146693,7 +155717,7 @@ unique_ptr ClientContext::TableInfo(const string &schema_name, result = make_unique(); result->schema = schema_name; result->table = table_name; - for (auto &column : table->columns.Logical()) { + for (auto &column : table->GetColumns().Logical()) { result->columns.emplace_back(column.Name(), column.Type()); } }); @@ -146702,18 +155726,18 @@ unique_ptr ClientContext::TableInfo(const string &schema_name, void ClientContext::Append(TableDescription &description, ColumnDataCollection &collection) { RunFunctionInTransaction([&]() { - auto &catalog = Catalog::GetCatalog(*this); - auto table_entry = catalog.GetEntry(*this, description.schema, description.table); + auto table_entry = + Catalog::GetEntry(*this, INVALID_CATALOG, description.schema, description.table); // verify that the table columns and types match up - if (description.columns.size() != table_entry->columns.PhysicalColumnCount()) { + if (description.columns.size() != table_entry->GetColumns().PhysicalColumnCount()) { throw Exception("Failed to append: table entry has different number of columns!"); } for (idx_t i = 0; i < description.columns.size(); i++) { - if (description.columns[i].Type() != table_entry->columns.GetColumn(PhysicalIndex(i)).Type()) { + if (description.columns[i].Type() != table_entry->GetColumns().GetColumn(PhysicalIndex(i)).Type()) { throw Exception("Failed to append: table entry has different number of columns!"); } } - table_entry->storage->LocalAppend(*table_entry, *this, collection); + table_entry->GetStorage().LocalAppend(*table_entry, *this, collection); }); } @@ -146727,6 +155751,8 @@ void ClientContext::TryBindRelation(Relation &relation, vector auto binder = Binder::CreateBinder(*this); auto result = relation.Bind(*binder); D_ASSERT(result.names.size() == result.types.size()); + + result_columns.reserve(result_columns.size() + result.names.size()); for (idx_t i = 0; i < result.names.size(); i++) { result_columns.emplace_back(result.names[i], result.types[i]); } @@ -146752,9 +155778,10 @@ unordered_set ClientContext::GetTableNames(const string &query) { return result; } -unique_ptr ClientContext::Execute(const shared_ptr &relation) { - auto lock = LockContext(); - InitialCleanup(*lock); +unique_ptr ClientContext::PendingQueryInternal(ClientContextLock &lock, + const shared_ptr &relation, + bool allow_stream_result) { + InitialCleanup(lock); string query; if (config.query_verification_enabled) { @@ -146765,14 +155792,32 @@ unique_ptr ClientContext::Execute(const shared_ptr &relat // verify read only statements by running a select statement auto select = make_unique(); select->node = relation->GetQueryNode(); - RunStatementInternal(*lock, query, move(select), false); + RunStatementInternal(lock, query, std::move(select), false); } } - auto &expected_columns = relation->Columns(); + auto relation_stmt = make_unique(relation); + PendingQueryParameters parameters; + parameters.allow_stream_result = allow_stream_result; + return PendingQueryInternal(lock, std::move(relation_stmt), parameters); +} + +unique_ptr ClientContext::PendingQuery(const shared_ptr &relation, + bool allow_stream_result) { + auto lock = LockContext(); + return PendingQueryInternal(*lock, relation, allow_stream_result); +} + +unique_ptr ClientContext::Execute(const shared_ptr &relation) { + auto lock = LockContext(); + auto &expected_columns = relation->Columns(); + auto pending = PendingQueryInternal(*lock, relation, false); + if (!pending->success) { + return make_unique(pending->GetErrorObject()); + } unique_ptr result; - result = RunStatementInternal(*lock, query, move(relation_stmt), false); + result = ExecutePendingQueryInternal(*lock, *pending); if (result->HasError()) { return result; } @@ -146843,6 +155888,13 @@ ClientProperties ClientContext::GetClientProperties() const { return properties; } +bool ClientContext::ExecutionIsFinished() { + if (!active_query || !active_query->executor) { + return false; + } + return active_query->executor->ExecutionIsFinished(); +} + } // namespace duckdb @@ -146854,6 +155906,20 @@ bool ClientContextFileOpener::TryGetCurrentSetting(const string &key, Value &res return context.TryGetCurrentSetting(key, result); } +ClientContext *FileOpener::TryGetClientContext(FileOpener *opener) { + if (!opener) { + return nullptr; + } + return opener->TryGetClientContext(); +} + +bool FileOpener::TryGetCurrentSetting(FileOpener *opener, const string &key, Value &result) { + if (!opener) { + return false; + } + return opener->TryGetCurrentSetting(key, result); +} + } // namespace duckdb @@ -146865,14 +155931,20 @@ bool ClientContextFileOpener::TryGetCurrentSetting(const string &key, Value &res + + + namespace duckdb { ClientData::ClientData(ClientContext &context) : catalog_search_path(make_unique(context)) { + auto &db = DatabaseInstance::GetDatabase(context); profiler = make_shared(context); query_profiler_history = make_unique(); - temporary_objects = make_shared(&Catalog::GetCatalog(context), TEMP_SCHEMA, true); + temporary_objects = make_shared(db, AttachedDatabaseType::TEMP_DATABASE); + temporary_objects->oid = DatabaseManager::Get(db).ModifyCatalog(); random_engine = make_unique(); file_opener = make_unique(context); + temporary_objects->Initialize(); } ClientData::~ClientData() { } @@ -146988,7 +156060,7 @@ PreservedError ClientContext::VerifyQuery(ClientContextLock &lock, const string statement_verifiers.emplace_back(StatementVerifier::Create(VerificationType::EXTERNAL, stmt)); } - auto original = make_unique(move(statement)); + auto original = make_unique(std::move(statement)); for (auto &verifier : statement_verifiers) { original->CheckExpressions(*verifier); } @@ -147009,7 +156081,7 @@ PreservedError ClientContext::VerifyQuery(ClientContextLock &lock, const string // Execute the original statement bool any_failed = original->Run(*this, query, [&](const string &q, unique_ptr s) { - return RunStatementInternal(lock, q, move(s), false, false); + return RunStatementInternal(lock, q, std::move(s), false, false); }); if (!any_failed) { statement_verifiers.emplace_back( @@ -147018,7 +156090,7 @@ PreservedError ClientContext::VerifyQuery(ClientContextLock &lock, const string // Execute the verifiers for (auto &verifier : statement_verifiers) { bool failed = verifier->Run(*this, query, [&](const string &q, unique_ptr s) { - return RunStatementInternal(lock, q, move(s), false, false); + return RunStatementInternal(lock, q, std::move(s), false, false); }); any_failed = any_failed || failed; } @@ -147026,11 +156098,11 @@ PreservedError ClientContext::VerifyQuery(ClientContextLock &lock, const string if (!any_failed && prepared_statement_verifier) { // If none failed, we execute the prepared statement verifier bool failed = prepared_statement_verifier->Run(*this, query, [&](const string &q, unique_ptr s) { - return RunStatementInternal(lock, q, move(s), false, false); + return RunStatementInternal(lock, q, std::move(s), false, false); }); if (!failed) { // PreparedStatementVerifier fails if it runs into a ParameterNotAllowedException, which is OK - statement_verifiers.push_back(move(prepared_statement_verifier)); + statement_verifiers.push_back(std::move(prepared_statement_verifier)); } } else { if (ValidChecker::IsInvalidated(*db)) { @@ -147045,9 +156117,9 @@ PreservedError ClientContext::VerifyQuery(ClientContextLock &lock, const string // Check explain, only if q does not already contain EXPLAIN if (original->materialized_result->success) { auto explain_q = "EXPLAIN " + query; - auto explain_stmt = make_unique(move(statement_copy_for_explain)); + auto explain_stmt = make_unique(std::move(statement_copy_for_explain)); try { - RunStatementInternal(lock, explain_q, move(explain_stmt), false, false); + RunStatementInternal(lock, explain_q, std::move(explain_stmt), false, false); } catch (std::exception &ex) { // LCOV_EXCL_START interrupted = false; return PreservedError("EXPLAIN failed but query did not (" + string(ex.what()) + ")"); @@ -147088,369 +156160,49 @@ PreservedError ClientContext::VerifyQuery(ClientContextLock &lock, const string -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/settings.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -namespace duckdb { -class ClientContext; -class DatabaseInstance; -struct DBConfig; - -struct AccessModeSetting { - static constexpr const char *Name = "access_mode"; - static constexpr const char *Description = "Access mode of the database (AUTOMATIC, READ_ONLY or READ_WRITE)"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct CheckpointThresholdSetting { - static constexpr const char *Name = "checkpoint_threshold"; - static constexpr const char *Description = - "The WAL size threshold at which to automatically trigger a checkpoint (e.g. 1GB)"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct DebugCheckpointAbort { - static constexpr const char *Name = "debug_checkpoint_abort"; - static constexpr const char *Description = - "DEBUG SETTING: trigger an abort while checkpointing for testing purposes"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct DebugForceExternal { - static constexpr const char *Name = "debug_force_external"; - static constexpr const char *Description = - "DEBUG SETTING: force out-of-core computation for operators that support it, used for testing"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; - static void SetLocal(ClientContext &context, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct DebugForceNoCrossProduct { - static constexpr const char *Name = "debug_force_no_cross_product"; - static constexpr const char *Description = - "DEBUG SETTING: Force disable cross product generation when hyper graph isn't connected, used for testing"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; - static void SetLocal(ClientContext &context, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct DebugWindowMode { - static constexpr const char *Name = "debug_window_mode"; - static constexpr const char *Description = "DEBUG SETTING: switch window mode to use"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct DefaultCollationSetting { - static constexpr const char *Name = "default_collation"; - static constexpr const char *Description = "The collation setting used when none is specified"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static void SetLocal(ClientContext &context, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct DefaultOrderSetting { - static constexpr const char *Name = "default_order"; - static constexpr const char *Description = "The order type used when none is specified (ASC or DESC)"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct DefaultNullOrderSetting { - static constexpr const char *Name = "default_null_order"; - static constexpr const char *Description = "Null ordering used when none is specified (NULLS_FIRST or NULLS_LAST)"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct DisabledOptimizersSetting { - static constexpr const char *Name = "disabled_optimizers"; - static constexpr const char *Description = "DEBUG SETTING: disable a specific set of optimizers (comma separated)"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct EnableExternalAccessSetting { - static constexpr const char *Name = "enable_external_access"; - static constexpr const char *Description = - "Allow the database to access external state (through e.g. loading/installing modules, COPY TO/FROM, CSV " - "readers, pandas replacement scans, etc)"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct EnableFSSTVectors { - static constexpr const char *Name = "enable_fsst_vectors"; - static constexpr const char *Description = - "Allow scans on FSST compressed segments to emit compressed vectors to utilize late decompression"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct AllowUnsignedExtensionsSetting { - static constexpr const char *Name = "allow_unsigned_extensions"; - static constexpr const char *Description = "Allow to load extensions with invalid or missing signatures"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct EnableObjectCacheSetting { - static constexpr const char *Name = "enable_object_cache"; - static constexpr const char *Description = "Whether or not object cache is used to cache e.g. Parquet metadata"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct EnableProfilingSetting { - static constexpr const char *Name = "enable_profiling"; - static constexpr const char *Description = - "Enables profiling, and sets the output format (JSON, QUERY_TREE, QUERY_TREE_OPTIMIZER)"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetLocal(ClientContext &context, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct EnableProgressBarSetting { - static constexpr const char *Name = "enable_progress_bar"; - static constexpr const char *Description = - "Enables the progress bar, printing progress to the terminal for long queries"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; - static void SetLocal(ClientContext &context, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct ExperimentalParallelCSVSetting { - static constexpr const char *Name = "experimental_parallel_csv"; - static constexpr const char *Description = "Whether or not to use the experimental parallel CSV reader"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct ExplainOutputSetting { - static constexpr const char *Name = "explain_output"; - static constexpr const char *Description = "Output of EXPLAIN statements (ALL, OPTIMIZED_ONLY, PHYSICAL_ONLY)"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetLocal(ClientContext &context, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct ExternalThreadsSetting { - static constexpr const char *Name = "external_threads"; - static constexpr const char *Description = "The number of external threads that work on DuckDB tasks."; - static constexpr const LogicalTypeId InputType = LogicalTypeId::BIGINT; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct FileSearchPathSetting { - static constexpr const char *Name = "file_search_path"; - static constexpr const char *Description = "A comma separated list of directories to search for input files"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetLocal(ClientContext &context, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct ForceCompressionSetting { - static constexpr const char *Name = "force_compression"; - static constexpr const char *Description = "DEBUG SETTING: forces a specific compression method to be used"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct HomeDirectorySetting { - static constexpr const char *Name = "home_directory"; - static constexpr const char *Description = "Sets the home directory used by the system"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetLocal(ClientContext &context, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct LogQueryPathSetting { - static constexpr const char *Name = "log_query_path"; - static constexpr const char *Description = - "Specifies the path to which queries should be logged (default: empty string, queries are not logged)"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetLocal(ClientContext &context, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct MaximumExpressionDepthSetting { - static constexpr const char *Name = "max_expression_depth"; - static constexpr const char *Description = - "The maximum expression depth limit in the parser. WARNING: increasing this setting and using very deep " - "expressions might lead to stack overflow errors."; - static constexpr const LogicalTypeId InputType = LogicalTypeId::UBIGINT; - static void SetLocal(ClientContext &context, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct MaximumMemorySetting { - static constexpr const char *Name = "max_memory"; - static constexpr const char *Description = "The maximum memory of the system (e.g. 1GB)"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct PasswordSetting { - static constexpr const char *Name = "password"; - static constexpr const char *Description = "The password to use. Ignored for legacy compatibility."; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct PerfectHashThresholdSetting { - static constexpr const char *Name = "perfect_ht_threshold"; - static constexpr const char *Description = "Threshold in bytes for when to use a perfect hash table (default: 12)"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::BIGINT; - static void SetLocal(ClientContext &context, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct PreserveIdentifierCase { - static constexpr const char *Name = "preserve_identifier_case"; - static constexpr const char *Description = - "Whether or not to preserve the identifier case, instead of always lowercasing all non-quoted identifiers"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; - static void SetLocal(ClientContext &context, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct PreserveInsertionOrder { - static constexpr const char *Name = "preserve_insertion_order"; - static constexpr const char *Description = - "Whether or not to preserve insertion order. If set to false the system is allowed to re-order any results " - "that do not contain ORDER BY clauses."; - static constexpr const LogicalTypeId InputType = LogicalTypeId::BOOLEAN; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct ProfilerHistorySize { - static constexpr const char *Name = "profiler_history_size"; - static constexpr const char *Description = "Sets the profiler history size"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::BIGINT; - static void SetLocal(ClientContext &context, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct ProfileOutputSetting { - static constexpr const char *Name = "profile_output"; - static constexpr const char *Description = - "The file to which profile output should be saved, or empty to print to the terminal"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetLocal(ClientContext &context, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct ProfilingModeSetting { - static constexpr const char *Name = "profiling_mode"; - static constexpr const char *Description = "The profiling mode (STANDARD or DETAILED)"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetLocal(ClientContext &context, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct ProgressBarTimeSetting { - static constexpr const char *Name = "progress_bar_time"; - static constexpr const char *Description = - "Sets the time (in milliseconds) how long a query needs to take before we start printing a progress bar"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::BIGINT; - static void SetLocal(ClientContext &context, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct SchemaSetting { - static constexpr const char *Name = "schema"; - static constexpr const char *Description = - "Sets the default search schema. Equivalent to setting search_path to a single value."; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetLocal(ClientContext &context, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct SearchPathSetting { - static constexpr const char *Name = "search_path"; - static constexpr const char *Description = - "Sets the default search search path as a comma-separated list of values"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetLocal(ClientContext &context, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; - -struct TempDirectorySetting { - static constexpr const char *Name = "temp_directory"; - static constexpr const char *Description = "Set the directory to which to write temp files"; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; -struct ThreadsSetting { - static constexpr const char *Name = "threads"; - static constexpr const char *Description = "The number of total threads used by the system."; - static constexpr const LogicalTypeId InputType = LogicalTypeId::BIGINT; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; -struct UsernameSetting { - static constexpr const char *Name = "username"; - static constexpr const char *Description = "The username to use. Ignored for legacy compatibility."; - static constexpr const LogicalTypeId InputType = LogicalTypeId::VARCHAR; - static void SetGlobal(DatabaseInstance *db, DBConfig &config, const Value ¶meter); - static Value GetSetting(ClientContext &context); -}; -} // namespace duckdb +#ifndef DUCKDB_NO_THREADS +#endif namespace duckdb { #define DUCKDB_GLOBAL(_PARAM) \ - { _PARAM::Name, _PARAM::Description, _PARAM::InputType, _PARAM::SetGlobal, nullptr, _PARAM::GetSetting } + { \ + _PARAM::Name, _PARAM::Description, _PARAM::InputType, _PARAM::SetGlobal, nullptr, _PARAM::ResetGlobal, \ + nullptr, _PARAM::GetSetting \ + } #define DUCKDB_GLOBAL_ALIAS(_ALIAS, _PARAM) \ - { _ALIAS, _PARAM::Description, _PARAM::InputType, _PARAM::SetGlobal, nullptr, _PARAM::GetSetting } + { \ + _ALIAS, _PARAM::Description, _PARAM::InputType, _PARAM::SetGlobal, nullptr, _PARAM::ResetGlobal, nullptr, \ + _PARAM::GetSetting \ + } #define DUCKDB_LOCAL(_PARAM) \ - { _PARAM::Name, _PARAM::Description, _PARAM::InputType, nullptr, _PARAM::SetLocal, _PARAM::GetSetting } + { \ + _PARAM::Name, _PARAM::Description, _PARAM::InputType, nullptr, _PARAM::SetLocal, nullptr, _PARAM::ResetLocal, \ + _PARAM::GetSetting \ + } #define DUCKDB_LOCAL_ALIAS(_ALIAS, _PARAM) \ - { _ALIAS, _PARAM::Description, _PARAM::InputType, nullptr, _PARAM::SetLocal, _PARAM::GetSetting } + { \ + _ALIAS, _PARAM::Description, _PARAM::InputType, nullptr, _PARAM::SetLocal, nullptr, _PARAM::ResetLocal, \ + _PARAM::GetSetting \ + } #define DUCKDB_GLOBAL_LOCAL(_PARAM) \ - { _PARAM::Name, _PARAM::Description, _PARAM::InputType, _PARAM::SetGlobal, _PARAM::SetLocal, _PARAM::GetSetting } + { \ + _PARAM::Name, _PARAM::Description, _PARAM::InputType, _PARAM::SetGlobal, _PARAM::SetLocal, \ + _PARAM::ResetGlobal, _PARAM::ResetLocal, _PARAM::GetSetting \ + } #define DUCKDB_GLOBAL_LOCAL_ALIAS(_ALIAS, _PARAM) \ - { _ALIAS, _PARAM::Description, _PARAM::InputType, _PARAM::SetGlobal, _PARAM::SetLocal, _PARAM::GetSetting } + { \ + _ALIAS, _PARAM::Description, _PARAM::InputType, _PARAM::SetGlobal, _PARAM::SetLocal, _PARAM::ResetGlobal, \ + _PARAM::ResetLocal, _PARAM::GetSetting \ + } #define FINAL_SETTING \ - { nullptr, nullptr, LogicalTypeId::INVALID, nullptr, nullptr, nullptr } + { nullptr, nullptr, LogicalTypeId::INVALID, nullptr, nullptr, nullptr, nullptr, nullptr } static ConfigurationOption internal_options[] = {DUCKDB_GLOBAL(AccessModeSetting), DUCKDB_GLOBAL(CheckpointThresholdSetting), @@ -147465,16 +156217,21 @@ static ConfigurationOption internal_options[] = {DUCKDB_GLOBAL(AccessModeSetting DUCKDB_GLOBAL(EnableExternalAccessSetting), DUCKDB_GLOBAL(EnableFSSTVectors), DUCKDB_GLOBAL(AllowUnsignedExtensionsSetting), + DUCKDB_LOCAL(CustomExtensionRepository), DUCKDB_GLOBAL(EnableObjectCacheSetting), + DUCKDB_GLOBAL(EnableHTTPMetadataCacheSetting), DUCKDB_LOCAL(EnableProfilingSetting), DUCKDB_LOCAL(EnableProgressBarSetting), + DUCKDB_LOCAL(EnableProgressBarPrintSetting), DUCKDB_GLOBAL(ExperimentalParallelCSVSetting), DUCKDB_LOCAL(ExplainOutputSetting), DUCKDB_GLOBAL(ExternalThreadsSetting), DUCKDB_LOCAL(FileSearchPathSetting), DUCKDB_GLOBAL(ForceCompressionSetting), + DUCKDB_GLOBAL(ForceBitpackingModeSetting), DUCKDB_LOCAL(HomeDirectorySetting), DUCKDB_LOCAL(LogQueryPathSetting), + DUCKDB_GLOBAL(ImmediateTransactionModeSetting), DUCKDB_LOCAL(MaximumExpressionDepthSetting), DUCKDB_GLOBAL(MaximumMemorySetting), DUCKDB_GLOBAL_ALIAS("memory_limit", MaximumMemorySetting), @@ -147546,29 +156303,82 @@ void DBConfig::SetOption(const ConfigurationOption &option, const Value &value) SetOption(nullptr, option, value); } +void DBConfig::SetOptionByName(const string &name, const Value &value) { + auto option = DBConfig::GetOptionByName(name); + if (option) { + SetOption(*option, value); + } else { + options.unrecognized_options[name] = value; + } +} + void DBConfig::SetOption(DatabaseInstance *db, const ConfigurationOption &option, const Value &value) { lock_guard l(config_lock); if (!option.set_global) { throw InternalException("Could not set option \"%s\" as a global option", option.name); } + D_ASSERT(option.reset_global); Value input = value.DefaultCastAs(option.parameter_type); option.set_global(db, *this, input); } +void DBConfig::ResetOption(DatabaseInstance *db, const ConfigurationOption &option) { + lock_guard l(config_lock); + if (!option.reset_global) { + throw InternalException("Could not reset option \"%s\" as a global option", option.name); + } + D_ASSERT(option.set_global); + option.reset_global(db, *this); +} + void DBConfig::SetOption(const string &name, Value value) { lock_guard l(config_lock); - options.set_variables[name] = move(value); + options.set_variables[name] = std::move(value); } -void DBConfig::AddExtensionOption(string name, string description, LogicalType parameter, - set_option_callback_t function) { - extension_parameters.insert(make_pair(move(name), ExtensionOption(move(description), move(parameter), function))); +void DBConfig::ResetOption(const string &name) { + lock_guard l(config_lock); + auto extension_option = extension_parameters.find(name); + D_ASSERT(extension_option != extension_parameters.end()); + auto &default_value = extension_option->second.default_value; + if (!default_value.IsNull()) { + // Default is not NULL, override the setting + options.set_variables[name] = default_value; + } else { + // Otherwise just remove it from the 'set_variables' map + options.set_variables.erase(name); + } +} + +void DBConfig::AddExtensionOption(const string &name, string description, LogicalType parameter, + const Value &default_value, set_option_callback_t function) { + extension_parameters.insert( + make_pair(name, ExtensionOption(std::move(description), std::move(parameter), function, default_value))); + if (!default_value.IsNull()) { + // Default value is set, insert it into the 'set_variables' list + options.set_variables[name] = default_value; + } } CastFunctionSet &DBConfig::GetCastFunctions() { return *cast_functions; } +void DBConfig::SetDefaultMaxMemory() { + auto memory = FileSystem::GetAvailableMemory(); + if (memory != DConstants::INVALID_INDEX) { + options.maximum_memory = memory * 8 / 10; + } +} + +void DBConfig::SetDefaultMaxThreads() { +#ifndef DUCKDB_NO_THREADS + options.maximum_threads = std::thread::hardware_concurrency(); +#else + options.maximum_threads = 1; +#endif +} + idx_t DBConfig::ParseMemoryLimit(const string &arg) { if (arg[0] == '-' || arg == "null" || arg == "none") { return DConstants::INVALID_INDEX; @@ -147682,7 +156492,7 @@ class ConnectionManager { connections.erase(it.first); continue; } else { - result.push_back(move(connection)); + result.push_back(std::move(connection)); } } @@ -147752,29 +156562,6 @@ class QueryRelation : public Relation { - -namespace duckdb { - -class ReadCSVRelation : public Relation { -public: - ReadCSVRelation(const std::shared_ptr &context, string csv_file, vector columns, - bool auto_detect = false, string alias = string()); - - string csv_file; - bool auto_detect; - string alias; - vector columns; - -public: - unique_ptr GetQueryNode() override; - const vector &Columns() override; - string ToString(idx_t depth) override; - string GetAlias() override; - unique_ptr GetTableRef() override; -}; - -} // namespace duckdb - //===----------------------------------------------------------------------===// // DuckDB // @@ -147792,10 +156579,11 @@ namespace duckdb { class TableFunctionRelation : public Relation { public: TableFunctionRelation(const std::shared_ptr &context, string name, vector parameters, - named_parameter_map_t named_parameters, shared_ptr input_relation_p = nullptr); + named_parameter_map_t named_parameters, shared_ptr input_relation_p = nullptr, + bool auto_init = true); TableFunctionRelation(const std::shared_ptr &context, string name, vector parameters, - shared_ptr input_relation_p = nullptr); + shared_ptr input_relation_p = nullptr, bool auto_init = true); string name; vector parameters; @@ -147810,10 +156598,40 @@ class TableFunctionRelation : public Relation { const vector &Columns() override; string ToString(idx_t depth) override; string GetAlias() override; + void AddNamedParameter(const string &name, Value argument); + +private: + void InitializeColumns(); + +private: + //! Whether or not to auto initialize the columns on construction + bool auto_initialize; +}; + +} // namespace duckdb + + +namespace duckdb { + +struct BufferedCSVReaderOptions; + +class ReadCSVRelation : public TableFunctionRelation { +public: + ReadCSVRelation(const std::shared_ptr &context, const string &csv_file, + vector columns, string alias = string()); + ReadCSVRelation(const std::shared_ptr &context, const string &csv_file, + BufferedCSVReaderOptions options, string alias = string()); + + string alias; + bool auto_detect; + +public: + string GetAlias() override; }; } // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // @@ -147984,13 +156802,41 @@ unique_ptr Connection::SendQuery(const string &query) { unique_ptr Connection::Query(const string &query) { auto result = context->Query(query, false); D_ASSERT(result->type == QueryResultType::MATERIALIZED_RESULT); - return unique_ptr_cast(move(result)); + return unique_ptr_cast(std::move(result)); +} + +DUCKDB_API string Connection::GetSubstrait(const string &query) { + vector params; + params.emplace_back(query); + auto result = TableFunction("get_substrait", params)->Execute(); + auto protobuf = result->FetchRaw()->GetValue(0, 0); + return protobuf.GetValueUnsafe().GetString(); +} + +DUCKDB_API unique_ptr Connection::FromSubstrait(const string &proto) { + vector params; + params.emplace_back(Value::BLOB_RAW(proto)); + return TableFunction("from_substrait", params)->Execute(); +} + +DUCKDB_API string Connection::GetSubstraitJSON(const string &query) { + vector params; + params.emplace_back(query); + auto result = TableFunction("get_substrait_json", params)->Execute(); + auto protobuf = result->FetchRaw()->GetValue(0, 0); + return protobuf.GetValueUnsafe().GetString(); +} + +DUCKDB_API unique_ptr Connection::FromSubstraitJSON(const string &json) { + vector params; + params.emplace_back(json); + return TableFunction("from_substrait_json", params)->Execute(); } unique_ptr Connection::Query(unique_ptr statement) { - auto result = context->Query(move(statement), false); + auto result = context->Query(std::move(statement), false); D_ASSERT(result->type == QueryResultType::MATERIALIZED_RESULT); - return unique_ptr_cast(move(result)); + return unique_ptr_cast(std::move(result)); } unique_ptr Connection::PendingQuery(const string &query, bool allow_stream_result) { @@ -147998,7 +156844,7 @@ unique_ptr Connection::PendingQuery(const string &query, boo } unique_ptr Connection::PendingQuery(unique_ptr statement, bool allow_stream_result) { - return context->PendingQuery(move(statement), allow_stream_result); + return context->PendingQuery(std::move(statement), allow_stream_result); } unique_ptr Connection::Prepare(const string &query) { @@ -148006,7 +156852,7 @@ unique_ptr Connection::Prepare(const string &query) { } unique_ptr Connection::Prepare(unique_ptr statement) { - return context->Prepare(move(statement)); + return context->Prepare(std::move(statement)); } unique_ptr Connection::QueryParamsRecursive(const string &query, vector &values) { @@ -148018,7 +156864,7 @@ unique_ptr Connection::QueryParamsRecursive(const string &query, ve } unique_ptr Connection::TableInfo(const string &table_name) { - return TableInfo(DEFAULT_SCHEMA, table_name); + return TableInfo(INVALID_SCHEMA, table_name); } unique_ptr Connection::TableInfo(const string &schema_name, const string &table_name) { @@ -148053,9 +156899,9 @@ shared_ptr Connection::Table(const string &table_name) { shared_ptr Connection::Table(const string &schema_name, const string &table_name) { auto table_info = TableInfo(schema_name, table_name); if (!table_info) { - throw Exception("Table does not exist!"); + throw CatalogException("Table '%s' does not exist!", table_name); } - return make_shared(context, move(table_info)); + return make_shared(context, std::move(table_info)); } shared_ptr Connection::View(const string &tname) { @@ -148102,14 +156948,13 @@ shared_ptr Connection::Values(const string &values, const vector Connection::ReadCSV(const string &csv_file) { BufferedCSVReaderOptions options; + return ReadCSV(csv_file, options); +} + +shared_ptr Connection::ReadCSV(const string &csv_file, BufferedCSVReaderOptions &options) { options.file_path = csv_file; options.auto_detect = true; - BufferedCSVReader reader(*context, options); - vector column_list; - for (idx_t i = 0; i < reader.sql_types.size(); i++) { - column_list.emplace_back(reader.col_names[i], reader.sql_types[i]); - } - return make_shared(context, csv_file, move(column_list), true); + return make_shared(context, csv_file, options); } shared_ptr Connection::ReadCSV(const string &csv_file, const vector &columns) { @@ -148120,9 +156965,16 @@ shared_ptr Connection::ReadCSV(const string &csv_file, const vector(context, csv_file, move(column_list)); + return make_shared(context, csv_file, std::move(column_list)); +} + +shared_ptr Connection::ReadParquet(const string &parquet_file, bool binary_as_string) { + vector params; + params.emplace_back(parquet_file); + named_parameter_map_t named_parameters({{"binary_as_string", Value::BOOLEAN(binary_as_string)}}); + return TableFunction("parquet_scan", params, named_parameters)->Alias(parquet_file); } unordered_set Connection::GetTableNames(const string &query) { @@ -148134,7 +156986,7 @@ shared_ptr Connection::RelationFromQuery(const string &query, const st } shared_ptr Connection::RelationFromQuery(unique_ptr select_stmt, const string &alias) { - return make_shared(context, move(select_stmt), alias); + return make_shared(context, std::move(select_stmt), alias); } void Connection::BeginTransaction() { @@ -148177,6 +157029,7 @@ bool Connection::HasActiveTransaction() { + //===----------------------------------------------------------------------===// // DuckDB // @@ -148228,7 +157081,7 @@ class ObjectCache { void Put(string key, shared_ptr value) { lock_guard glock(lock); - cache[key] = move(value); + cache[key] = std::move(value); } DUCKDB_API static ObjectCache &GetObjectCache(ClientContext &context); @@ -148246,10 +157099,14 @@ class ObjectCache { + + + + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/extension_helper.hpp +// duckdb/storage/magic_bytes.hpp // // //===----------------------------------------------------------------------===// @@ -148259,10 +157116,18 @@ class ObjectCache { namespace duckdb { +class FileSystem; -class ExtensionPrefixReplacementOpen : public ReplacementOpen { +enum class DataFileType : uint8_t { + FILE_DOES_NOT_EXIST, // file does not exist + DUCKDB_FILE, // duckdb database file + SQLITE_FILE, // sqlite database file + PARQUET_FILE // parquet file +}; + +class MagicBytes { public: - ExtensionPrefixReplacementOpen(); + static DataFileType CheckMagicBytes(FileSystem *fs, const string &path); }; } // namespace duckdb @@ -148278,25 +157143,19 @@ namespace duckdb { DBConfig::DBConfig() { compression_functions = make_unique(); - replacement_opens.push_back(ExtensionPrefixReplacementOpen()); cast_functions = make_unique(); error_manager = make_unique(); } -DBConfig::DBConfig(std::unordered_map &config_dict, bool read_only) { - compression_functions = make_unique(); +DBConfig::DBConfig(std::unordered_map &config_dict, bool read_only) : DBConfig::DBConfig() { if (read_only) { options.access_mode = AccessMode::READ_ONLY; } for (auto &kv : config_dict) { string key = kv.first; string val = kv.second; - auto config_property = DBConfig::GetOptionByName(key); - if (!config_property) { - throw InvalidInputException("Unrecognized configuration property \"%s\"", key); - } auto opt_val = Value(val); - DBConfig::SetOption(*config_property, opt_val); + DBConfig::SetOptionByName(key, opt_val); } } @@ -148307,38 +157166,32 @@ DatabaseInstance::DatabaseInstance() { } DatabaseInstance::~DatabaseInstance() { - if (Exception::UncaughtException()) { - return; - } - - // shutting down: attempt to checkpoint the database - // but only if we are not cleaning up as part of an exception unwind - try { - auto &storage = StorageManager::GetStorageManager(*this); - if (!storage.InMemory()) { - auto &config = storage.db.config; - if (!config.options.checkpoint_on_shutdown) { - return; - } - storage.CreateCheckpoint(true); - } - } catch (...) { - } } BufferManager &BufferManager::GetBufferManager(DatabaseInstance &db) { - return *db.GetStorageManager().buffer_manager; + return db.GetBufferManager(); +} + +BufferManager &BufferManager::GetBufferManager(AttachedDatabase &db) { + return BufferManager::GetBufferManager(db.GetDatabase()); } DatabaseInstance &DatabaseInstance::GetDatabase(ClientContext &context) { return *context.db; } -StorageManager &StorageManager::GetStorageManager(DatabaseInstance &db) { - return db.GetStorageManager(); +DatabaseManager &DatabaseInstance::GetDatabaseManager() { + if (!db_manager) { + throw InternalException("Missing DB manager"); + } + return *db_manager; +} + +Catalog &Catalog::GetSystemCatalog(DatabaseInstance &db) { + return db.GetDatabaseManager().GetSystemCatalog(); } -Catalog &Catalog::GetCatalog(DatabaseInstance &db) { +Catalog &Catalog::GetCatalog(AttachedDatabase &db) { return db.GetCatalog(); } @@ -148346,6 +157199,10 @@ FileSystem &FileSystem::GetFileSystem(DatabaseInstance &db) { return db.GetFileSystem(); } +FileSystem &FileSystem::Get(AttachedDatabase &db) { + return FileSystem::GetFileSystem(db.GetDatabase()); +} + DBConfig &DBConfig::GetConfig(DatabaseInstance &db) { return db.config; } @@ -148354,6 +157211,10 @@ ClientConfig &ClientConfig::GetConfig(ClientContext &context) { return context.config; } +DBConfig &DBConfig::Get(AttachedDatabase &db) { + return DBConfig::GetConfig(db.GetDatabase()); +} + const DBConfig &DBConfig::GetConfig(const DatabaseInstance &db) { return db.config; } @@ -148362,11 +157223,7 @@ const ClientConfig &ClientConfig::GetConfig(const ClientContext &context) { return context.config; } -TransactionManager &TransactionManager::Get(ClientContext &context) { - return TransactionManager::Get(DatabaseInstance::GetDatabase(context)); -} - -TransactionManager &TransactionManager::Get(DatabaseInstance &db) { +TransactionManager &TransactionManager::Get(AttachedDatabase &db) { return db.GetTransactionManager(); } @@ -148378,6 +157235,42 @@ ConnectionManager &ConnectionManager::Get(ClientContext &context) { return ConnectionManager::Get(DatabaseInstance::GetDatabase(context)); } +string DatabaseInstance::ExtractDatabaseType(string &path) { + // first check if there is an existing prefix + auto extension = ExtensionHelper::ExtractExtensionPrefixFromPath(path); + if (!extension.empty()) { + // path is prefixed with an extension - remove it + path = StringUtil::Replace(path, extension + ":", ""); + return extension; + } + // if there isn't - check the magic bytes of the file (if any) + auto file_type = MagicBytes::CheckMagicBytes(config.file_system.get(), path); + if (file_type == DataFileType::SQLITE_FILE) { + return "sqlite"; + } + return string(); +} + +unique_ptr DatabaseInstance::CreateAttachedDatabase(AttachInfo &info, const string &type, + AccessMode access_mode) { + unique_ptr attached_database; + if (!type.empty()) { + // find the storage extensionon database + auto entry = config.storage_extensions.find(type); + if (entry == config.storage_extensions.end()) { + throw BinderException("Unrecognized storage type \"%s\"", type); + } + // use storage extension to create the initial database + attached_database = make_unique(*this, Catalog::GetSystemCatalog(*this), *entry->second, + info.name, info, access_mode); + } else { + // check if this is an in-memory database or not + attached_database = + make_unique(*this, Catalog::GetSystemCatalog(*this), info.name, info.path, access_mode); + } + return attached_database; +} + void DatabaseInstance::Initialize(const char *database_path, DBConfig *user_config) { DBConfig default_config; DBConfig *config_ptr = &default_config; @@ -148400,15 +157293,6 @@ void DatabaseInstance::Initialize(const char *database_path, DBConfig *user_conf } else { config_ptr->options.database_path.clear(); } - - for (auto &open : config_ptr->replacement_opens) { - if (open.pre_func) { - open.data = open.pre_func(*config_ptr, open.static_data.get()); - if (open.data) { - break; - } - } - } Configure(*config_ptr); if (user_config && !user_config->options.use_temporary_directory) { @@ -148416,29 +157300,64 @@ void DatabaseInstance::Initialize(const char *database_path, DBConfig *user_conf config.options.temporary_directory = string(); } - // TODO: Support an extension here, to generate different storage managers - // depending on the DB path structure/prefix. - const string dbPath = config.options.database_path; - storage = make_unique(*this, dbPath, config.options.access_mode == AccessMode::READ_ONLY); - - catalog = make_unique(*this); - transaction_manager = make_unique(*this); + db_manager = make_unique(*this); + buffer_manager = + make_unique(*this, config.options.temporary_directory, config.options.maximum_memory); scheduler = make_unique(*this); object_cache = make_unique(); connection_manager = make_unique(); + // check if we are opening a standard DuckDB database or an extension database + auto database_type = ExtractDatabaseType(config.options.database_path); + if (!database_type.empty()) { + // we are opening an extension database, run storage_init + ExtensionHelper::StorageInit(database_type, config); + } + AttachInfo info; + info.name = AttachedDatabase::ExtractDatabaseName(config.options.database_path); + info.path = config.options.database_path; + auto attached_database = CreateAttachedDatabase(info, database_type, config.options.access_mode); + auto initial_database = attached_database.get(); + { + Connection con(*this); + con.BeginTransaction(); + db_manager->AddDatabase(*con.context, std::move(attached_database)); + con.Commit(); + } + + // initialize the system catalog + db_manager->InitializeSystemCatalog(); // initialize the database - storage->Initialize(); + initial_database->Initialize(); - // only increase thread count after storage init because we get races on catalog otherwise - scheduler->SetThreads(config.options.maximum_threads); + if (!database_type.empty()) { + // if we are opening an extension database - load the extension + ExtensionHelper::LoadExternalExtension(*this, nullptr, database_type); + } - for (auto &open : config.replacement_opens) { - if (open.post_func && open.data) { - open.post_func(*this, open.data.get()); - break; + if (!config.options.unrecognized_options.empty()) { + // check if all unrecognized options can be handled by the loaded extension(s) + for (auto &unrecognized_option : config.options.unrecognized_options) { + auto entry = config.extension_parameters.find(unrecognized_option.first); + if (entry == config.extension_parameters.end()) { + throw InvalidInputException("Unrecognized configuration property \"%s\"", unrecognized_option.first); + } + } + + // if so - set the options + Connection con(*this); + con.BeginTransaction(); + for (auto &unrecognized_option : config.options.unrecognized_options) { + auto entry = config.extension_parameters.find(unrecognized_option.first); + D_ASSERT(entry != config.extension_parameters.end()); + PhysicalSet::SetExtensionVariable(*con.context, entry->second, unrecognized_option.first, SetScope::GLOBAL, + unrecognized_option.second); } + con.Commit(); } + + // only increase thread count after storage init because we get races on catalog otherwise + scheduler->SetThreads(config.options.maximum_threads); } DuckDB::DuckDB(const char *path, DBConfig *new_config) : instance(make_shared()) { @@ -148457,16 +157376,16 @@ DuckDB::DuckDB(DatabaseInstance &instance_p) : instance(instance_p.shared_from_t DuckDB::~DuckDB() { } -StorageManager &DatabaseInstance::GetStorageManager() { - return *storage; +BufferManager &DatabaseInstance::GetBufferManager() { + return *buffer_manager; } -Catalog &DatabaseInstance::GetCatalog() { - return *catalog; +DatabaseManager &DatabaseManager::Get(DatabaseInstance &db) { + return db.GetDatabaseManager(); } -TransactionManager &DatabaseInstance::GetTransactionManager() { - return *transaction_manager; +DatabaseManager &DatabaseManager::Get(ClientContext &db) { + return DatabaseManager::Get(*db.db); } TaskScheduler &DatabaseInstance::GetScheduler() { @@ -148497,37 +157416,33 @@ Allocator &Allocator::Get(DatabaseInstance &db) { return *db.config.allocator; } +Allocator &Allocator::Get(AttachedDatabase &db) { + return Allocator::Get(db.GetDatabase()); +} + void DatabaseInstance::Configure(DBConfig &new_config) { config.options = new_config.options; if (config.options.access_mode == AccessMode::UNDEFINED) { config.options.access_mode = AccessMode::READ_WRITE; } if (new_config.file_system) { - config.file_system = move(new_config.file_system); + config.file_system = std::move(new_config.file_system); } else { config.file_system = make_unique(); } if (config.options.maximum_memory == (idx_t)-1) { - auto memory = FileSystem::GetAvailableMemory(); - if (memory != DConstants::INVALID_INDEX) { - config.options.maximum_memory = memory * 8 / 10; - } + config.SetDefaultMaxMemory(); } if (new_config.options.maximum_threads == (idx_t)-1) { -#ifndef DUCKDB_NO_THREADS - config.options.maximum_threads = std::thread::hardware_concurrency(); -#else - config.options.maximum_threads = 1; -#endif + config.SetDefaultMaxThreads(); } - config.allocator = move(new_config.allocator); + config.allocator = std::move(new_config.allocator); if (!config.allocator) { config.allocator = make_unique(); } - config.replacement_scans = move(new_config.replacement_scans); - config.replacement_opens = move(new_config.replacement_opens); - config.parser_extensions = move(new_config.parser_extensions); - config.error_manager = move(new_config.error_manager); + config.replacement_scans = std::move(new_config.replacement_scans); + config.parser_extensions = std::move(new_config.parser_extensions); + config.error_manager = std::move(new_config.error_manager); if (!config.error_manager) { config.error_manager = make_unique(); } @@ -148556,9 +157471,14 @@ idx_t DuckDB::NumberOfThreads() { return instance->NumberOfThreads(); } +bool DatabaseInstance::ExtensionIsLoaded(const std::string &name) { + return loaded_extensions.find(name) != loaded_extensions.end(); +} + bool DuckDB::ExtensionIsLoaded(const std::string &name) { - return instance->loaded_extensions.find(name) != instance->loaded_extensions.end(); + return instance->ExtensionIsLoaded(name); } + void DatabaseInstance::SetExtensionLoaded(const std::string &name) { loaded_extensions.insert(name); } @@ -148595,6 +157515,103 @@ ValidChecker &ValidChecker::Get(DatabaseInstance &db) { } } // namespace duckdb + + + + + + + +namespace duckdb { + +DatabaseManager::DatabaseManager(DatabaseInstance &db) : catalog_version(0), current_query_number(1) { + system = make_unique(db); + databases = make_unique(system->GetCatalog()); +} + +DatabaseManager::~DatabaseManager() { +} + +DatabaseManager &DatabaseManager::Get(AttachedDatabase &db) { + return DatabaseManager::Get(db.GetDatabase()); +} + +void DatabaseManager::InitializeSystemCatalog() { + system->Initialize(); +} + +AttachedDatabase *DatabaseManager::GetDatabase(ClientContext &context, const string &name) { + if (StringUtil::Lower(name) == TEMP_CATALOG) { + return context.client_data->temporary_objects.get(); + } + return (AttachedDatabase *)databases->GetEntry(context, name); +} + +void DatabaseManager::AddDatabase(ClientContext &context, unique_ptr db_instance) { + auto name = db_instance->GetName(); + db_instance->oid = ModifyCatalog(); + DependencyList dependencies; + if (default_database.empty()) { + default_database = name; + } + if (!databases->CreateEntry(context, name, std::move(db_instance), dependencies)) { + throw BinderException("Failed to attach database: database with name \"%s\" already exists", name); + } +} + +void DatabaseManager::DetachDatabase(ClientContext &context, const string &name, bool if_exists) { + if (!databases->DropEntry(context, name, false, true)) { + if (!if_exists) { + throw BinderException("Failed to detach database with name \"%s\": database not found", name); + } + } +} + +AttachedDatabase *DatabaseManager::GetDatabaseFromPath(ClientContext &context, const string &path) { + auto databases = GetDatabases(context); + for (auto db : databases) { + if (db->IsSystem()) { + continue; + } + auto &catalog = Catalog::GetCatalog(*db); + if (catalog.InMemory()) { + continue; + } + auto db_path = catalog.GetDBPath(); + if (StringUtil::CIEquals(path, db_path)) { + return db; + } + } + return nullptr; +} + +const string &DatabaseManager::GetDefaultDatabase(ClientContext &context) { + auto &config = ClientData::Get(context); + auto &default_entry = config.catalog_search_path->GetDefault(); + if (IsInvalidCatalog(default_entry.catalog)) { + auto &result = DatabaseManager::Get(context).default_database; + if (result.empty()) { + throw InternalException("Calling DatabaseManager::GetDefaultDatabase with no default database set"); + } + return result; + } + return default_entry.catalog; +} + +vector DatabaseManager::GetDatabases(ClientContext &context) { + vector result; + databases->Scan(context, [&](CatalogEntry *entry) { result.push_back((AttachedDatabase *)entry); }); + result.push_back(system.get()); + result.push_back(context.client_data->temporary_objects.get()); + return result; +} + +Catalog &DatabaseManager::GetSystemCatalog() { + D_ASSERT(system); + return system->GetCatalog(); +} + +} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // @@ -148647,6 +157664,10 @@ string GetDBAbsolutePath(const string &database) { // this is a memory db, just return it. return database; } + if (!ExtensionHelper::ExtractExtensionPrefixFromPath(database).empty()) { + // this database path is handled by a replacement open and is not a file path + return database; + } if (FileSystem::IsPathAbsolute(database)) { return database; } @@ -148660,9 +157681,9 @@ shared_ptr DBInstanceCache::GetInstanceInternal(const string &database, db_instance = db_instances[abs_database_path].lock(); if (db_instance) { if (db_instance->instance->config != config) { - throw duckdb::Exception(ExceptionType::CONNECTION, - "Can't open a connection to same database file with a different configuration " - "than existing connections"); + throw duckdb::ConnectionException( + "Can't open a connection to same database file with a different configuration " + "than existing connections"); } } else { // clean-up @@ -148772,7 +157793,7 @@ string ErrorManager::InvalidUnicodeError(const string &input, const string &cont } void ErrorManager::AddCustomError(ErrorType type, string new_error) { - custom_errors.insert(make_pair(type, move(new_error))); + custom_errors.insert(make_pair(type, std::move(new_error))); } ErrorManager &ErrorManager::Get(ClientContext &context) { @@ -148790,6 +157811,7 @@ namespace duckdb { static ExtensionAlias internal_aliases[] = {{"http", "httpfs"}, // httpfs {"https", "httpfs"}, + {"md", "motherduck"}, // motherduck {"s3", "httpfs"}, {"postgres", "postgres_scanner"}, // postgres {"sqlite", "sqlite_scanner"}, // sqlite @@ -148898,6 +157920,11 @@ string ExtensionHelper::ApplyExtensionAlias(string extension_name) { #include "inet-extension.hpp" #endif +// Load the generated header file containing our list of extension headers +#if defined(OOTE_HEADERS_AVAILABLE) && OOTE_HEADERS_AVAILABLE +#include "extension_oote_loader.hpp" +#endif + namespace duckdb { //===--------------------------------------------------------------------===// @@ -148912,6 +157939,7 @@ static DefaultExtension internal_extensions[] = { {"httpfs", "Adds support for reading and writing files over a HTTP(S) connection", HTTPFS_STATICALLY_LOADED}, {"json", "Adds support for JSON operations", JSON_STATICALLY_LOADED}, {"jemalloc", "Overwrites system allocator with JEMalloc", JEMALLOC_STATICALLY_LOADED}, + {"motherduck", "Enables motherduck integration with the system", false}, {"sqlite_scanner", "Adds support for reading SQLite database files", false}, {"postgres_scanner", "Adds support for reading from a Postgres database", false}, {"inet", "Adds support for IP-related data types and functions", false}, @@ -148938,6 +157966,12 @@ void ExtensionHelper::LoadAllExtensions(DuckDB &db) { for (auto &ext : extensions) { LoadExtensionInternal(db, ext, true); } + +#if defined(OOTE_HEADERS_AVAILABLE) && OOTE_HEADERS_AVAILABLE + for (auto &ext : OOT_EXTENSIONS) { + LoadExtensionInternal(db, ext, true); + } +#endif } ExtensionLoadResult ExtensionHelper::LoadExtension(DuckDB &db, const std::string &extension) { @@ -149046,7 +158080,12 @@ ExtensionLoadResult ExtensionHelper::LoadExtensionInternal(DuckDB &db, const std return ExtensionLoadResult::NOT_LOADED; #endif } else { - // unknown extension + +#if defined(OOTE_HEADERS_AVAILABLE) && OOTE_HEADERS_AVAILABLE + if (TryLoadLinkedExtension(db, extension)) { + return ExtensionLoadResult::LOADED_EXTENSION; + } +#endif return ExtensionLoadResult::EXTENSION_UNKNOWN; } return ExtensionLoadResult::LOADED_EXTENSION; @@ -149397,8 +158436,10 @@ const vector ExtensionHelper::GetPublicKeys() { #define CPPHTTPLIB_RECV_FLAGS 0 #endif -#ifndef CPPHTTPLIB_SEND_FLAGS +#ifndef MSG_NOSIGNAL #define CPPHTTPLIB_SEND_FLAGS 0 +#else +#define CPPHTTPLIB_SEND_FLAGS MSG_NOSIGNAL #endif #ifndef CPPHTTPLIB_LISTEN_BACKLOG @@ -157538,6 +166579,25 @@ string ExtensionHelper::ExtensionDirectory(ClientContext &context) { return local_path; } +bool ExtensionHelper::CreateSuggestions(const string &extension_name, string &message) { + vector candidates; + for (idx_t ext_count = ExtensionHelper::DefaultExtensionCount(), i = 0; i < ext_count; i++) { + candidates.emplace_back(ExtensionHelper::GetDefaultExtension(i).name); + } + for (idx_t ext_count = ExtensionHelper::ExtensionAliasCount(), i = 0; i < ext_count; i++) { + candidates.emplace_back(ExtensionHelper::GetExtensionAlias(i).alias); + } + auto closest_extensions = StringUtil::TopNLevenshtein(candidates, extension_name); + message = StringUtil::CandidatesMessage(closest_extensions, "Candidate extensions"); + for (auto &closest : closest_extensions) { + if (closest == extension_name) { + message = "Extension \"" + extension_name + "\" is an existing extension.\n"; + return true; + } + } + return false; +} + void ExtensionHelper::InstallExtension(ClientContext &context, const string &extension, bool force_install) { auto &config = DBConfig::GetConfig(context); if (!config.options.enable_external_access) { @@ -157583,7 +166643,12 @@ void ExtensionHelper::InstallExtension(ClientContext &context, const string &ext #ifdef DISABLE_DUCKDB_REMOTE_INSTALL throw BinderException("Remote extension installation is disabled through configuration"); #else - string url_template = "http://extensions.duckdb.org/${REVISION}/${PLATFORM}/${NAME}.duckdb_extension.gz"; + + string default_endpoint = "http://extensions.duckdb.org"; + string versioned_path = "/${REVISION}/${PLATFORM}/${NAME}.duckdb_extension.gz"; + string &custom_endpoint = ClientConfig::GetConfig(context).custom_extension_repo; + string &endpoint = !custom_endpoint.empty() ? custom_endpoint : default_endpoint; + string url_template = endpoint + versioned_path; if (is_http_url) { url_template = extension; @@ -157615,21 +166680,10 @@ void ExtensionHelper::InstallExtension(ClientContext &context, const string &ext if (!res || res->status != 200) { // create suggestions - vector candidates; - for (idx_t ext_count = ExtensionHelper::DefaultExtensionCount(), i = 0; i < ext_count; i++) { - candidates.emplace_back(ExtensionHelper::GetDefaultExtension(i).name); - } - for (idx_t ext_count = ExtensionHelper::ExtensionAliasCount(), i = 0; i < ext_count; i++) { - candidates.emplace_back(ExtensionHelper::GetExtensionAlias(i).alias); - } - auto closest_extensions = StringUtil::TopNLevenshtein(candidates, extension_name); - auto message = StringUtil::CandidatesMessage(closest_extensions, "Candidate extensions"); - for (auto &closest : closest_extensions) { - if (closest == extension_name) { - message = "Extension \"" + extension_name + "\" is an existing extension.\n"; - message += "Are you using a development build? In this case, extensions might not (yet) be uploaded."; - break; - } + string message; + auto exact_match = ExtensionHelper::CreateSuggestions(extension_name, message); + if (exact_match) { + message += "\nAre you using a development build? In this case, extensions might not (yet) be uploaded."; } throw IOException("Failed to download extension \"%s\" at URL \"%s%s\"\n%s", extension_name, url_base, url_local_part, message); @@ -157699,7 +166753,6 @@ inline std::string GetDLError(void) { - // LICENSE_CHANGE_BEGIN // The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #12 // See the end of this file for a list @@ -157739,6 +166792,7 @@ namespace duckdb { //===--------------------------------------------------------------------===// typedef void (*ext_init_fun_t)(DatabaseInstance &); typedef const char *(*ext_version_fun_t)(void); +typedef void (*ext_storage_init_t)(DBConfig &); template static T LoadFunctionFromDLL(void *dll, const string &function_name, const string &filename) { @@ -157769,9 +166823,14 @@ ExtensionInitResult ExtensionHelper::InitialLoad(DBConfig &config, FileOpener *o } if (!fs.FileExists(filename)) { - throw IOException("Extension \"%s\" not found", filename); + string message; + bool exact_match = ExtensionHelper::CreateSuggestions(extension, message); + if (exact_match) { + message += "\nInstall it first using \"INSTALL " + extension + "\"."; + } + throw IOException("Extension \"%s\" not found.\n%s", filename, message); } - { + if (!config.options.allow_unsigned_extensions) { auto handle = fs.OpenFile(filename, FileFlags::FILE_FLAGS_READ); // signature is the last 265 bytes of the file @@ -157797,7 +166856,7 @@ ExtensionInitResult ExtensionHelper::InitialLoad(DBConfig &config, FileOpener *o break; } } - if (!any_valid && !config.options.allow_unsigned_extensions) { + if (!any_valid) { throw IOException(config.error_manager->FormatException(ErrorType::UNSIGNED_EXTENSION, filename)); } } @@ -157843,10 +166902,13 @@ ExtensionInitResult ExtensionHelper::InitialLoad(DBConfig &config, FileOpener *o return res; } -void ExtensionHelper::LoadExternalExtension(ClientContext &context, const string &extension) { - auto &db = DatabaseInstance::GetDatabase(context); +void ExtensionHelper::LoadExternalExtension(DatabaseInstance &db, FileOpener *opener, const string &extension) { + auto &loaded_extensions = db.LoadedExtensions(); + if (loaded_extensions.find(extension) != loaded_extensions.end()) { + return; + } - auto res = InitialLoad(DBConfig::GetConfig(context), FileSystem::GetFileOpener(context), extension); + auto res = InitialLoad(DBConfig::GetConfig(db), opener, extension); auto init_fun_name = res.basename + "_init"; ext_init_fun_t init_fun; @@ -157859,102 +166921,58 @@ void ExtensionHelper::LoadExternalExtension(ClientContext &context, const string init_fun_name, res.filename, e.what()); } - DatabaseInstance::GetDatabase(context).SetExtensionLoaded(extension); + db.SetExtensionLoaded(extension); } -unique_ptr ExtensionHelper::ReplacementOpenPre(const string &extension, DBConfig &config) { - - auto res = InitialLoad(config, nullptr, extension); // TODO opener - auto init_fun_name = res.basename + "_replacement_open_pre"; - - replacement_open_pre_t open_pre_fun; - open_pre_fun = LoadFunctionFromDLL(res.lib_hdl, init_fun_name, res.filename); - - try { - return (*open_pre_fun)(config, nullptr); - } catch (std::exception &e) { - throw InvalidInputException("Initialization function \"%s\" from file \"%s\" threw an exception: \"%s\"", - init_fun_name, res.filename, e.what()); - } +void ExtensionHelper::LoadExternalExtension(ClientContext &context, const string &extension) { + LoadExternalExtension(DatabaseInstance::GetDatabase(context), FileSystem::GetFileOpener(context), extension); } -void ExtensionHelper::ReplacementOpenPost(ClientContext &context, const string &extension, DatabaseInstance &instance, - ReplacementOpenData *open_data) { - auto res = InitialLoad(DBConfig::GetConfig(context), FileSystem::GetFileOpener(context), extension); - auto init_fun_name = res.basename + "_replacement_open_post"; +void ExtensionHelper::StorageInit(string &extension, DBConfig &config) { + extension = ExtensionHelper::ApplyExtensionAlias(extension); + auto res = InitialLoad(config, nullptr, extension); // TODO opener + auto storage_fun_name = res.basename + "_storage_init"; - replacement_open_post_t open_post_fun; - open_post_fun = LoadFunctionFromDLL(res.lib_hdl, init_fun_name, res.filename); + ext_storage_init_t storage_init_fun; + storage_init_fun = LoadFunctionFromDLL(res.lib_hdl, storage_fun_name, res.filename); try { - (*open_post_fun)(instance, open_data); + (*storage_init_fun)(config); } catch (std::exception &e) { - throw InvalidInputException("Initialization function \"%s\" from file \"%s\" threw an exception: \"%s\"", - init_fun_name, res.filename, e.what()); + throw InvalidInputException( + "Storage initialization function \"%s\" from file \"%s\" threw an exception: \"%s\"", storage_fun_name, + res.filename, e.what()); } } -} // namespace duckdb - - -namespace duckdb { - -Extension::~Extension() { -} - -} // namespace duckdb - - - - - -namespace duckdb { - -struct ExtensionPrefixOpenData : public ReplacementOpenData { - ExtensionPrefixOpenData(string extension, string path, unique_ptr data) - : extension(move(extension)), path(move(path)), data(move(data)) { - } - string extension; - string path; - unique_ptr data; -}; - -static unique_ptr ExtensionPrefixPreOpen(DBConfig &config, ReplacementOpenStaticData *) { - auto path = config.options.database_path; +string ExtensionHelper::ExtractExtensionPrefixFromPath(const string &path) { auto first_colon = path.find(':'); if (first_colon == string::npos || first_colon < 2) { // needs to be at least two characters because windows c: ... - return nullptr; + return ""; } auto extension = path.substr(0, first_colon); + + if (path.substr(first_colon, 3) == "://") { + // these are not extensions + return ""; + } + D_ASSERT(extension.size() > 1); // needs to be alphanumeric for (auto &ch : extension) { if (!isalnum(ch) && ch != '_') { - return nullptr; + return ""; } } - auto extension_data = ExtensionHelper::ReplacementOpenPre(extension, config); - if (extension_data) { - return make_unique(extension, path, move(extension_data)); - } - return nullptr; + return extension; } -static void ExtensionPrefixPostOpen(DatabaseInstance &instance, ReplacementOpenData *open_data) { - if (!open_data) { - return; - } - D_ASSERT(open_data); - auto prefix_open_data = (ExtensionPrefixOpenData *)open_data; +} // namespace duckdb - Connection con(instance); - ExtensionHelper::LoadExternalExtension(*con.context, prefix_open_data->extension); - ExtensionHelper::ReplacementOpenPost(*con.context, prefix_open_data->extension, instance, - prefix_open_data->data.get()); -} -ExtensionPrefixReplacementOpen::ExtensionPrefixReplacementOpen() - : ReplacementOpen(ExtensionPrefixPreOpen, ExtensionPrefixPostOpen) { +namespace duckdb { + +Extension::~Extension() { } } // namespace duckdb @@ -157962,18 +166980,19 @@ ExtensionPrefixReplacementOpen::ExtensionPrefixReplacementOpen() + namespace duckdb { MaterializedQueryResult::MaterializedQueryResult(StatementType statement_type, StatementProperties properties, vector names_p, unique_ptr collection_p, ClientProperties client_properties) - : QueryResult(QueryResultType::MATERIALIZED_RESULT, statement_type, properties, collection_p->Types(), - move(names_p), move(client_properties)), - collection(move(collection_p)), scan_initialized(false) { + : QueryResult(QueryResultType::MATERIALIZED_RESULT, statement_type, std::move(properties), collection_p->Types(), + std::move(names_p), std::move(client_properties)), + collection(std::move(collection_p)), scan_initialized(false) { } MaterializedQueryResult::MaterializedQueryResult(PreservedError error) - : QueryResult(QueryResultType::MATERIALIZED_RESULT, move(error)), scan_initialized(false) { + : QueryResult(QueryResultType::MATERIALIZED_RESULT, std::move(error)), scan_initialized(false) { } string MaterializedQueryResult::ToString() { @@ -157999,6 +167018,17 @@ string MaterializedQueryResult::ToString() { return result; } +string MaterializedQueryResult::ToBox(ClientContext &context, const BoxRendererConfig &config) { + if (!success) { + return GetError() + "\n"; + } + if (!collection) { + return "Internal error - result was successful but there was no collection"; + } + BoxRenderer renderer(config); + return renderer.ToString(context, names, Collection()); +} + Value MaterializedQueryResult::GetValue(idx_t column, idx_t index) { if (!row_collection) { row_collection = make_unique(collection->GetRows()); @@ -158052,13 +167082,13 @@ namespace duckdb { PendingQueryResult::PendingQueryResult(shared_ptr context_p, PreparedStatementData &statement, vector types_p, bool allow_stream_result) - : BaseQueryResult(QueryResultType::PENDING_RESULT, statement.statement_type, statement.properties, move(types_p), - statement.names), - context(move(context_p)), allow_stream_result(allow_stream_result) { + : BaseQueryResult(QueryResultType::PENDING_RESULT, statement.statement_type, statement.properties, + std::move(types_p), statement.names), + context(std::move(context_p)), allow_stream_result(allow_stream_result) { } PendingQueryResult::PendingQueryResult(PreservedError error) - : BaseQueryResult(QueryResultType::PENDING_RESULT, move(error)) { + : BaseQueryResult(QueryResultType::PENDING_RESULT, std::move(error)) { } PendingQueryResult::~PendingQueryResult() { @@ -158129,12 +167159,13 @@ void PendingQueryResult::Close() { namespace duckdb { PreparedStatement::PreparedStatement(shared_ptr context, shared_ptr data_p, - string query, idx_t n_param) - : context(move(context)), data(move(data_p)), query(move(query)), success(true), n_param(n_param) { + string query, idx_t n_param, case_insensitive_map_t named_param_pam_p) + : context(std::move(context)), data(std::move(data_p)), query(std::move(query)), success(true), n_param(n_param), + named_param_map(std::move(named_param_pam_p)) { D_ASSERT(data || !success); } -PreparedStatement::PreparedStatement(PreservedError error) : context(nullptr), success(false), error(move(error)) { +PreparedStatement::PreparedStatement(PreservedError error) : context(nullptr), success(false), error(std::move(error)) { } PreparedStatement::~PreparedStatement() { @@ -158174,6 +167205,19 @@ const vector &PreparedStatement::GetNames() { return data->names; } +vector PreparedStatement::GetExpectedParameterTypes() const { + D_ASSERT(data); + vector expected_types(data->value_map.size()); + for (auto &it : data->value_map) { + D_ASSERT(it.first >= 1); + idx_t param_index = it.first - 1; + D_ASSERT(param_index < expected_types.size()); + D_ASSERT(it.second); + expected_types[param_index] = it.second->value.type(); + } + return expected_types; +} + unique_ptr PreparedStatement::Execute(vector &values, bool allow_stream_result) { auto pending = PendingQuery(values, allow_stream_result); if (pending->HasError()) { @@ -158225,8 +167269,7 @@ bool PreparedStatementData::RequireRebind(ClientContext &context, const vector #include @@ -158368,7 +167412,7 @@ void QueryProfiler::StartQuery(string query, bool is_explain_analyze, bool start return; } this->running = true; - this->query = move(query); + this->query = std::move(query); tree_map.clear(); root = nullptr; phase_timings.clear(); @@ -158613,7 +167657,7 @@ void QueryProfiler::Flush(OperatorProfiler &profiler) { if (int(entry->second->info.executors_info.size()) <= info_id) { entry->second->info.executors_info.resize(info_id + 1); } - entry->second->info.executors_info[info_id] = move(info); + entry->second->info.executors_info[info_id] = std::move(info); } } profiler.timings.clear(); @@ -158674,10 +167718,38 @@ void QueryProfiler::QueryTreeToStream(std::ostream &ss) const { ss << "│└───────────────────────────────────┘│\n"; ss << "└─────────────────────────────────────┘\n"; ss << StringUtil::Replace(query, "\n", " ") + "\n"; - if (query.empty()) { + + // checking the tree to ensure the query is really empty + // the query string is empty when a logical plan is deserialized + if (query.empty() && !root) { return; } + if (context.client_data->http_stats && !context.client_data->http_stats->IsEmpty()) { + string read = + "in: " + StringUtil::BytesToHumanReadableString(context.client_data->http_stats->total_bytes_received); + string written = + "out: " + StringUtil::BytesToHumanReadableString(context.client_data->http_stats->total_bytes_sent); + string head = "#HEAD: " + to_string(context.client_data->http_stats->head_count); + string get = "#GET: " + to_string(context.client_data->http_stats->get_count); + string put = "#PUT: " + to_string(context.client_data->http_stats->put_count); + string post = "#POST: " + to_string(context.client_data->http_stats->post_count); + + constexpr idx_t TOTAL_BOX_WIDTH = 39; + ss << "┌─────────────────────────────────────┐\n"; + ss << "│┌───────────────────────────────────┐│\n"; + ss << "││ HTTP Stats: ││\n"; + ss << "││ ││\n"; + ss << "││" + DrawPadded(read, TOTAL_BOX_WIDTH - 4) + "││\n"; + ss << "││" + DrawPadded(written, TOTAL_BOX_WIDTH - 4) + "││\n"; + ss << "││" + DrawPadded(head, TOTAL_BOX_WIDTH - 4) + "││\n"; + ss << "││" + DrawPadded(get, TOTAL_BOX_WIDTH - 4) + "││\n"; + ss << "││" + DrawPadded(put, TOTAL_BOX_WIDTH - 4) + "││\n"; + ss << "││" + DrawPadded(post, TOTAL_BOX_WIDTH - 4) + "││\n"; + ss << "│└───────────────────────────────────┘│\n"; + ss << "└─────────────────────────────────────┘\n"; + } + constexpr idx_t TOTAL_BOX_WIDTH = 39; ss << "┌─────────────────────────────────────┐\n"; ss << "│┌───────────────────────────────────┐│\n"; @@ -158837,7 +167909,7 @@ string QueryProfiler::ToJSON() const { if (!IsEnabled()) { return "{ \"result\": \"disabled\" }\n"; } - if (query.empty()) { + if (query.empty() && !root) { return "{ \"result\": \"empty\" }\n"; } if (!root) { @@ -158897,7 +167969,7 @@ unique_ptr QueryProfiler::CreateTree(PhysicalOperator * auto children = root->GetChildren(); for (auto &child : children) { auto child_node = CreateTree(child, depth + 1); - node->children.push_back(move(child_node)); + node->children.push_back(std::move(child_node)); } return node; } @@ -158949,7 +168021,7 @@ void ExpressionInfo::ExtractExpressionsRecursive(unique_ptr &st expr_info->tuples_count = child->profiler.tuples_count; } expr_info->ExtractExpressionsRecursive(child); - children.push_back(move(expr_info)); + children.push_back(std::move(expr_info)); } return; } @@ -158966,7 +168038,7 @@ ExpressionRootInfo::ExpressionRootInfo(ExpressionExecutorState &state, string na sample_tuples_count(state.profiler.sample_tuples_count), tuples_count(state.profiler.tuples_count), name(state.name), time(state.profiler.time) { // Use the name of expression-tree as extra-info - extra_info = move(name); + extra_info = std::move(name); auto expression_info_p = make_unique(); // Maybe root has a function if (state.root_state->expr.expression_class == ExpressionClass::BOUND_FUNCTION) { @@ -158977,7 +168049,7 @@ ExpressionRootInfo::ExpressionRootInfo(ExpressionExecutorState &state, string na expression_info_p->tuples_count = state.root_state->profiler.tuples_count; } expression_info_p->ExtractExpressionsRecursive(state.root_state); - root = move(expression_info_p); + root = std::move(expression_info_p); } } // namespace duckdb @@ -158985,17 +168057,18 @@ ExpressionRootInfo::ExpressionRootInfo(ExpressionExecutorState &state, string na + namespace duckdb { -BaseQueryResult::BaseQueryResult(QueryResultType type, StatementType statement_type, StatementProperties properties, +BaseQueryResult::BaseQueryResult(QueryResultType type, StatementType statement_type, StatementProperties properties_p, vector types_p, vector names_p) - : type(type), statement_type(statement_type), properties(properties), types(move(types_p)), names(move(names_p)), - success(true) { + : type(type), statement_type(statement_type), properties(std::move(properties_p)), types(std::move(types_p)), + names(std::move(names_p)), success(true) { D_ASSERT(types.size() == names.size()); } BaseQueryResult::BaseQueryResult(QueryResultType type, PreservedError error) - : type(type), success(false), error(move(error)) { + : type(type), success(false), error(std::move(error)) { } BaseQueryResult::~BaseQueryResult() { @@ -159008,7 +168081,7 @@ void BaseQueryResult::ThrowError(const string &prepended_message) const { void BaseQueryResult::SetError(PreservedError error) { success = !error; - this->error = move(error); + this->error = std::move(error); } bool BaseQueryResult::HasError() const { @@ -159035,16 +168108,25 @@ idx_t BaseQueryResult::ColumnCount() { QueryResult::QueryResult(QueryResultType type, StatementType statement_type, StatementProperties properties, vector types_p, vector names_p, ClientProperties client_properties_p) - : BaseQueryResult(type, statement_type, properties, move(types_p), move(names_p)), - client_properties(move(client_properties_p)) { + : BaseQueryResult(type, statement_type, std::move(properties), std::move(types_p), std::move(names_p)), + client_properties(std::move(client_properties_p)) { } -QueryResult::QueryResult(QueryResultType type, PreservedError error) : BaseQueryResult(type, move(error)) { +QueryResult::QueryResult(QueryResultType type, PreservedError error) : BaseQueryResult(type, std::move(error)) { } QueryResult::~QueryResult() { } +const string &QueryResult::ColumnName(idx_t index) const { + D_ASSERT(index < names.size()); + return names[index]; +} + +string QueryResult::ToBox(ClientContext &context, const BoxRendererConfig &config) { + return ToString(); +} + unique_ptr QueryResult::Fetch() { auto chunk = FetchRaw(); if (!chunk) { @@ -159208,8 +168290,8 @@ namespace duckdb { AggregateRelation::AggregateRelation(shared_ptr child_p, vector> parsed_expressions) - : Relation(child_p->context, RelationType::AGGREGATE_RELATION), expressions(move(parsed_expressions)), - child(move(child_p)) { + : Relation(child_p->context, RelationType::AGGREGATE_RELATION), expressions(std::move(parsed_expressions)), + child(std::move(child_p)) { // bind the expressions context.GetContext()->TryBindRelation(*this, this->columns); } @@ -159217,8 +168299,8 @@ AggregateRelation::AggregateRelation(shared_ptr child_p, AggregateRelation::AggregateRelation(shared_ptr child_p, vector> parsed_expressions, vector> groups_p) - : Relation(child_p->context, RelationType::AGGREGATE_RELATION), expressions(move(parsed_expressions)), - groups(move(groups_p)), child(move(child_p)) { + : Relation(child_p->context, RelationType::AGGREGATE_RELATION), expressions(std::move(parsed_expressions)), + groups(std::move(groups_p)), child(std::move(child_p)) { // bind the expressions context.GetContext()->TryBindRelation(*this, this->columns); } @@ -159236,7 +168318,7 @@ unique_ptr AggregateRelation::GetQueryNode() { // child node is not a join: create a new select node and push the child as a table reference auto select = make_unique(); select->from_table = child->GetTableRef(); - result = move(select); + result = std::move(select); } D_ASSERT(result->type == QueryNodeType::SELECT_NODE); auto &select_node = (SelectNode &)*result; @@ -159249,7 +168331,7 @@ unique_ptr AggregateRelation::GetQueryNode() { select_node.groups.group_expressions.push_back(groups[i]->Copy()); grouping_set.insert(i); } - select_node.groups.grouping_sets.push_back(move(grouping_set)); + select_node.groups.grouping_sets.push_back(std::move(grouping_set)); } else { // no groups provided: automatically figure out groups (if any) select_node.aggregate_handling = AggregateHandling::FORCE_AGGREGATES; @@ -159353,8 +168435,8 @@ class CreateStatement : public SQLStatement { namespace duckdb { CreateTableRelation::CreateTableRelation(shared_ptr child_p, string schema_name, string table_name) - : Relation(child_p->context, RelationType::CREATE_TABLE_RELATION), child(move(child_p)), - schema_name(move(schema_name)), table_name(move(table_name)) { + : Relation(child_p->context, RelationType::CREATE_TABLE_RELATION), child(std::move(child_p)), + schema_name(std::move(schema_name)), table_name(std::move(table_name)) { context.GetContext()->TryBindRelation(*this, this->columns); } @@ -159366,9 +168448,9 @@ BoundStatement CreateTableRelation::Bind(Binder &binder) { auto info = make_unique(); info->schema = schema_name; info->table = table_name; - info->query = move(select); + info->query = std::move(select); info->on_conflict = OnCreateConflict::ERROR_ON_CONFLICT; - stmt.info = move(info); + stmt.info = std::move(info); return binder.Bind((SQLStatement &)stmt); } @@ -159427,15 +168509,16 @@ namespace duckdb { CreateViewRelation::CreateViewRelation(shared_ptr child_p, string view_name_p, bool replace_p, bool temporary_p) - : Relation(child_p->context, RelationType::CREATE_VIEW_RELATION), child(move(child_p)), - view_name(move(view_name_p)), replace(replace_p), temporary(temporary_p) { + : Relation(child_p->context, RelationType::CREATE_VIEW_RELATION), child(std::move(child_p)), + view_name(std::move(view_name_p)), replace(replace_p), temporary(temporary_p) { context.GetContext()->TryBindRelation(*this, this->columns); } CreateViewRelation::CreateViewRelation(shared_ptr child_p, string schema_name_p, string view_name_p, bool replace_p, bool temporary_p) - : Relation(child_p->context, RelationType::CREATE_VIEW_RELATION), child(move(child_p)), - schema_name(move(schema_name_p)), view_name(move(view_name_p)), replace(replace_p), temporary(temporary_p) { + : Relation(child_p->context, RelationType::CREATE_VIEW_RELATION), child(std::move(child_p)), + schema_name(std::move(schema_name_p)), view_name(std::move(view_name_p)), replace(replace_p), + temporary(temporary_p) { context.GetContext()->TryBindRelation(*this, this->columns); } @@ -159445,12 +168528,12 @@ BoundStatement CreateViewRelation::Bind(Binder &binder) { CreateStatement stmt; auto info = make_unique(); - info->query = move(select); + info->query = std::move(select); info->view_name = view_name; info->temporary = temporary; info->schema = schema_name; info->on_conflict = replace ? OnCreateConflict::REPLACE_ON_CONFLICT : OnCreateConflict::ERROR_ON_CONFLICT; - stmt.info = move(info); + stmt.info = std::move(info); return binder.Bind((SQLStatement &)stmt); } @@ -159503,7 +168586,18 @@ class CrossProductRelation : public Relation { //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/parser/tableref/crossproductref.hpp +// duckdb/parser/tableref/joinref.hpp +// +// +//===----------------------------------------------------------------------===// + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/joinref_type.hpp // // //===----------------------------------------------------------------------===// @@ -159513,16 +168607,45 @@ class CrossProductRelation : public Relation { namespace duckdb { -//! Represents a cross product -class CrossProductRef : public TableRef { + +//===--------------------------------------------------------------------===// +// Join Reference Types +//===--------------------------------------------------------------------===// +enum class JoinRefType : uint8_t { + REGULAR, // Explicit conditions + NATURAL, // Implied conditions + CROSS, // No condition + POSITIONAL // Positional condition +}; + +} // namespace duckdb + + + + + + +namespace duckdb { + +//! Represents a JOIN between two expressions +class JoinRef : public TableRef { public: - CrossProductRef() : TableRef(TableReferenceType::CROSS_PRODUCT) { + explicit JoinRef(JoinRefType ref_type) + : TableRef(TableReferenceType::JOIN), type(JoinType::INNER), ref_type(ref_type) { } - //! The left hand side of the cross product + //! The left hand side of the join unique_ptr left; - //! The right hand side of the cross product + //! The right hand side of the join unique_ptr right; + //! The join condition + unique_ptr condition; + //! The join type + JoinType type; + //! Join condition type + JoinRefType ref_type; + //! The set of USING columns (if any) + vector using_columns; public: string ToString() const override; @@ -159530,9 +168653,9 @@ class CrossProductRef : public TableRef { unique_ptr Copy() override; - //! Serializes a blob into a CrossProductRef + //! Serializes a blob into a JoinRef void Serialize(FieldWriter &serializer) const override; - //! Deserializes a blob back into a CrossProductRef + //! Deserializes a blob back into a JoinRef static unique_ptr Deserialize(FieldReader &source); }; } // namespace duckdb @@ -159541,7 +168664,8 @@ class CrossProductRef : public TableRef { namespace duckdb { CrossProductRelation::CrossProductRelation(shared_ptr left_p, shared_ptr right_p) - : Relation(left_p->context, RelationType::CROSS_PRODUCT_RELATION), left(move(left_p)), right(move(right_p)) { + : Relation(left_p->context, RelationType::CROSS_PRODUCT_RELATION), left(std::move(left_p)), + right(std::move(right_p)) { if (left->context.GetContext() != right->context.GetContext()) { throw Exception("Cannot combine LEFT and RIGHT relations of different connections!"); } @@ -159552,14 +168676,14 @@ unique_ptr CrossProductRelation::GetQueryNode() { auto result = make_unique(); result->select_list.push_back(make_unique()); result->from_table = GetTableRef(); - return move(result); + return std::move(result); } unique_ptr CrossProductRelation::GetTableRef() { - auto cross_product_ref = make_unique(); + auto cross_product_ref = make_unique(JoinRefType::CROSS); cross_product_ref->left = left->GetTableRef(); cross_product_ref->right = right->GetTableRef(); - return move(cross_product_ref); + return std::move(cross_product_ref); } const vector &CrossProductRelation::Columns() { @@ -159655,8 +168779,8 @@ namespace duckdb { DeleteRelation::DeleteRelation(ClientContextWrapper &context, unique_ptr condition_p, string schema_name_p, string table_name_p) - : Relation(context, RelationType::DELETE_RELATION), condition(move(condition_p)), schema_name(move(schema_name_p)), - table_name(move(table_name_p)) { + : Relation(context, RelationType::DELETE_RELATION), condition(std::move(condition_p)), + schema_name(std::move(schema_name_p)), table_name(std::move(table_name_p)) { context.GetContext()->TryBindRelation(*this, this->columns); } @@ -159667,7 +168791,7 @@ BoundStatement DeleteRelation::Bind(Binder &binder) { DeleteStatement stmt; stmt.condition = condition ? condition->Copy() : nullptr; - stmt.table = move(basetable); + stmt.table = std::move(basetable); return binder.Bind((SQLStatement &)stmt); } @@ -159728,7 +168852,7 @@ class DistinctRelation : public Relation { namespace duckdb { DistinctRelation::DistinctRelation(shared_ptr child_p) - : Relation(child_p->context, RelationType::DISTINCT_RELATION), child(move(child_p)) { + : Relation(child_p->context, RelationType::DISTINCT_RELATION), child(std::move(child_p)) { D_ASSERT(child.get() != this); vector dummy_columns; context.GetContext()->TryBindRelation(*this, dummy_columns); @@ -159796,14 +168920,14 @@ class ExplainRelation : public Relation { namespace duckdb { ExplainRelation::ExplainRelation(shared_ptr child_p) - : Relation(child_p->context, RelationType::EXPLAIN_RELATION), child(move(child_p)) { + : Relation(child_p->context, RelationType::EXPLAIN_RELATION), child(std::move(child_p)) { context.GetContext()->TryBindRelation(*this, this->columns); } BoundStatement ExplainRelation::Bind(Binder &binder) { auto select = make_unique(); select->node = child->GetQueryNode(); - ExplainStatement explain(move(select)); + ExplainStatement explain(std::move(select)); return binder.Bind((SQLStatement &)explain); } @@ -159954,7 +169078,7 @@ class ConjunctionExpression : public ParsedExpression { string ToString() const override; - static bool Equals(const ConjunctionExpression *a, const ConjunctionExpression *b); + static bool Equal(const ConjunctionExpression *a, const ConjunctionExpression *b); unique_ptr Copy() const override; @@ -159978,7 +169102,8 @@ class ConjunctionExpression : public ParsedExpression { namespace duckdb { FilterRelation::FilterRelation(shared_ptr child_p, unique_ptr condition_p) - : Relation(child_p->context, RelationType::FILTER_RELATION), condition(move(condition_p)), child(move(child_p)) { + : Relation(child_p->context, RelationType::FILTER_RELATION), condition(std::move(condition_p)), + child(std::move(child_p)) { D_ASSERT(child.get() != this); vector dummy_columns; context.GetContext()->TryBindRelation(*this, dummy_columns); @@ -159998,7 +169123,7 @@ unique_ptr FilterRelation::GetQueryNode() { select_node.where_clause = condition->Copy(); } else { select_node.where_clause = make_unique( - ExpressionType::CONJUNCTION_AND, move(select_node.where_clause), condition->Copy()); + ExpressionType::CONJUNCTION_AND, std::move(select_node.where_clause), condition->Copy()); } return child_node; } else { @@ -160006,7 +169131,7 @@ unique_ptr FilterRelation::GetQueryNode() { result->select_list.push_back(make_unique()); result->from_table = child->GetTableRef(); result->where_clause = condition->Copy(); - return move(result); + return std::move(result); } } @@ -160058,56 +169183,6 @@ class InsertRelation : public Relation { } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/statement/insert_statement.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - -namespace duckdb { -class ExpressionListRef; - -class InsertStatement : public SQLStatement { -public: - InsertStatement(); - - //! The select statement to insert from - unique_ptr select_statement; - //! Column names to insert into - vector columns; - - //! Table name to insert to - string table; - //! Schema name to insert to - string schema; - - //! keep track of optional returningList if statement contains a RETURNING keyword - vector> returning_list; - - //! CTEs - CommonTableExpressionMap cte_map; - -protected: - InsertStatement(const InsertStatement &other); - -public: - string ToString() const override; - unique_ptr Copy() const override; - - //! If the INSERT statement is inserted DIRECTLY from a values list (i.e. INSERT INTO tbl VALUES (...)) this returns - //! the expression list Otherwise, this returns NULL - ExpressionListRef *GetValuesList() const; -}; - -} // namespace duckdb @@ -160117,8 +169192,8 @@ class InsertStatement : public SQLStatement { namespace duckdb { InsertRelation::InsertRelation(shared_ptr child_p, string schema_name, string table_name) - : Relation(child_p->context, RelationType::INSERT_RELATION), child(move(child_p)), schema_name(move(schema_name)), - table_name(move(table_name)) { + : Relation(child_p->context, RelationType::INSERT_RELATION), child(std::move(child_p)), + schema_name(std::move(schema_name)), table_name(std::move(table_name)) { context.GetContext()->TryBindRelation(*this, this->columns); } @@ -160129,7 +169204,7 @@ BoundStatement InsertRelation::Bind(Binder &binder) { stmt.schema = schema_name; stmt.table = table_name; - stmt.select_statement = move(select); + stmt.select_statement = std::move(select); return binder.Bind((SQLStatement &)stmt); } @@ -160185,62 +169260,14 @@ class JoinRelation : public Relation { -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/tableref/joinref.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - - - -namespace duckdb { -//! Represents a JOIN between two expressions -class JoinRef : public TableRef { -public: - JoinRef() : TableRef(TableReferenceType::JOIN), is_natural(false) { - } - - //! The left hand side of the join - unique_ptr left; - //! The right hand side of the join - unique_ptr right; - //! The join condition - unique_ptr condition; - //! The join type - JoinType type; - //! Natural join - bool is_natural; - //! The set of USING columns (if any) - vector using_columns; - -public: - string ToString() const override; - bool Equals(const TableRef *other_p) const override; - - unique_ptr Copy() override; - - //! Serializes a blob into a JoinRef - void Serialize(FieldWriter &serializer) const override; - //! Deserializes a blob back into a JoinRef - static unique_ptr Deserialize(FieldReader &source); -}; -} // namespace duckdb namespace duckdb { JoinRelation::JoinRelation(shared_ptr left_p, shared_ptr right_p, unique_ptr condition_p, JoinType type) - : Relation(left_p->context, RelationType::JOIN_RELATION), left(move(left_p)), right(move(right_p)), - condition(move(condition_p)), join_type(type) { + : Relation(left_p->context, RelationType::JOIN_RELATION), left(std::move(left_p)), right(std::move(right_p)), + condition(std::move(condition_p)), join_type(type) { if (left->context.GetContext() != right->context.GetContext()) { throw Exception("Cannot combine LEFT and RIGHT relations of different connections!"); } @@ -160249,8 +169276,8 @@ JoinRelation::JoinRelation(shared_ptr left_p, shared_ptr rig JoinRelation::JoinRelation(shared_ptr left_p, shared_ptr right_p, vector using_columns_p, JoinType type) - : Relation(left_p->context, RelationType::JOIN_RELATION), left(move(left_p)), right(move(right_p)), - using_columns(move(using_columns_p)), join_type(type) { + : Relation(left_p->context, RelationType::JOIN_RELATION), left(std::move(left_p)), right(std::move(right_p)), + using_columns(std::move(using_columns_p)), join_type(type) { if (left->context.GetContext() != right->context.GetContext()) { throw Exception("Cannot combine LEFT and RIGHT relations of different connections!"); } @@ -160261,11 +169288,11 @@ unique_ptr JoinRelation::GetQueryNode() { auto result = make_unique(); result->select_list.push_back(make_unique()); result->from_table = GetTableRef(); - return move(result); + return std::move(result); } unique_ptr JoinRelation::GetTableRef() { - auto join_ref = make_unique(); + auto join_ref = make_unique(JoinRefType::REGULAR); join_ref->left = left->GetTableRef(); join_ref->right = right->GetTableRef(); if (condition) { @@ -160273,7 +169300,7 @@ unique_ptr JoinRelation::GetTableRef() { } join_ref->using_columns = using_columns; join_ref->type = join_type; - return move(join_ref); + return std::move(join_ref); } const vector &JoinRelation::Columns() { @@ -160340,7 +169367,7 @@ namespace duckdb { LimitRelation::LimitRelation(shared_ptr child_p, int64_t limit, int64_t offset) : Relation(child_p->context, RelationType::PROJECTION_RELATION), limit(limit), offset(offset), - child(move(child_p)) { + child(std::move(child_p)) { D_ASSERT(child.get() != this); } @@ -160354,7 +169381,7 @@ unique_ptr LimitRelation::GetQueryNode() { limit_node->offset = make_unique(Value::BIGINT(offset)); } - child_node->modifiers.push_back(move(limit_node)); + child_node->modifiers.push_back(std::move(limit_node)); return child_node; } @@ -160426,7 +169453,7 @@ class OrderRelation : public Relation { namespace duckdb { OrderRelation::OrderRelation(shared_ptr child_p, vector orders) - : Relation(child_p->context, RelationType::ORDER_RELATION), orders(move(orders)), child(move(child_p)) { + : Relation(child_p->context, RelationType::ORDER_RELATION), orders(std::move(orders)), child(std::move(child_p)) { D_ASSERT(child.get() != this); // bind the expressions context.GetContext()->TryBindRelation(*this, this->columns); @@ -160440,8 +169467,8 @@ unique_ptr OrderRelation::GetQueryNode() { for (idx_t i = 0; i < orders.size(); i++) { order_node->orders.emplace_back(orders[i].type, orders[i].null_order, orders[i].expression->Copy()); } - select->modifiers.push_back(move(order_node)); - return move(select); + select->modifiers.push_back(std::move(order_node)); + return std::move(select); } string OrderRelation::GetAlias() { @@ -160507,8 +169534,8 @@ namespace duckdb { ProjectionRelation::ProjectionRelation(shared_ptr child_p, vector> parsed_expressions, vector aliases) - : Relation(child_p->context, RelationType::PROJECTION_RELATION), expressions(move(parsed_expressions)), - child(move(child_p)) { + : Relation(child_p->context, RelationType::PROJECTION_RELATION), expressions(std::move(parsed_expressions)), + child(std::move(child_p)) { if (!aliases.empty()) { if (aliases.size() != expressions.size()) { throw ParserException("Aliases list length must match expression list length!"); @@ -160534,7 +169561,7 @@ unique_ptr ProjectionRelation::GetQueryNode() { // child node is not a join: create a new select node and push the child as a table reference auto select = make_unique(); select->from_table = child->GetTableRef(); - result = move(select); + result = std::move(select); } D_ASSERT(result->type == QueryNodeType::SELECT_NODE); auto &select_node = (SelectNode &)*result; @@ -160577,7 +169604,8 @@ namespace duckdb { QueryRelation::QueryRelation(const std::shared_ptr &context, unique_ptr select_stmt_p, string alias_p) - : Relation(context, RelationType::QUERY_RELATION), select_stmt(move(select_stmt_p)), alias(move(alias_p)) { + : Relation(context, RelationType::QUERY_RELATION), select_stmt(std::move(select_stmt_p)), + alias(std::move(alias_p)) { context->TryBindRelation(*this, this->columns); } @@ -160594,7 +169622,7 @@ unique_ptr QueryRelation::ParseStatement(ClientContext &context if (parser.statements[0]->type != StatementType::SELECT_STATEMENT) { throw ParserException(error); } - return unique_ptr_cast(move(parser.statements[0])); + return unique_ptr_cast(std::move(parser.statements[0])); } unique_ptr QueryRelation::GetSelectStatement() { @@ -160603,12 +169631,12 @@ unique_ptr QueryRelation::GetSelectStatement() { unique_ptr QueryRelation::GetQueryNode() { auto select = GetSelectStatement(); - return move(select->node); + return std::move(select->node); } unique_ptr QueryRelation::GetTableRef() { auto subquery_ref = make_unique(GetSelectStatement(), GetAlias()); - return move(subquery_ref); + return std::move(subquery_ref); } string QueryRelation::GetAlias() { @@ -160635,58 +169663,93 @@ string QueryRelation::ToString(idx_t depth) { + namespace duckdb { -ReadCSVRelation::ReadCSVRelation(const std::shared_ptr &context, string csv_file_p, - vector columns_p, bool auto_detect, string alias_p) - : Relation(context, RelationType::READ_CSV_RELATION), csv_file(move(csv_file_p)), auto_detect(auto_detect), - alias(move(alias_p)), columns(move(columns_p)) { +ReadCSVRelation::ReadCSVRelation(const std::shared_ptr &context, const string &csv_file, + vector columns_p, string alias_p) + : TableFunctionRelation(context, "read_csv", {Value(csv_file)}, nullptr, false), alias(std::move(alias_p)), + auto_detect(false) { + if (alias.empty()) { alias = StringUtil::Split(csv_file, ".")[0]; } -} -unique_ptr ReadCSVRelation::GetQueryNode() { - auto result = make_unique(); - result->select_list.push_back(make_unique()); - result->from_table = GetTableRef(); - return move(result); + columns = std::move(columns_p); + + child_list_t column_names; + for (idx_t i = 0; i < columns.size(); i++) { + column_names.push_back(make_pair(columns[i].Name(), Value(columns[i].Type().ToString()))); + } + + AddNamedParameter("columns", Value::STRUCT(std::move(column_names))); } -unique_ptr ReadCSVRelation::GetTableRef() { - auto table_ref = make_unique(); - table_ref->alias = alias; - vector> children; - // CSV file - children.push_back(make_unique(Value(csv_file))); - if (!auto_detect) { - // parameters - child_list_t column_names; - for (idx_t i = 0; i < columns.size(); i++) { - column_names.push_back(make_pair(columns[i].Name(), Value(columns[i].Type().ToString()))); - } - auto colnames = make_unique(Value::STRUCT(move(column_names))); - children.push_back(make_unique( - ExpressionType::COMPARE_EQUAL, make_unique("columns"), move(colnames))); - } else { - children.push_back(make_unique(ExpressionType::COMPARE_EQUAL, - make_unique("auto_detect"), - make_unique(Value::BOOLEAN(true)))); +ReadCSVRelation::ReadCSVRelation(const std::shared_ptr &context, const string &csv_file, + BufferedCSVReaderOptions options, string alias_p) + : TableFunctionRelation(context, "read_csv_auto", {Value(csv_file)}, nullptr, false), alias(std::move(alias_p)), + auto_detect(true) { + + if (alias.empty()) { + alias = StringUtil::Split(csv_file, ".")[0]; + } + + // Force auto_detect for this constructor + options.auto_detect = true; + BufferedCSVReader reader(*context, std::move(options)); + + for (idx_t i = 0; i < reader.return_types.size(); i++) { + columns.emplace_back(reader.names[i], reader.return_types[i]); } - table_ref->function = make_unique("read_csv", move(children)); - return move(table_ref); + + AddNamedParameter("auto_detect", Value::BOOLEAN(true)); } string ReadCSVRelation::GetAlias() { return alias; } -const vector &ReadCSVRelation::Columns() { - return columns; +} // namespace duckdb + + + + + + + + + +namespace duckdb { + +class ReadJSONRelation : public TableFunctionRelation { +public: + ReadJSONRelation(const shared_ptr &context, string json_file, named_parameter_map_t options, + bool auto_detect, string alias = ""); + string json_file; + string alias; + +public: + string GetAlias() override; +}; + +} // namespace duckdb + + +namespace duckdb { + +ReadJSONRelation::ReadJSONRelation(const shared_ptr &context, string json_file_p, + named_parameter_map_t options, bool auto_detect, string alias_p) + : TableFunctionRelation(context, auto_detect ? "read_json_auto" : "read_json", {Value(json_file_p)}, + std::move(options)), + json_file(std::move(json_file_p)), alias(std::move(alias_p)) { + + if (alias.empty()) { + alias = StringUtil::Split(json_file, ".")[0]; + } } -string ReadCSVRelation::ToString(idx_t depth) { - return RenderWhitespace(depth) + "Read CSV [" + csv_file + "]"; +string ReadJSONRelation::GetAlias() { + return alias; } } // namespace duckdb @@ -160730,8 +169793,8 @@ class SetOpRelation : public Relation { namespace duckdb { SetOpRelation::SetOpRelation(shared_ptr left_p, shared_ptr right_p, SetOperationType setop_type_p) - : Relation(left_p->context, RelationType::SET_OPERATION_RELATION), left(move(left_p)), right(move(right_p)), - setop_type(setop_type_p) { + : Relation(left_p->context, RelationType::SET_OPERATION_RELATION), left(std::move(left_p)), + right(std::move(right_p)), setop_type(setop_type_p) { if (left->context.GetContext() != right->context.GetContext()) { throw Exception("Cannot combine LEFT and RIGHT relations of different connections!"); } @@ -160747,7 +169810,7 @@ unique_ptr SetOpRelation::GetQueryNode() { result->left = left->GetQueryNode(); result->right = right->GetQueryNode(); result->setop_type = setop_type; - return move(result); + return std::move(result); } string SetOpRelation::GetAlias() { @@ -160822,7 +169885,8 @@ class SubqueryRelation : public Relation { namespace duckdb { SubqueryRelation::SubqueryRelation(shared_ptr child_p, string alias_p) - : Relation(child_p->context, RelationType::SUBQUERY_RELATION), child(move(child_p)), alias(move(alias_p)) { + : Relation(child_p->context, RelationType::SUBQUERY_RELATION), child(std::move(child_p)), + alias(std::move(alias_p)) { D_ASSERT(child.get() != this); vector dummy_columns; context.GetContext()->TryBindRelation(*this, dummy_columns); @@ -160893,7 +169957,7 @@ class SubqueryExpression : public ParsedExpression { string ToString() const override; - static bool Equals(const SubqueryExpression *a, const SubqueryExpression *b); + static bool Equal(const SubqueryExpression *a, const SubqueryExpression *b); unique_ptr Copy() const override; @@ -160908,27 +169972,39 @@ class SubqueryExpression : public ParsedExpression { namespace duckdb { +void TableFunctionRelation::AddNamedParameter(const string &name, Value argument) { + named_parameters[name] = std::move(argument); +} + TableFunctionRelation::TableFunctionRelation(const std::shared_ptr &context, string name_p, vector parameters_p, named_parameter_map_t named_parameters, - shared_ptr input_relation_p) - : Relation(context, RelationType::TABLE_FUNCTION_RELATION), name(move(name_p)), parameters(move(parameters_p)), - named_parameters(move(named_parameters)), input_relation(move(input_relation_p)) { - context->TryBindRelation(*this, this->columns); + shared_ptr input_relation_p, bool auto_init) + : Relation(context, RelationType::TABLE_FUNCTION_RELATION), name(std::move(name_p)), + parameters(std::move(parameters_p)), named_parameters(std::move(named_parameters)), + input_relation(std::move(input_relation_p)), auto_initialize(auto_init) { + InitializeColumns(); } + TableFunctionRelation::TableFunctionRelation(const std::shared_ptr &context, string name_p, - vector parameters_p, + vector parameters_p, shared_ptr input_relation_p, + bool auto_init) + : Relation(context, RelationType::TABLE_FUNCTION_RELATION), name(std::move(name_p)), + parameters(std::move(parameters_p)), input_relation(std::move(input_relation_p)), auto_initialize(auto_init) { + InitializeColumns(); +} - shared_ptr input_relation_p) - : Relation(context, RelationType::TABLE_FUNCTION_RELATION), name(move(name_p)), parameters(move(parameters_p)), - input_relation(move(input_relation_p)) { - context->TryBindRelation(*this, this->columns); +void TableFunctionRelation::InitializeColumns() { + if (!auto_initialize) { + return; + } + context.GetContext()->TryBindRelation(*this, this->columns); } unique_ptr TableFunctionRelation::GetQueryNode() { auto result = make_unique(); result->select_list.push_back(make_unique()); result->from_table = GetTableRef(); - return move(result); + return std::move(result); } unique_ptr TableFunctionRelation::GetTableRef() { @@ -160938,7 +170014,7 @@ unique_ptr TableFunctionRelation::GetTableRef() { subquery->subquery = make_unique(); subquery->subquery->node = input_relation->GetQueryNode(); subquery->subquery_type = SubqueryType::SCALAR; - children.push_back(move(subquery)); + children.push_back(std::move(subquery)); } for (auto ¶meter : parameters) { children.push_back(make_unique(parameter)); @@ -160950,15 +170026,15 @@ unique_ptr TableFunctionRelation::GetTableRef() { // the function binder likes auto column_ref = make_unique(parameter.first); auto constant_value = make_unique(parameter.second); - auto comparison = - make_unique(ExpressionType::COMPARE_EQUAL, move(column_ref), move(constant_value)); - children.push_back(move(comparison)); + auto comparison = make_unique(ExpressionType::COMPARE_EQUAL, std::move(column_ref), + std::move(constant_value)); + children.push_back(std::move(comparison)); } auto table_function = make_unique(); - auto function = make_unique(name, move(children)); - table_function->function = move(function); - return move(table_function); + auto function = make_unique(name, std::move(children)); + table_function->function = std::move(function); + return std::move(table_function); } string TableFunctionRelation::GetAlias() { @@ -161031,21 +170107,21 @@ class UpdateRelation : public Relation { namespace duckdb { TableRelation::TableRelation(const std::shared_ptr &context, unique_ptr description) - : Relation(context, RelationType::TABLE_RELATION), description(move(description)) { + : Relation(context, RelationType::TABLE_RELATION), description(std::move(description)) { } unique_ptr TableRelation::GetQueryNode() { auto result = make_unique(); result->select_list.push_back(make_unique()); result->from_table = GetTableRef(); - return move(result); + return std::move(result); } unique_ptr TableRelation::GetTableRef() { auto table_ref = make_unique(); table_ref->schema_name = description->schema; table_ref->table_name = description->table; - return move(table_ref); + return std::move(table_ref); } string TableRelation::GetAlias() { @@ -161066,7 +170142,7 @@ static unique_ptr ParseCondition(ClientContext &context, const if (expression_list.size() != 1) { throw ParserException("Expected a single expression as filter condition"); } - return move(expression_list[0]); + return std::move(expression_list[0]); } else { return nullptr; } @@ -161077,60 +170153,19 @@ void TableRelation::Update(const string &update_list, const string &condition) { vector> expressions; auto cond = ParseCondition(*context.GetContext(), condition); Parser::ParseUpdateList(update_list, update_columns, expressions, context.GetContext()->GetParserOptions()); - auto update = make_shared(context, move(cond), description->schema, description->table, - move(update_columns), move(expressions)); + auto update = make_shared(context, std::move(cond), description->schema, description->table, + std::move(update_columns), std::move(expressions)); update->Execute(); } void TableRelation::Delete(const string &condition) { auto cond = ParseCondition(*context.GetContext(), condition); - auto del = make_shared(context, move(cond), description->schema, description->table); + auto del = make_shared(context, std::move(cond), description->schema, description->table); del->Execute(); } } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/statement/update_statement.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - - - -namespace duckdb { - -class UpdateStatement : public SQLStatement { -public: - UpdateStatement(); - - unique_ptr condition; - unique_ptr table; - unique_ptr from_table; - vector columns; - vector> expressions; - //! keep track of optional returningList if statement contains a RETURNING keyword - vector> returning_list; - //! CTEs - CommonTableExpressionMap cte_map; - -protected: - UpdateStatement(const UpdateStatement &other); - -public: - string ToString() const override; - unique_ptr Copy() const override; -}; - -} // namespace duckdb @@ -161141,8 +170176,9 @@ namespace duckdb { UpdateRelation::UpdateRelation(ClientContextWrapper &context, unique_ptr condition_p, string schema_name_p, string table_name_p, vector update_columns_p, vector> expressions_p) - : Relation(context, RelationType::UPDATE_RELATION), condition(move(condition_p)), schema_name(move(schema_name_p)), - table_name(move(table_name_p)), update_columns(move(update_columns_p)), expressions(move(expressions_p)) { + : Relation(context, RelationType::UPDATE_RELATION), condition(std::move(condition_p)), + schema_name(std::move(schema_name_p)), table_name(std::move(table_name_p)), + update_columns(std::move(update_columns_p)), expressions(std::move(expressions_p)) { D_ASSERT(update_columns.size() == expressions.size()); context.GetContext()->TryBindRelation(*this, this->columns); } @@ -161153,11 +170189,13 @@ BoundStatement UpdateRelation::Bind(Binder &binder) { basetable->table_name = table_name; UpdateStatement stmt; - stmt.condition = condition ? condition->Copy() : nullptr; - stmt.table = move(basetable); - stmt.columns = update_columns; + stmt.set_info = make_unique(); + + stmt.set_info->condition = condition ? condition->Copy() : nullptr; + stmt.table = std::move(basetable); + stmt.set_info->columns = update_columns; for (auto &expr : expressions) { - stmt.expressions.push_back(expr->Copy()); + stmt.set_info->expressions.push_back(expr->Copy()); } return binder.Bind((SQLStatement &)stmt); } @@ -161231,7 +170269,7 @@ namespace duckdb { ValueRelation::ValueRelation(const std::shared_ptr &context, const vector> &values, vector names_p, string alias_p) - : Relation(context, RelationType::VALUE_LIST_RELATION), names(move(names_p)), alias(move(alias_p)) { + : Relation(context, RelationType::VALUE_LIST_RELATION), names(std::move(names_p)), alias(std::move(alias_p)) { // create constant expressions for the values for (idx_t row_idx = 0; row_idx < values.size(); row_idx++) { auto &list = values[row_idx]; @@ -161239,14 +170277,14 @@ ValueRelation::ValueRelation(const std::shared_ptr &context, cons for (idx_t col_idx = 0; col_idx < list.size(); col_idx++) { expressions.push_back(make_unique(list[col_idx])); } - this->expressions.push_back(move(expressions)); + this->expressions.push_back(std::move(expressions)); } context->TryBindRelation(*this, this->columns); } ValueRelation::ValueRelation(const std::shared_ptr &context, const string &values_list, vector names_p, string alias_p) - : Relation(context, RelationType::VALUE_LIST_RELATION), names(move(names_p)), alias(move(alias_p)) { + : Relation(context, RelationType::VALUE_LIST_RELATION), names(std::move(names_p)), alias(std::move(alias_p)) { this->expressions = Parser::ParseValuesList(values_list, context->GetParserOptions()); context->TryBindRelation(*this, this->columns); } @@ -161255,7 +170293,7 @@ unique_ptr ValueRelation::GetQueryNode() { auto result = make_unique(); result->select_list.push_back(make_unique()); result->from_table = GetTableRef(); - return move(result); + return std::move(result); } unique_ptr ValueRelation::GetTableRef() { @@ -161280,10 +170318,10 @@ unique_ptr ValueRelation::GetTableRef() { for (auto &expr : expr_list) { copied_list.push_back(expr->Copy()); } - table_ref->values.push_back(move(copied_list)); + table_ref->values.push_back(std::move(copied_list)); } table_ref->alias = GetAlias(); - return move(table_ref); + return std::move(table_ref); } string ValueRelation::GetAlias() { @@ -161320,7 +170358,8 @@ string ValueRelation::ToString(idx_t depth) { namespace duckdb { ViewRelation::ViewRelation(const std::shared_ptr &context, string schema_name_p, string view_name_p) - : Relation(context, RelationType::VIEW_RELATION), schema_name(move(schema_name_p)), view_name(move(view_name_p)) { + : Relation(context, RelationType::VIEW_RELATION), schema_name(std::move(schema_name_p)), + view_name(std::move(view_name_p)) { context->TryBindRelation(*this, this->columns); } @@ -161328,14 +170367,14 @@ unique_ptr ViewRelation::GetQueryNode() { auto result = make_unique(); result->select_list.push_back(make_unique()); result->from_table = GetTableRef(); - return move(result); + return std::move(result); } unique_ptr ViewRelation::GetTableRef() { auto table_ref = make_unique(); table_ref->schema_name = schema_name; table_ref->table_name = view_name; - return move(table_ref); + return std::move(table_ref); } string ViewRelation::GetAlias() { @@ -161367,11 +170406,12 @@ namespace duckdb { class WriteCSVRelation : public Relation { public: - WriteCSVRelation(shared_ptr child, string csv_file); + WriteCSVRelation(shared_ptr child, string csv_file, case_insensitive_map_t> options); shared_ptr child; string csv_file; vector columns; + case_insensitive_map_t> options; public: BoundStatement Bind(Binder &binder) override; @@ -161384,10 +170424,46 @@ class WriteCSVRelation : public Relation { } // namespace duckdb + + + + + +namespace duckdb { + +WriteCSVRelation::WriteCSVRelation(shared_ptr child_p, string csv_file_p, + case_insensitive_map_t> options_p) + : Relation(child_p->context, RelationType::WRITE_CSV_RELATION), child(std::move(child_p)), + csv_file(std::move(csv_file_p)), options(std::move(options_p)) { + context.GetContext()->TryBindRelation(*this, this->columns); +} + +BoundStatement WriteCSVRelation::Bind(Binder &binder) { + CopyStatement copy; + copy.select_statement = child->GetQueryNode(); + auto info = make_unique(); + info->is_from = false; + info->file_path = csv_file; + info->format = "csv"; + info->options = options; + copy.info = std::move(info); + return binder.Bind((SQLStatement &)copy); +} + +const vector &WriteCSVRelation::Columns() { + return columns; +} + +string WriteCSVRelation::ToString(idx_t depth) { + string str = RenderWhitespace(depth) + "Write To CSV [" + csv_file + "]\n"; + return str + child->ToString(depth + 1); +} + +} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/parser/statement/copy_statement.hpp +// duckdb/main/relation/write_csv_relation.hpp // // //===----------------------------------------------------------------------===// @@ -161396,54 +170472,61 @@ class WriteCSVRelation : public Relation { - - namespace duckdb { -class CopyStatement : public SQLStatement { +class WriteParquetRelation : public Relation { public: - CopyStatement(); - - unique_ptr info; - // The SQL statement used instead of a table when copying data out to a file - unique_ptr select_statement; + WriteParquetRelation(shared_ptr child, string parquet_file, + case_insensitive_map_t> options); -protected: - CopyStatement(const CopyStatement &other); + shared_ptr child; + string parquet_file; + vector columns; + case_insensitive_map_t> options; public: - unique_ptr Copy() const override; + BoundStatement Bind(Binder &binder) override; + const vector &Columns() override; + string ToString(idx_t depth) override; + bool IsReadOnly() override { + return false; + } }; + } // namespace duckdb + namespace duckdb { -WriteCSVRelation::WriteCSVRelation(shared_ptr child_p, string csv_file_p) - : Relation(child_p->context, RelationType::WRITE_CSV_RELATION), child(move(child_p)), csv_file(move(csv_file_p)) { +WriteParquetRelation::WriteParquetRelation(shared_ptr child_p, string parquet_file_p, + case_insensitive_map_t> options_p) + : Relation(child_p->context, RelationType::WRITE_PARQUET_RELATION), child(std::move(child_p)), + parquet_file(std::move(parquet_file_p)), options(std::move(options_p)) { context.GetContext()->TryBindRelation(*this, this->columns); } -BoundStatement WriteCSVRelation::Bind(Binder &binder) { +BoundStatement WriteParquetRelation::Bind(Binder &binder) { CopyStatement copy; copy.select_statement = child->GetQueryNode(); auto info = make_unique(); info->is_from = false; - info->file_path = csv_file; - info->format = "csv"; - copy.info = move(info); + info->file_path = parquet_file; + info->format = "parquet"; + info->options = options; + copy.info = std::move(info); return binder.Bind((SQLStatement &)copy); } -const vector &WriteCSVRelation::Columns() { +const vector &WriteParquetRelation::Columns() { return columns; } -string WriteCSVRelation::ToString(idx_t depth) { - string str = RenderWhitespace(depth) + "Write To CSV [" + csv_file + "]\n"; +string WriteParquetRelation::ToString(idx_t depth) { + string str = RenderWhitespace(depth) + "Write To Parquet [" + parquet_file + "]\n"; return str + child->ToString(depth + 1); } @@ -161473,6 +170556,7 @@ string WriteCSVRelation::ToString(idx_t depth) { + namespace duckdb { @@ -161487,7 +170571,7 @@ shared_ptr Relation::Project(const string &expression, const string &a shared_ptr Relation::Project(const string &select_list, const vector &aliases) { auto expressions = Parser::ParseExpressionList(select_list, context.GetContext()->GetParserOptions()); - return make_shared(shared_from_this(), move(expressions), aliases); + return make_shared(shared_from_this(), std::move(expressions), aliases); } shared_ptr Relation::Project(const vector &expressions) { @@ -161506,14 +170590,14 @@ static vector> StringListToExpressionList(ClientCon if (expression_list.size() != 1) { throw ParserException("Expected a single expression in the expression list"); } - result_list.push_back(move(expression_list[0])); + result_list.push_back(std::move(expression_list[0])); } return result_list; } shared_ptr Relation::Project(const vector &expressions, const vector &aliases) { auto result_list = StringListToExpressionList(*context.GetContext(), expressions); - return make_shared(shared_from_this(), move(result_list), aliases); + return make_shared(shared_from_this(), std::move(result_list), aliases); } shared_ptr Relation::Filter(const string &expression) { @@ -161521,7 +170605,7 @@ shared_ptr Relation::Filter(const string &expression) { if (expression_list.size() != 1) { throw ParserException("Expected a single expression as filter condition"); } - return make_shared(shared_from_this(), move(expression_list[0])); + return make_shared(shared_from_this(), std::move(expression_list[0])); } shared_ptr Relation::Filter(const vector &expressions) { @@ -161529,12 +170613,12 @@ shared_ptr Relation::Filter(const vector &expressions) { auto expression_list = StringListToExpressionList(*context.GetContext(), expressions); D_ASSERT(!expression_list.empty()); - auto expr = move(expression_list[0]); + auto expr = std::move(expression_list[0]); for (idx_t i = 1; i < expression_list.size(); i++) { - expr = - make_unique(ExpressionType::CONJUNCTION_AND, move(expr), move(expression_list[i])); + expr = make_unique(ExpressionType::CONJUNCTION_AND, std::move(expr), + std::move(expression_list[i])); } - return make_shared(shared_from_this(), move(expr)); + return make_shared(shared_from_this(), std::move(expr)); } shared_ptr Relation::Limit(int64_t limit, int64_t offset) { @@ -161543,7 +170627,7 @@ shared_ptr Relation::Limit(int64_t limit, int64_t offset) { shared_ptr Relation::Order(const string &expression) { auto order_list = Parser::ParseOrderList(expression, context.GetContext()->GetParserOptions()); - return make_shared(shared_from_this(), move(order_list)); + return make_shared(shared_from_this(), std::move(order_list)); } shared_ptr Relation::Order(const vector &expressions) { @@ -161556,9 +170640,9 @@ shared_ptr Relation::Order(const vector &expressions) { if (inner_list.size() != 1) { throw ParserException("Expected a single ORDER BY expression in the expression list"); } - order_list.push_back(move(inner_list[0])); + order_list.push_back(std::move(inner_list[0])); } - return make_shared(shared_from_this(), move(order_list)); + return make_shared(shared_from_this(), std::move(order_list)); } shared_ptr Relation::Join(const shared_ptr &other, const string &condition, JoinType type) { @@ -161578,10 +170662,10 @@ shared_ptr Relation::Join(const shared_ptr &other, const str } using_columns.push_back(colref.column_names[0]); } - return make_shared(shared_from_this(), other, move(using_columns), type); + return make_shared(shared_from_this(), other, std::move(using_columns), type); } else { // single expression that is not a column reference: use the expression as a join condition - return make_shared(shared_from_this(), other, move(expression_list[0]), type); + return make_shared(shared_from_this(), other, std::move(expression_list[0]), type); } } @@ -161611,24 +170695,24 @@ shared_ptr Relation::Alias(const string &alias) { shared_ptr Relation::Aggregate(const string &aggregate_list) { auto expression_list = Parser::ParseExpressionList(aggregate_list, context.GetContext()->GetParserOptions()); - return make_shared(shared_from_this(), move(expression_list)); + return make_shared(shared_from_this(), std::move(expression_list)); } shared_ptr Relation::Aggregate(const string &aggregate_list, const string &group_list) { auto expression_list = Parser::ParseExpressionList(aggregate_list, context.GetContext()->GetParserOptions()); auto groups = Parser::ParseExpressionList(group_list, context.GetContext()->GetParserOptions()); - return make_shared(shared_from_this(), move(expression_list), move(groups)); + return make_shared(shared_from_this(), std::move(expression_list), std::move(groups)); } shared_ptr Relation::Aggregate(const vector &aggregates) { auto aggregate_list = StringListToExpressionList(*context.GetContext(), aggregates); - return make_shared(shared_from_this(), move(aggregate_list)); + return make_shared(shared_from_this(), std::move(aggregate_list)); } shared_ptr Relation::Aggregate(const vector &aggregates, const vector &groups) { auto aggregate_list = StringListToExpressionList(*context.GetContext(), aggregates); auto group_list = StringListToExpressionList(*context.GetContext(), groups); - return make_shared(shared_from_this(), move(aggregate_list), move(group_list)); + return make_shared(shared_from_this(), std::move(aggregate_list), std::move(group_list)); } string Relation::GetAlias() { @@ -161638,25 +170722,38 @@ string Relation::GetAlias() { unique_ptr Relation::GetTableRef() { auto select = make_unique(); select->node = GetQueryNode(); - return make_unique(move(select), GetAlias()); + return make_unique(std::move(select), GetAlias()); } unique_ptr Relation::Execute() { return context.GetContext()->Execute(shared_from_this()); } +unique_ptr Relation::ExecuteOrThrow() { + auto res = Execute(); + D_ASSERT(res); + if (res->HasError()) { + res->ThrowError(); + } + return res; +} + BoundStatement Relation::Bind(Binder &binder) { SelectStatement stmt; stmt.node = GetQueryNode(); return binder.Bind((SQLStatement &)stmt); } +shared_ptr Relation::InsertRel(const string &schema_name, const string &table_name) { + return make_shared(shared_from_this(), schema_name, table_name); +} + void Relation::Insert(const string &table_name) { - Insert(DEFAULT_SCHEMA, table_name); + Insert(INVALID_SCHEMA, table_name); } void Relation::Insert(const string &schema_name, const string &table_name) { - auto insert = make_shared(shared_from_this(), schema_name, table_name); + auto insert = InsertRel(schema_name, table_name); auto res = insert->Execute(); if (res->HasError()) { const string prepended_message = "Failed to insert into table '" + table_name + "': "; @@ -161666,16 +170763,20 @@ void Relation::Insert(const string &schema_name, const string &table_name) { void Relation::Insert(const vector> &values) { vector column_names; - auto rel = make_shared(context.GetContext(), values, move(column_names), "values"); + auto rel = make_shared(context.GetContext(), values, std::move(column_names), "values"); rel->Insert(GetAlias()); } +shared_ptr Relation::CreateRel(const string &schema_name, const string &table_name) { + return make_shared(shared_from_this(), schema_name, table_name); +} + void Relation::Create(const string &table_name) { - Create(DEFAULT_SCHEMA, table_name); + Create(INVALID_SCHEMA, table_name); } void Relation::Create(const string &schema_name, const string &table_name) { - auto create = make_shared(shared_from_this(), schema_name, table_name); + auto create = CreateRel(schema_name, table_name); auto res = create->Execute(); if (res->HasError()) { const string prepended_message = "Failed to create table '" + table_name + "': "; @@ -161683,8 +170784,12 @@ void Relation::Create(const string &schema_name, const string &table_name) { } } -void Relation::WriteCSV(const string &csv_file) { - auto write_csv = make_shared(shared_from_this(), csv_file); +shared_ptr Relation::WriteCSVRel(const string &csv_file, case_insensitive_map_t> options) { + return std::make_shared(shared_from_this(), csv_file, std::move(options)); +} + +void Relation::WriteCSV(const string &csv_file, case_insensitive_map_t> options) { + auto write_csv = WriteCSVRel(csv_file, std::move(options)); auto res = write_csv->Execute(); if (res->HasError()) { const string prepended_message = "Failed to write '" + csv_file + "': "; @@ -161692,14 +170797,24 @@ void Relation::WriteCSV(const string &csv_file) { } } -shared_ptr Relation::CreateView(const string &name, bool replace, bool temporary) { - auto view = make_shared(shared_from_this(), name, replace, temporary); - auto res = view->Execute(); +shared_ptr Relation::WriteParquetRel(const string &parquet_file, + case_insensitive_map_t> options) { + auto write_parquet = + std::make_shared(shared_from_this(), parquet_file, std::move(options)); + return std::move(write_parquet); +} + +void Relation::WriteParquet(const string &parquet_file, case_insensitive_map_t> options) { + auto write_parquet = WriteParquetRel(parquet_file, std::move(options)); + auto res = write_parquet->Execute(); if (res->HasError()) { - const string prepended_message = "Failed to create view '" + name + "': "; + const string prepended_message = "Failed to write '" + parquet_file + "': "; res->ThrowError(prepended_message); } - return shared_from_this(); +} + +shared_ptr Relation::CreateView(const string &name, bool replace, bool temporary) { + return CreateView(INVALID_SCHEMA, name, replace, temporary); } shared_ptr Relation::CreateView(const string &schema_name, const string &name, bool replace, bool temporary) { @@ -161807,6 +170922,9 @@ vector> Relation::GetAllDependencies() { + + + namespace duckdb { //===--------------------------------------------------------------------===// @@ -161826,6 +170944,10 @@ void AccessModeSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const } } +void AccessModeSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + config.options.access_mode = DBConfig().options.access_mode; +} + Value AccessModeSetting::GetSetting(ClientContext &context) { auto &config = DBConfig::GetConfig(context); switch (config.options.access_mode) { @@ -161848,6 +170970,10 @@ void CheckpointThresholdSetting::SetGlobal(DatabaseInstance *db, DBConfig &confi config.options.checkpoint_wal_size = new_limit; } +void CheckpointThresholdSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + config.options.checkpoint_wal_size = DBConfig().options.checkpoint_wal_size; +} + Value CheckpointThresholdSetting::GetSetting(ClientContext &context) { auto &config = DBConfig::GetConfig(context); return Value(StringUtil::BytesToHumanReadableString(config.options.checkpoint_wal_size)); @@ -161872,13 +170998,35 @@ void DebugCheckpointAbort::SetGlobal(DatabaseInstance *db, DBConfig &config, con } } +void DebugCheckpointAbort::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + config.options.checkpoint_abort = DBConfig().options.checkpoint_abort; +} + Value DebugCheckpointAbort::GetSetting(ClientContext &context) { - return Value(); + auto &config = DBConfig::GetConfig(*context.db); + auto setting = config.options.checkpoint_abort; + switch (setting) { + case CheckpointAbort::NO_ABORT: + return "none"; + case CheckpointAbort::DEBUG_ABORT_BEFORE_TRUNCATE: + return "before_truncate"; + case CheckpointAbort::DEBUG_ABORT_BEFORE_HEADER: + return "before_header"; + case CheckpointAbort::DEBUG_ABORT_AFTER_FREE_LIST_WRITE: + return "after_free_list_write"; + default: + throw InternalException("Type not implemented for CheckpointAbort"); + } } //===--------------------------------------------------------------------===// // Debug Force External //===--------------------------------------------------------------------===// + +void DebugForceExternal::ResetLocal(ClientContext &context) { + ClientConfig::GetConfig(context).force_external = ClientConfig().force_external; +} + void DebugForceExternal::SetLocal(ClientContext &context, const Value &input) { ClientConfig::GetConfig(context).force_external = input.GetValue(); } @@ -161890,6 +171038,11 @@ Value DebugForceExternal::GetSetting(ClientContext &context) { //===--------------------------------------------------------------------===// // Debug Force NoCrossProduct //===--------------------------------------------------------------------===// + +void DebugForceNoCrossProduct::ResetLocal(ClientContext &context) { + ClientConfig::GetConfig(context).force_no_cross_product = ClientConfig().force_no_cross_product; +} + void DebugForceNoCrossProduct::SetLocal(ClientContext &context, const Value &input) { ClientConfig::GetConfig(context).force_no_cross_product = input.GetValue(); } @@ -161914,6 +171067,10 @@ void DebugWindowMode::SetGlobal(DatabaseInstance *db, DBConfig &config, const Va } } +void DebugWindowMode::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + config.options.window_mode = DBConfig().options.window_mode; +} + Value DebugWindowMode::GetSetting(ClientContext &context) { return Value(); } @@ -161926,6 +171083,15 @@ void DefaultCollationSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, config.options.collation = parameter; } +void DefaultCollationSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + config.options.collation = DBConfig().options.collation; +} + +void DefaultCollationSetting::ResetLocal(ClientContext &context) { + auto &config = DBConfig::GetConfig(context); + config.options.collation = DBConfig().options.collation; +} + void DefaultCollationSetting::SetLocal(ClientContext &context, const Value &input) { auto parameter = input.ToString(); // bind the collation to verify that it exists @@ -161954,6 +171120,10 @@ void DefaultOrderSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, cons } } +void DefaultOrderSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + config.options.default_order_type = DBConfig().options.default_order_type; +} + Value DefaultOrderSetting::GetSetting(ClientContext &context) { auto &config = DBConfig::GetConfig(context); switch (config.options.default_order_type) { @@ -161984,6 +171154,10 @@ void DefaultNullOrderSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, } } +void DefaultNullOrderSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + config.options.default_null_order = DBConfig().options.default_null_order; +} + Value DefaultNullOrderSetting::GetSetting(ClientContext &context) { auto &config = DBConfig::GetConfig(context); switch (config.options.default_null_order) { @@ -162010,7 +171184,11 @@ void DisabledOptimizersSetting::SetGlobal(DatabaseInstance *db, DBConfig &config } disabled_optimizers.insert(OptimizerTypeFromString(param)); } - config.options.disabled_optimizers = move(disabled_optimizers); + config.options.disabled_optimizers = std::move(disabled_optimizers); +} + +void DisabledOptimizersSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + config.options.disabled_optimizers = DBConfig().options.disabled_optimizers; } Value DisabledOptimizersSetting::GetSetting(ClientContext &context) { @@ -162036,6 +171214,13 @@ void EnableExternalAccessSetting::SetGlobal(DatabaseInstance *db, DBConfig &conf config.options.enable_external_access = new_value; } +void EnableExternalAccessSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + if (db) { + throw InvalidInputException("Cannot change enable_external_access setting while database is running"); + } + config.options.enable_external_access = DBConfig().options.enable_external_access; +} + Value EnableExternalAccessSetting::GetSetting(ClientContext &context) { auto &config = DBConfig::GetConfig(context); return Value::BOOLEAN(config.options.enable_external_access); @@ -162048,6 +171233,10 @@ void EnableFSSTVectors::SetGlobal(DatabaseInstance *db, DBConfig &config, const config.options.enable_fsst_vectors = input.GetValue(); } +void EnableFSSTVectors::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + config.options.enable_fsst_vectors = DBConfig().options.enable_fsst_vectors; +} + Value EnableFSSTVectors::GetSetting(ClientContext &context) { auto &config = DBConfig::GetConfig(context); return Value::BOOLEAN(config.options.enable_fsst_vectors); @@ -162064,6 +171253,13 @@ void AllowUnsignedExtensionsSetting::SetGlobal(DatabaseInstance *db, DBConfig &c config.options.allow_unsigned_extensions = new_value; } +void AllowUnsignedExtensionsSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + if (db) { + throw InvalidInputException("Cannot change allow_unsigned_extensions setting while database is running"); + } + config.options.allow_unsigned_extensions = DBConfig().options.allow_unsigned_extensions; +} + Value AllowUnsignedExtensionsSetting::GetSetting(ClientContext &context) { auto &config = DBConfig::GetConfig(context); return Value::BOOLEAN(config.options.allow_unsigned_extensions); @@ -162076,14 +171272,42 @@ void EnableObjectCacheSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, config.options.object_cache_enable = input.GetValue(); } +void EnableObjectCacheSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + config.options.object_cache_enable = DBConfig().options.object_cache_enable; +} + Value EnableObjectCacheSetting::GetSetting(ClientContext &context) { auto &config = DBConfig::GetConfig(context); return Value::BOOLEAN(config.options.object_cache_enable); } +//===--------------------------------------------------------------------===// +// Enable HTTP Metadata Cache +//===--------------------------------------------------------------------===// +void EnableHTTPMetadataCacheSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { + config.options.http_metadata_cache_enable = input.GetValue(); +} + +void EnableHTTPMetadataCacheSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + config.options.http_metadata_cache_enable = DBConfig().options.http_metadata_cache_enable; +} + +Value EnableHTTPMetadataCacheSetting::GetSetting(ClientContext &context) { + auto &config = DBConfig::GetConfig(context); + return Value::BOOLEAN(config.options.http_metadata_cache_enable); +} + //===--------------------------------------------------------------------===// // Enable Profiling //===--------------------------------------------------------------------===// + +void EnableProfilingSetting::ResetLocal(ClientContext &context) { + auto &config = ClientConfig::GetConfig(context); + config.profiler_print_format = ClientConfig().profiler_print_format; + config.enable_profiler = ClientConfig().enable_profiler; + config.emit_profiler_output = ClientConfig().emit_profiler_output; +} + void EnableProfilingSetting::SetLocal(ClientContext &context, const Value &input) { auto parameter = StringUtil::Lower(input.ToString()); @@ -162119,9 +171343,30 @@ Value EnableProfilingSetting::GetSetting(ClientContext &context) { } } +//===--------------------------------------------------------------------===// +// Custom Extension Repository +//===--------------------------------------------------------------------===// + +void CustomExtensionRepository::ResetLocal(ClientContext &context) { + ClientConfig::GetConfig(context).custom_extension_repo = ClientConfig().custom_extension_repo; +} + +void CustomExtensionRepository::SetLocal(ClientContext &context, const Value &input) { + ClientConfig::GetConfig(context).custom_extension_repo = StringUtil::Lower(input.ToString()); +} + +Value CustomExtensionRepository::GetSetting(ClientContext &context) { + return Value(ClientConfig::GetConfig(context).custom_extension_repo); +} + //===--------------------------------------------------------------------===// // Enable Progress Bar //===--------------------------------------------------------------------===// + +void EnableProgressBarSetting::ResetLocal(ClientContext &context) { + ClientConfig::GetConfig(context).enable_progress_bar = ClientConfig().enable_progress_bar; +} + void EnableProgressBarSetting::SetLocal(ClientContext &context, const Value &input) { ClientConfig::GetConfig(context).enable_progress_bar = input.GetValue(); } @@ -162130,6 +171375,21 @@ Value EnableProgressBarSetting::GetSetting(ClientContext &context) { return Value::BOOLEAN(ClientConfig::GetConfig(context).enable_progress_bar); } +//===--------------------------------------------------------------------===// +// Enable Progress Bar Print +//===--------------------------------------------------------------------===// +void EnableProgressBarPrintSetting::SetLocal(ClientContext &context, const Value &input) { + ClientConfig::GetConfig(context).print_progress_bar = input.GetValue(); +} + +void EnableProgressBarPrintSetting::ResetLocal(ClientContext &context) { + ClientConfig::GetConfig(context).print_progress_bar = ClientConfig().print_progress_bar; +} + +Value EnableProgressBarPrintSetting::GetSetting(ClientContext &context) { + return Value::BOOLEAN(ClientConfig::GetConfig(context).print_progress_bar); +} + //===--------------------------------------------------------------------===// // Experimental Parallel CSV //===--------------------------------------------------------------------===// @@ -162137,6 +171397,10 @@ void ExperimentalParallelCSVSetting::SetGlobal(DatabaseInstance *db, DBConfig &c config.options.experimental_parallel_csv_reader = input.GetValue(); } +void ExperimentalParallelCSVSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + config.options.experimental_parallel_csv_reader = DBConfig().options.experimental_parallel_csv_reader; +} + Value ExperimentalParallelCSVSetting::GetSetting(ClientContext &context) { auto &config = DBConfig::GetConfig(context); return Value::BIGINT(config.options.experimental_parallel_csv_reader); @@ -162145,6 +171409,11 @@ Value ExperimentalParallelCSVSetting::GetSetting(ClientContext &context) { //===--------------------------------------------------------------------===// // Explain Output //===--------------------------------------------------------------------===// + +void ExplainOutputSetting::ResetLocal(ClientContext &context) { + ClientConfig::GetConfig(context).explain_output_type = ClientConfig().explain_output_type; +} + void ExplainOutputSetting::SetLocal(ClientContext &context, const Value &input) { auto parameter = StringUtil::Lower(input.ToString()); if (parameter == "all") { @@ -162179,6 +171448,10 @@ void ExternalThreadsSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, c config.options.external_threads = input.GetValue(); } +void ExternalThreadsSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + config.options.external_threads = DBConfig().options.external_threads; +} + Value ExternalThreadsSetting::GetSetting(ClientContext &context) { auto &config = DBConfig::GetConfig(context); return Value::BIGINT(config.options.external_threads); @@ -162187,6 +171460,11 @@ Value ExternalThreadsSetting::GetSetting(ClientContext &context) { //===--------------------------------------------------------------------===// // File Search Path //===--------------------------------------------------------------------===// +void FileSearchPathSetting::ResetLocal(ClientContext &context) { + auto &client_data = ClientData::Get(context); + client_data.file_search_path.clear(); +} + void FileSearchPathSetting::SetLocal(ClientContext &context, const Value &input) { auto parameter = input.ToString(); auto &client_data = ClientData::Get(context); @@ -162203,25 +171481,61 @@ Value FileSearchPathSetting::GetSetting(ClientContext &context) { //===--------------------------------------------------------------------===// void ForceCompressionSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { auto compression = StringUtil::Lower(input.ToString()); - if (compression == "none") { + if (compression == "none" || compression == "auto") { config.options.force_compression = CompressionType::COMPRESSION_AUTO; } else { auto compression_type = CompressionTypeFromString(compression); if (compression_type == CompressionType::COMPRESSION_AUTO) { - throw ParserException("Unrecognized option for PRAGMA force_compression, expected none, uncompressed, rle, " - "dictionary, pfor, bitpacking or fsst"); + auto compression_types = StringUtil::Join(ListCompressionTypes(), ", "); + throw ParserException("Unrecognized option for PRAGMA force_compression, expected %s", compression_types); } config.options.force_compression = compression_type; } } +void ForceCompressionSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + config.options.force_compression = DBConfig().options.force_compression; +} + Value ForceCompressionSetting::GetSetting(ClientContext &context) { - return Value(); + auto &config = DBConfig::GetConfig(*context.db); + return CompressionTypeToString(config.options.force_compression); +} + +//===--------------------------------------------------------------------===// +// Force Bitpacking mode +//===--------------------------------------------------------------------===// +void ForceBitpackingModeSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { + auto mode_str = StringUtil::Lower(input.ToString()); + if (mode_str == "none") { + config.options.force_bitpacking_mode = BitpackingMode::AUTO; + } else { + auto mode = BitpackingModeFromString(mode_str); + if (mode == BitpackingMode::AUTO) { + throw ParserException( + "Unrecognized option for force_bitpacking_mode, expected none, constant, constant_delta, " + "delta_for, or for"); + } + config.options.force_bitpacking_mode = mode; + } +} + +void ForceBitpackingModeSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + config.options.force_bitpacking_mode = DBConfig().options.force_bitpacking_mode; +} + +Value ForceBitpackingModeSetting::GetSetting(ClientContext &context) { + return Value(BitpackingModeToString(context.db->config.options.force_bitpacking_mode)); } //===--------------------------------------------------------------------===// // Home Directory //===--------------------------------------------------------------------===// + +void HomeDirectorySetting::ResetLocal(ClientContext &context) { + ClientConfig::GetConfig(context).home_directory = ClientConfig().home_directory; +} + void HomeDirectorySetting::SetLocal(ClientContext &context, const Value &input) { auto &config = ClientConfig::GetConfig(context); config.home_directory = input.IsNull() ? string() : input.ToString(); @@ -162235,6 +171549,13 @@ Value HomeDirectorySetting::GetSetting(ClientContext &context) { //===--------------------------------------------------------------------===// // Log Query Path //===--------------------------------------------------------------------===// + +void LogQueryPathSetting::ResetLocal(ClientContext &context) { + auto &client_data = ClientData::Get(context); + // TODO: verify that this does the right thing + client_data.log_query_writer = std::move(ClientData(context).log_query_writer); +} + void LogQueryPathSetting::SetLocal(ClientContext &context, const Value &input) { auto &client_data = ClientData::Get(context); auto path = input.ToString(); @@ -162253,9 +171574,30 @@ Value LogQueryPathSetting::GetSetting(ClientContext &context) { return client_data.log_query_writer ? Value(client_data.log_query_writer->path) : Value(); } +//===--------------------------------------------------------------------===// +// Immediate Transaction Mode +//===--------------------------------------------------------------------===// +void ImmediateTransactionModeSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Value &input) { + config.options.immediate_transaction_mode = BooleanValue::Get(input); +} + +void ImmediateTransactionModeSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + config.options.immediate_transaction_mode = DBConfig().options.immediate_transaction_mode; +} + +Value ImmediateTransactionModeSetting::GetSetting(ClientContext &context) { + auto &config = DBConfig::GetConfig(context); + return Value::BOOLEAN(config.options.immediate_transaction_mode); +} + //===--------------------------------------------------------------------===// // Maximum Expression Depth //===--------------------------------------------------------------------===// + +void MaximumExpressionDepthSetting::ResetLocal(ClientContext &context) { + ClientConfig::GetConfig(context).max_expression_depth = ClientConfig().max_expression_depth; +} + void MaximumExpressionDepthSetting::SetLocal(ClientContext &context, const Value &input) { ClientConfig::GetConfig(context).max_expression_depth = input.GetValue(); } @@ -162274,6 +171616,10 @@ void MaximumMemorySetting::SetGlobal(DatabaseInstance *db, DBConfig &config, con } } +void MaximumMemorySetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + config.SetDefaultMaxMemory(); +} + Value MaximumMemorySetting::GetSetting(ClientContext &context) { auto &config = DBConfig::GetConfig(context); return Value(StringUtil::BytesToHumanReadableString(config.options.maximum_memory)); @@ -162286,6 +171632,10 @@ void PasswordSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Va // nop } +void PasswordSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + // nop +} + Value PasswordSetting::GetSetting(ClientContext &context) { return Value(); } @@ -162293,6 +171643,11 @@ Value PasswordSetting::GetSetting(ClientContext &context) { //===--------------------------------------------------------------------===// // Perfect Hash Threshold //===--------------------------------------------------------------------===// + +void PerfectHashThresholdSetting::ResetLocal(ClientContext &context) { + ClientConfig::GetConfig(context).perfect_ht_threshold = ClientConfig().perfect_ht_threshold; +} + void PerfectHashThresholdSetting::SetLocal(ClientContext &context, const Value &input) { auto bits = input.GetValue(); if (bits < 0 || bits > 32) { @@ -162308,6 +171663,11 @@ Value PerfectHashThresholdSetting::GetSetting(ClientContext &context) { //===--------------------------------------------------------------------===// // PreserveIdentifierCase //===--------------------------------------------------------------------===// + +void PreserveIdentifierCase::ResetLocal(ClientContext &context) { + ClientConfig::GetConfig(context).preserve_identifier_case = ClientConfig().preserve_identifier_case; +} + void PreserveIdentifierCase::SetLocal(ClientContext &context, const Value &input) { ClientConfig::GetConfig(context).preserve_identifier_case = input.GetValue(); } @@ -162323,6 +171683,10 @@ void PreserveInsertionOrder::SetGlobal(DatabaseInstance *db, DBConfig &config, c config.options.preserve_insertion_order = input.GetValue(); } +void PreserveInsertionOrder::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + config.options.preserve_insertion_order = DBConfig().options.preserve_insertion_order; +} + Value PreserveInsertionOrder::GetSetting(ClientContext &context) { auto &config = DBConfig::GetConfig(context); return Value::BOOLEAN(config.options.preserve_insertion_order); @@ -162331,6 +171695,12 @@ Value PreserveInsertionOrder::GetSetting(ClientContext &context) { //===--------------------------------------------------------------------===// // Profiler History Size //===--------------------------------------------------------------------===// + +void ProfilerHistorySize::ResetLocal(ClientContext &context) { + auto &client_data = ClientData::Get(context); + client_data.query_profiler_history->ResetProfilerHistorySize(); +} + void ProfilerHistorySize::SetLocal(ClientContext &context, const Value &input) { auto size = input.GetValue(); if (size <= 0) { @@ -162347,6 +171717,11 @@ Value ProfilerHistorySize::GetSetting(ClientContext &context) { //===--------------------------------------------------------------------===// // Profile Output //===--------------------------------------------------------------------===// + +void ProfileOutputSetting::ResetLocal(ClientContext &context) { + ClientConfig::GetConfig(context).profiler_save_location = ClientConfig().profiler_save_location; +} + void ProfileOutputSetting::SetLocal(ClientContext &context, const Value &input) { auto &config = ClientConfig::GetConfig(context); auto parameter = input.ToString(); @@ -162361,6 +171736,13 @@ Value ProfileOutputSetting::GetSetting(ClientContext &context) { //===--------------------------------------------------------------------===// // Profiling Mode //===--------------------------------------------------------------------===// + +void ProfilingModeSetting::ResetLocal(ClientContext &context) { + ClientConfig::GetConfig(context).enable_profiler = ClientConfig().enable_profiler; + ClientConfig::GetConfig(context).enable_detailed_profiling = ClientConfig().enable_detailed_profiling; + ClientConfig::GetConfig(context).emit_profiler_output = ClientConfig().emit_profiler_output; +} + void ProfilingModeSetting::SetLocal(ClientContext &context, const Value &input) { auto parameter = StringUtil::Lower(input.ToString()); auto &config = ClientConfig::GetConfig(context); @@ -162388,6 +171770,12 @@ Value ProfilingModeSetting::GetSetting(ClientContext &context) { //===--------------------------------------------------------------------===// // Progress Bar Time //===--------------------------------------------------------------------===// + +void ProgressBarTimeSetting::ResetLocal(ClientContext &context) { + ClientConfig::GetConfig(context).wait_time = ClientConfig().wait_time; + ClientConfig::GetConfig(context).enable_progress_bar = ClientConfig().enable_progress_bar; +} + void ProgressBarTimeSetting::SetLocal(ClientContext &context, const Value &input) { ClientConfig::GetConfig(context).wait_time = input.GetValue(); ClientConfig::GetConfig(context).enable_progress_bar = true; @@ -162400,28 +171788,42 @@ Value ProgressBarTimeSetting::GetSetting(ClientContext &context) { //===--------------------------------------------------------------------===// // Schema //===--------------------------------------------------------------------===// +void SchemaSetting::ResetLocal(ClientContext &context) { + // FIXME: catalog_search_path is controlled by both SchemaSetting and SearchPathSetting + auto &client_data = ClientData::Get(context); + client_data.catalog_search_path->Reset(); +} + void SchemaSetting::SetLocal(ClientContext &context, const Value &input) { auto parameter = input.ToString(); auto &client_data = ClientData::Get(context); - client_data.catalog_search_path->Set(parameter, true); + client_data.catalog_search_path->Set(CatalogSearchEntry::Parse(parameter), true); } Value SchemaSetting::GetSetting(ClientContext &context) { - return SearchPathSetting::GetSetting(context); + auto &client_data = ClientData::Get(context); + return client_data.catalog_search_path->GetDefault().schema; } //===--------------------------------------------------------------------===// // Search Path //===--------------------------------------------------------------------===// +void SearchPathSetting::ResetLocal(ClientContext &context) { + // FIXME: catalog_search_path is controlled by both SchemaSetting and SearchPathSetting + auto &client_data = ClientData::Get(context); + client_data.catalog_search_path->Reset(); +} + void SearchPathSetting::SetLocal(ClientContext &context, const Value &input) { auto parameter = input.ToString(); auto &client_data = ClientData::Get(context); - client_data.catalog_search_path->Set(parameter, false); + client_data.catalog_search_path->Set(CatalogSearchEntry::ParseList(parameter), false); } Value SearchPathSetting::GetSetting(ClientContext &context) { auto &client_data = ClientData::Get(context); - return Value(StringUtil::Join(client_data.catalog_search_path->GetSetPaths(), ",")); + auto &set_paths = client_data.catalog_search_path->GetSetPaths(); + return Value(CatalogSearchEntry::ListToString(set_paths)); } //===--------------------------------------------------------------------===// @@ -162436,6 +171838,15 @@ void TempDirectorySetting::SetGlobal(DatabaseInstance *db, DBConfig &config, con } } +void TempDirectorySetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + config.options.temporary_directory = DBConfig().options.temporary_directory; + config.options.use_temporary_directory = DBConfig().options.use_temporary_directory; + if (db) { + auto &buffer_manager = BufferManager::GetBufferManager(*db); + buffer_manager.SetTemporaryDirectory(config.options.temporary_directory); + } +} + Value TempDirectorySetting::GetSetting(ClientContext &context) { auto &buffer_manager = BufferManager::GetBufferManager(context); return Value(buffer_manager.GetTemporaryDirectory()); @@ -162451,6 +171862,10 @@ void ThreadsSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Val } } +void ThreadsSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + config.SetDefaultMaxThreads(); +} + Value ThreadsSetting::GetSetting(ClientContext &context) { auto &config = DBConfig::GetConfig(context); return Value::BIGINT(config.options.maximum_threads); @@ -162463,6 +171878,10 @@ void UsernameSetting::SetGlobal(DatabaseInstance *db, DBConfig &config, const Va // nop } +void UsernameSetting::ResetGlobal(DatabaseInstance *db, DBConfig &config) { + // nop +} + Value UsernameSetting::GetSetting(ClientContext &context) { return Value(); } @@ -162473,14 +171892,15 @@ Value UsernameSetting::GetSetting(ClientContext &context) { + namespace duckdb { StreamQueryResult::StreamQueryResult(StatementType statement_type, StatementProperties properties, shared_ptr context_p, vector types, vector names) - : QueryResult(QueryResultType::STREAM_RESULT, statement_type, properties, move(types), move(names), - context_p->GetClientProperties()), - context(move(context_p)) { + : QueryResult(QueryResultType::STREAM_RESULT, statement_type, std::move(properties), std::move(types), + std::move(names), context_p->GetClientProperties()), + context(std::move(context_p)) { D_ASSERT(context); } @@ -162548,8 +171968,8 @@ unique_ptr StreamQueryResult::Materialize() { } collection->Append(append_state, *chunk); } - auto result = - make_unique(statement_type, properties, names, move(collection), client_properties); + auto result = make_unique(statement_type, properties, names, std::move(collection), + client_properties); if (HasError()) { return make_unique(GetErrorObject()); } @@ -162587,7 +172007,7 @@ ValidChecker::ValidChecker() : is_invalidated(false) { void ValidChecker::Invalidate(string error) { lock_guard l(invalidate_lock); this->is_invalidated = true; - this->invalidated_msg = move(error); + this->invalidated_msg = std::move(error); } bool ValidChecker::IsInvalidated() { @@ -162599,12 +172019,490 @@ string ValidChecker::InvalidatedMessage() { return invalidated_msg; } } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/column_lifetime_optimizer.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + +namespace duckdb { +class BoundColumnRefExpression; + +//! The ColumnLifetimeAnalyzer optimizer traverses the logical operator tree and ensures that columns are removed from +//! the plan when no longer required +class ColumnLifetimeAnalyzer : public LogicalOperatorVisitor { +public: + explicit ColumnLifetimeAnalyzer(bool is_root = false) : everything_referenced(is_root) { + } + + void VisitOperator(LogicalOperator &op) override; + +protected: + unique_ptr VisitReplace(BoundColumnRefExpression &expr, unique_ptr *expr_ptr) override; + unique_ptr VisitReplace(BoundReferenceExpression &expr, unique_ptr *expr_ptr) override; + +private: + //! Whether or not all the columns are referenced. This happens in the case of the root expression (because the + //! output implicitly refers all the columns below it) + bool everything_referenced; + //! The set of column references + column_binding_set_t column_references; + +private: + void StandardVisitOperator(LogicalOperator &op); + + void ExtractUnusedColumnBindings(vector bindings, column_binding_set_t &unused_bindings); + void GenerateProjectionMap(vector bindings, column_binding_set_t &unused_bindings, + vector &map); +}; +} // namespace duckdb + + + + + + + + +namespace duckdb { + +void ColumnLifetimeAnalyzer::ExtractUnusedColumnBindings(vector bindings, + column_binding_set_t &unused_bindings) { + for (idx_t i = 0; i < bindings.size(); i++) { + if (column_references.find(bindings[i]) == column_references.end()) { + unused_bindings.insert(bindings[i]); + } + } +} + +void ColumnLifetimeAnalyzer::GenerateProjectionMap(vector bindings, + column_binding_set_t &unused_bindings, + vector &projection_map) { + if (unused_bindings.empty()) { + return; + } + // now iterate over the result bindings of the child + for (idx_t i = 0; i < bindings.size(); i++) { + // if this binding does not belong to the unused bindings, add it to the projection map + if (unused_bindings.find(bindings[i]) == unused_bindings.end()) { + projection_map.push_back(i); + } + } + if (projection_map.size() == bindings.size()) { + projection_map.clear(); + } +} + +void ColumnLifetimeAnalyzer::StandardVisitOperator(LogicalOperator &op) { + LogicalOperatorVisitor::VisitOperatorExpressions(op); + if (op.type == LogicalOperatorType::LOGICAL_DELIM_JOIN) { + // visit the duplicate eliminated columns on the LHS, if any + auto &delim_join = (LogicalDelimJoin &)op; + for (auto &expr : delim_join.duplicate_eliminated_columns) { + VisitExpression(&expr); + } + } + LogicalOperatorVisitor::VisitOperatorChildren(op); +} + +void ColumnLifetimeAnalyzer::VisitOperator(LogicalOperator &op) { + switch (op.type) { + case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY: { + // FIXME: groups that are not referenced can be removed from projection + // recurse into the children of the aggregate + ColumnLifetimeAnalyzer analyzer; + analyzer.VisitOperatorExpressions(op); + analyzer.VisitOperator(*op.children[0]); + return; + } + case LogicalOperatorType::LOGICAL_DELIM_JOIN: + case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: { + if (everything_referenced) { + break; + } + auto &comp_join = (LogicalComparisonJoin &)op; + if (comp_join.join_type == JoinType::MARK || comp_join.join_type == JoinType::SEMI || + comp_join.join_type == JoinType::ANTI) { + break; + } + // FIXME for now, we only push into the projection map for equality (hash) joins + // FIXME: add projection to LHS as well + bool has_equality = false; + for (auto &cond : comp_join.conditions) { + if (cond.comparison == ExpressionType::COMPARE_EQUAL) { + has_equality = true; + } + } + if (!has_equality) { + break; + } + // now, for each of the columns of the RHS, check which columns need to be projected + column_binding_set_t unused_bindings; + ExtractUnusedColumnBindings(op.children[1]->GetColumnBindings(), unused_bindings); + + // now recurse into the filter and its children + StandardVisitOperator(op); + + // then generate the projection map + GenerateProjectionMap(op.children[1]->GetColumnBindings(), unused_bindings, comp_join.right_projection_map); + return; + } + case LogicalOperatorType::LOGICAL_UNION: + case LogicalOperatorType::LOGICAL_EXCEPT: + case LogicalOperatorType::LOGICAL_INTERSECT: + // for set operations we don't remove anything, just recursively visit the children + // FIXME: for UNION we can remove unreferenced columns as long as everything_referenced is false (i.e. we + // encounter a UNION node that is not preceded by a DISTINCT) + for (auto &child : op.children) { + ColumnLifetimeAnalyzer analyzer(true); + analyzer.VisitOperator(*child); + } + return; + case LogicalOperatorType::LOGICAL_PROJECTION: { + // then recurse into the children of this projection + ColumnLifetimeAnalyzer analyzer; + analyzer.VisitOperatorExpressions(op); + analyzer.VisitOperator(*op.children[0]); + return; + } + case LogicalOperatorType::LOGICAL_DISTINCT: { + // distinct, all projected columns are used for the DISTINCT computation + // mark all columns as used and continue to the children + // FIXME: DISTINCT with expression list does not implicitly reference everything + everything_referenced = true; + break; + } + case LogicalOperatorType::LOGICAL_FILTER: { + auto &filter = (LogicalFilter &)op; + if (everything_referenced) { + break; + } + // filter, figure out which columns are not needed after the filter + column_binding_set_t unused_bindings; + ExtractUnusedColumnBindings(op.children[0]->GetColumnBindings(), unused_bindings); + + // now recurse into the filter and its children + StandardVisitOperator(op); + + // then generate the projection map + GenerateProjectionMap(op.children[0]->GetColumnBindings(), unused_bindings, filter.projection_map); + return; + } + default: + break; + } + StandardVisitOperator(op); +} + +unique_ptr ColumnLifetimeAnalyzer::VisitReplace(BoundColumnRefExpression &expr, + unique_ptr *expr_ptr) { + column_references.insert(expr.binding); + return nullptr; +} + +unique_ptr ColumnLifetimeAnalyzer::VisitReplace(BoundReferenceExpression &expr, + unique_ptr *expr_ptr) { + // BoundReferenceExpression should not be used here yet, they only belong in the physical plan + throw InternalException("BoundReferenceExpression should not be used here yet!"); +} + +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/common_aggregate_optimizer.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { +//! The CommonAggregateOptimizer optimizer eliminates duplicate aggregates from aggregate nodes +class CommonAggregateOptimizer : public LogicalOperatorVisitor { +public: + void VisitOperator(LogicalOperator &op) override; + +private: + unique_ptr VisitReplace(BoundColumnRefExpression &expr, unique_ptr *expr_ptr) override; + + void ExtractCommonAggregates(LogicalAggregate &aggr); + +private: + column_binding_map_t aggregate_map; +}; +} // namespace duckdb + + + + + + + +namespace duckdb { + +void CommonAggregateOptimizer::VisitOperator(LogicalOperator &op) { + LogicalOperatorVisitor::VisitOperator(op); + switch (op.type) { + case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY: + ExtractCommonAggregates((LogicalAggregate &)op); + break; + default: + break; + } +} + +unique_ptr CommonAggregateOptimizer::VisitReplace(BoundColumnRefExpression &expr, + unique_ptr *expr_ptr) { + // check if this column ref points to an aggregate that was remapped; if it does we remap it + auto entry = aggregate_map.find(expr.binding); + if (entry != aggregate_map.end()) { + expr.binding = entry->second; + } + return nullptr; +} + +void CommonAggregateOptimizer::ExtractCommonAggregates(LogicalAggregate &aggr) { + expression_map_t aggregate_remap; + idx_t total_erased = 0; + for (idx_t i = 0; i < aggr.expressions.size(); i++) { + idx_t original_index = i + total_erased; + auto entry = aggregate_remap.find(aggr.expressions[i].get()); + if (entry == aggregate_remap.end()) { + // aggregate does not exist yet: add it to the map + aggregate_remap[aggr.expressions[i].get()] = i; + if (i != original_index) { + // this aggregate is not erased, however an agregate BEFORE it has been erased + // so we need to remap this aggregaet + ColumnBinding original_binding(aggr.aggregate_index, original_index); + ColumnBinding new_binding(aggr.aggregate_index, i); + aggregate_map[original_binding] = new_binding; + } + } else { + // aggregate already exists! we can remove this entry + total_erased++; + aggr.expressions.erase(aggr.expressions.begin() + i); + i--; + // we need to remap any references to this aggregate so they point to the other aggregate + ColumnBinding original_binding(aggr.aggregate_index, original_index); + ColumnBinding new_binding(aggr.aggregate_index, entry->second); + aggregate_map[original_binding] = new_binding; + } + } +} + +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/cse_optimizer.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + +namespace duckdb { +class Binder; +struct CSEReplacementState; + +//! The CommonSubExpression optimizer traverses the expressions of a LogicalOperator to look for duplicate expressions +//! if there are any, it pushes a projection under the operator that resolves these expressions +class CommonSubExpressionOptimizer : public LogicalOperatorVisitor { +public: + explicit CommonSubExpressionOptimizer(Binder &binder) : binder(binder) { + } + +public: + void VisitOperator(LogicalOperator &op) override; + +private: + //! First iteration: count how many times each expression occurs + void CountExpressions(Expression &expr, CSEReplacementState &state); + //! Second iteration: perform the actual replacement of the duplicate expressions with common subexpressions nodes + void PerformCSEReplacement(unique_ptr *expr, CSEReplacementState &state); + + //! Main method to extract common subexpressions + void ExtractCommonSubExpresions(LogicalOperator &op); + +private: + Binder &binder; +}; +} // namespace duckdb + + + + + + + + + +namespace duckdb { + +//! The CSENode contains information about a common subexpression; how many times it occurs, and the column index in the +//! underlying projection +struct CSENode { + idx_t count; + idx_t column_index; + + CSENode() : count(1), column_index(DConstants::INVALID_INDEX) { + } +}; + +//! The CSEReplacementState +struct CSEReplacementState { + //! The projection index of the new projection + idx_t projection_index; + //! Map of expression -> CSENode + expression_map_t expression_count; + //! Map of column bindings to column indexes in the projection expression list + column_binding_map_t column_map; + //! The set of expressions of the resulting projection + vector> expressions; + //! Cached expressions that are kept around so the expression_map always contains valid expressions + vector> cached_expressions; +}; + +void CommonSubExpressionOptimizer::VisitOperator(LogicalOperator &op) { + switch (op.type) { + case LogicalOperatorType::LOGICAL_PROJECTION: + case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY: + ExtractCommonSubExpresions(op); + break; + default: + break; + } + LogicalOperatorVisitor::VisitOperator(op); +} + +void CommonSubExpressionOptimizer::CountExpressions(Expression &expr, CSEReplacementState &state) { + // we only consider expressions with children for CSE elimination + switch (expr.expression_class) { + case ExpressionClass::BOUND_COLUMN_REF: + case ExpressionClass::BOUND_CONSTANT: + case ExpressionClass::BOUND_PARAMETER: + // skip conjunctions and case, since short-circuiting might be incorrectly disabled otherwise + case ExpressionClass::BOUND_CONJUNCTION: + case ExpressionClass::BOUND_CASE: + return; + default: + break; + } + if (expr.expression_class != ExpressionClass::BOUND_AGGREGATE && !expr.HasSideEffects()) { + // we can't move aggregates to a projection, so we only consider the children of the aggregate + auto node = state.expression_count.find(&expr); + if (node == state.expression_count.end()) { + // first time we encounter this expression, insert this node with [count = 1] + state.expression_count[&expr] = CSENode(); + } else { + // we encountered this expression before, increment the occurrence count + node->second.count++; + } + } + // recursively count the children + ExpressionIterator::EnumerateChildren(expr, [&](Expression &child) { CountExpressions(child, state); }); +} + +void CommonSubExpressionOptimizer::PerformCSEReplacement(unique_ptr *expr_ptr, CSEReplacementState &state) { + Expression &expr = **expr_ptr; + if (expr.expression_class == ExpressionClass::BOUND_COLUMN_REF) { + auto &bound_column_ref = (BoundColumnRefExpression &)expr; + // bound column ref, check if this one has already been recorded in the expression list + auto column_entry = state.column_map.find(bound_column_ref.binding); + if (column_entry == state.column_map.end()) { + // not there yet: push the expression + idx_t new_column_index = state.expressions.size(); + state.column_map[bound_column_ref.binding] = new_column_index; + state.expressions.push_back(make_unique( + bound_column_ref.alias, bound_column_ref.return_type, bound_column_ref.binding)); + bound_column_ref.binding = ColumnBinding(state.projection_index, new_column_index); + } else { + // else: just update the column binding! + bound_column_ref.binding = ColumnBinding(state.projection_index, column_entry->second); + } + return; + } + // check if this child is eligible for CSE elimination + bool can_cse = expr.expression_class != ExpressionClass::BOUND_CONJUNCTION && + expr.expression_class != ExpressionClass::BOUND_CASE; + if (can_cse && state.expression_count.find(&expr) != state.expression_count.end()) { + auto &node = state.expression_count[&expr]; + if (node.count > 1) { + // this expression occurs more than once! push it into the projection + // check if it has already been pushed into the projection + auto alias = expr.alias; + auto type = expr.return_type; + if (node.column_index == DConstants::INVALID_INDEX) { + // has not been pushed yet: push it + node.column_index = state.expressions.size(); + state.expressions.push_back(std::move(*expr_ptr)); + } else { + state.cached_expressions.push_back(std::move(*expr_ptr)); + } + // replace the original expression with a bound column ref + *expr_ptr = make_unique(alias, type, + ColumnBinding(state.projection_index, node.column_index)); + return; + } + } + // this expression only occurs once, we can't perform CSE elimination + // look into the children to see if we can replace them + ExpressionIterator::EnumerateChildren(expr, + [&](unique_ptr &child) { PerformCSEReplacement(&child, state); }); +} +void CommonSubExpressionOptimizer::ExtractCommonSubExpresions(LogicalOperator &op) { + D_ASSERT(op.children.size() == 1); + + // first we count for each expression with children how many types it occurs + CSEReplacementState state; + LogicalOperatorVisitor::EnumerateExpressions( + op, [&](unique_ptr *child) { CountExpressions(**child, state); }); + // check if there are any expressions to extract + bool perform_replacement = false; + for (auto &expr : state.expression_count) { + if (expr.second.count > 1) { + perform_replacement = true; + break; + } + } + if (!perform_replacement) { + // no CSEs to extract + return; + } + state.projection_index = binder.GenerateTableIndex(); + // we found common subexpressions to extract + // now we iterate over all the expressions and perform the actual CSE elimination + LogicalOperatorVisitor::EnumerateExpressions( + op, [&](unique_ptr *child) { PerformCSEReplacement(child, state); }); + D_ASSERT(state.expressions.size() > 0); + // create a projection node as the child of this node + auto projection = make_unique(state.projection_index, std::move(state.expressions)); + projection->children.push_back(std::move(op.children[0])); + op.children[0] = std::move(projection); +} +} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/join_order_optimizer.hpp +// duckdb/optimizer/deliminator.hpp // // //===----------------------------------------------------------------------===// @@ -162616,13 +172514,40 @@ string ValidChecker::InvalidatedMessage() { +namespace duckdb { + +class Optimizer; +class DeliminatorPlanUpdater; + +//! The Deliminator optimizer traverses the logical operator tree and removes any redundant DelimGets/DelimJoins +class Deliminator { +public: + explicit Deliminator(ClientContext &context) : context(context) { + } + //! Perform DelimJoin elimination + unique_ptr Optimize(unique_ptr op); + +private: + //! Find Joins with a DelimGet that can be removed + void FindCandidates(unique_ptr *op_ptr, vector *> &candidates); + //! Try to remove a Join with a DelimGet, returns true if it was successful + bool RemoveCandidate(unique_ptr *plan, unique_ptr *candidate, + DeliminatorPlanUpdater &updater); + //! Try to remove an inequality Join with a DelimGet, returns true if it was successful + bool RemoveInequalityCandidate(unique_ptr *plan, unique_ptr *candidate, + DeliminatorPlanUpdater &updater); + +private: + ClientContext &context; +}; +} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/cardinality_estimator.hpp +// duckdb/optimizer/join_order/join_order_optimizer.hpp // // //===----------------------------------------------------------------------===// @@ -162632,6 +172557,18 @@ string ValidChecker::InvalidatedMessage() { +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/join_order/cardinality_estimator.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + @@ -162665,7 +172602,7 @@ struct NodeOp { unique_ptr node; LogicalOperator *op; - NodeOp(unique_ptr node, LogicalOperator *op) : node(move(node)), op(op) {}; + NodeOp(unique_ptr node, LogicalOperator *op) : node(std::move(node)), op(op) {}; }; struct Subgraph2Denominator { @@ -162690,13 +172627,11 @@ class CardinalityEstimator { vector relations_to_tdoms; +public: static constexpr double DEFAULT_SELECTIVITY = 0.2; -public: static void VerifySymmetry(JoinNode *result, JoinNode *entry); - void AssertEquivalentRelationSize(); - //! given a binding of (relation, column) used for DP, and a (table, column) in that catalog //! Add the key value entry into the relation_column_to_original_column void AddRelationToColumnMapping(ColumnBinding key, ColumnBinding value); @@ -162713,7 +172648,7 @@ class CardinalityEstimator { void UpdateTotalDomains(JoinNode *node, LogicalOperator *op); void InitEquivalentRelations(vector> *filter_infos); - void InitCardinalityEstimatorProps(vector *node_ops, vector> *filter_infos); + void InitCardinalityEstimatorProps(vector *node_ops, vector> *filter_infos); double EstimateCardinalityWithSet(JoinRelationSet *new_set); void EstimateBaseTableCardinality(JoinNode *node, LogicalOperator *op); double EstimateCrossProduct(const JoinNode *left, const JoinNode *right); @@ -162745,6 +172680,11 @@ class CardinalityEstimator { } // namespace duckdb + + + + + #include namespace duckdb { @@ -162781,8 +172721,7 @@ class JoinOrderOptimizer { //! The set of filter infos created from the extracted filters vector> filter_infos; //! A map of all expressions a given expression has to be equivalent to. This is used to add "implied join edges". - //! i.e. in the join A=B AND B=C, the equivalence set of {B} is {A, C}, thus we can add an implied join edge {A <-> - //! C} + //! i.e. in the join A=B AND B=C, the equivalence set of {B} is {A, C}, thus we can add an implied join edge {A = C} expression_map_t> equivalence_sets; CardinalityEstimator cardinality_estimator; @@ -162829,6 +172768,7 @@ class JoinOrderOptimizer { void UpdateDPTree(JoinNode *new_plan); void UpdateJoinNodesInFullPlan(JoinNode *node); + bool NodeInFullPlan(JoinNode *node); std::pair> GenerateJoins(vector> &extracted_relations, JoinNode *node); @@ -162843,577 +172783,439 @@ class JoinOrderOptimizer { + + namespace duckdb { -static TableCatalogEntry *GetCatalogTableEntry(LogicalOperator *op) { - if (op->type == LogicalOperatorType::LOGICAL_GET) { - auto get = (LogicalGet *)op; - TableCatalogEntry *entry = get->GetTable(); - return entry; - } - for (auto &child : op->children) { - TableCatalogEntry *entry = GetCatalogTableEntry(child.get()); - if (entry != nullptr) { - return entry; - } +class DeliminatorPlanUpdater : LogicalOperatorVisitor { +public: + explicit DeliminatorPlanUpdater(ClientContext &context) : context(context) { } - return nullptr; -} + //! Update the plan after a DelimGet has been removed + void VisitOperator(LogicalOperator &op) override; + void VisitExpression(unique_ptr *expression) override; -// The filter was made on top of a logical sample or other projection, -// but no specific columns are referenced. See issue 4978 number 4. -bool CardinalityEstimator::EmptyFilter(FilterInfo *filter_info) { - if (!filter_info->left_set && !filter_info->right_set) { - return true; - } - return false; -} +public: + ClientContext &context; -void CardinalityEstimator::AddRelationTdom(FilterInfo *filter_info) { - D_ASSERT(filter_info->set->count >= 1); - for (const RelationsToTDom &r2tdom : relations_to_tdoms) { - auto &i_set = r2tdom.equivalent_relations; - if (i_set.find(filter_info->left_binding) != i_set.end()) { - // found an equivalent filter - return; - } + expression_map_t expr_map; + column_binding_map_t projection_map; + column_binding_map_t reverse_proj_or_agg_map; + unique_ptr temp_ptr; +}; + +static idx_t DelimGetCount(LogicalOperator &op) { + if (op.type == LogicalOperatorType::LOGICAL_DELIM_GET) { + return 1; } - auto key = ColumnBinding(filter_info->left_binding.table_index, filter_info->left_binding.column_index); - column_binding_set_t tmp({key}); - relations_to_tdoms.emplace_back(RelationsToTDom(tmp)); + idx_t child_count = 0; + for (auto &child : op.children) { + child_count += DelimGetCount(*child); + } + return child_count; } -bool CardinalityEstimator::SingleColumnFilter(FilterInfo *filter_info) { - if (filter_info->left_set && filter_info->right_set) { - // Both set - return false; - } - if (EmptyFilter(filter_info)) { +static bool IsEqualityJoinCondition(JoinCondition &cond) { + switch (cond.comparison) { + case ExpressionType::COMPARE_EQUAL: + case ExpressionType::COMPARE_NOT_DISTINCT_FROM: + return true; + default: return false; } - return true; } -vector CardinalityEstimator::DetermineMatchingEquivalentSets(FilterInfo *filter_info) { - vector matching_equivalent_sets; - auto equivalent_relation_index = 0; - - for (const RelationsToTDom &r2tdom : relations_to_tdoms) { - auto &i_set = r2tdom.equivalent_relations; - if (i_set.find(filter_info->left_binding) != i_set.end()) { - matching_equivalent_sets.push_back(equivalent_relation_index); - } else if (i_set.find(filter_info->right_binding) != i_set.end()) { - // don't add both left and right to the matching_equivalent_sets - // since both left and right get added to that index anyway. - matching_equivalent_sets.push_back(equivalent_relation_index); - } - equivalent_relation_index++; +static bool InequalityDelimJoinCanBeEliminated(JoinType &join_type) { + switch (join_type) { + case JoinType::ANTI: + case JoinType::MARK: + case JoinType::SEMI: + case JoinType::SINGLE: + return true; + default: + return false; } - return matching_equivalent_sets; } -void CardinalityEstimator::AddToEquivalenceSets(FilterInfo *filter_info, vector matching_equivalent_sets) { - D_ASSERT(matching_equivalent_sets.size() <= 2); - if (matching_equivalent_sets.size() > 1) { - // an equivalence relation is connecting to sets of equivalence relations - // so push all relations from the second set into the first. Later we will delete - // the second set. - for (ColumnBinding i : relations_to_tdoms.at(matching_equivalent_sets[1]).equivalent_relations) { - relations_to_tdoms.at(matching_equivalent_sets[0]).equivalent_relations.insert(i); +void DeliminatorPlanUpdater::VisitOperator(LogicalOperator &op) { + VisitOperatorChildren(op); + VisitOperatorExpressions(op); + if (op.type == LogicalOperatorType::LOGICAL_DELIM_JOIN && DelimGetCount(op) == 0) { + auto &delim_join = (LogicalDelimJoin &)op; + auto decs = &delim_join.duplicate_eliminated_columns; + for (auto &cond : delim_join.conditions) { + if (!IsEqualityJoinCondition(cond)) { + continue; + } + auto rhs = cond.right.get(); + while (rhs->type == ExpressionType::OPERATOR_CAST) { + auto &cast = (BoundCastExpression &)*rhs; + rhs = cast.child.get(); + } + if (rhs->type != ExpressionType::BOUND_COLUMN_REF) { + throw InternalException("Error in Deliminator: expected a bound column reference"); + } + auto &colref = (BoundColumnRefExpression &)*rhs; + if (projection_map.find(colref.binding) != projection_map.end()) { + // value on the right is a projection of removed DelimGet + for (idx_t i = 0; i < decs->size(); i++) { + if (decs->at(i)->Equals(cond.left.get())) { + // the value on the left no longer needs to be a duplicate-eliminated column + decs->erase(decs->begin() + i); + break; + } + } + // whether we applied an IS NOT NULL filter + cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM; + } + } + // change type if there are no more duplicate-eliminated columns + if (decs->empty()) { + delim_join.type = LogicalOperatorType::LOGICAL_COMPARISON_JOIN; + // sub-plans with DelimGets are not re-orderable (yet), however, we removed all DelimGet of this DelimJoin + // the DelimGets are on the RHS of the DelimJoin, so we can call the JoinOrderOptimizer on the RHS now + JoinOrderOptimizer optimizer(context); + delim_join.children[1] = optimizer.Optimize(std::move(delim_join.children[1])); } - relations_to_tdoms.at(matching_equivalent_sets[1]).equivalent_relations.clear(); - relations_to_tdoms.at(matching_equivalent_sets[0]).filters.push_back(filter_info); - // add all values of one set to the other, delete the empty one - } else if (matching_equivalent_sets.size() == 1) { - auto &tdom_i = relations_to_tdoms.at(matching_equivalent_sets.at(0)); - tdom_i.equivalent_relations.insert(filter_info->left_binding); - tdom_i.equivalent_relations.insert(filter_info->right_binding); - tdom_i.filters.push_back(filter_info); - } else if (matching_equivalent_sets.empty()) { - column_binding_set_t tmp; - tmp.insert(filter_info->left_binding); - tmp.insert(filter_info->right_binding); - relations_to_tdoms.emplace_back(RelationsToTDom(tmp)); - relations_to_tdoms.back().filters.push_back(filter_info); } } -void CardinalityEstimator::AddRelationToColumnMapping(ColumnBinding key, ColumnBinding value) { - relation_column_to_original_column[key] = value; -} - -void CardinalityEstimator::CopyRelationMap(column_binding_map_t &child_binding_map) { - for (auto &binding_map : relation_column_to_original_column) { - child_binding_map[binding_map.first] = binding_map.second; +void DeliminatorPlanUpdater::VisitExpression(unique_ptr *expression) { + if (expr_map.find(expression->get()) != expr_map.end()) { + *expression = expr_map[expression->get()]->Copy(); + } else { + VisitExpressionChildren(**expression); } } -void CardinalityEstimator::AddColumnToRelationMap(idx_t table_index, idx_t column_index) { - relation_attributes[table_index].columns.insert(column_index); -} +unique_ptr Deliminator::Optimize(unique_ptr op) { + vector *> candidates; + FindCandidates(&op, candidates); -void CardinalityEstimator::InitEquivalentRelations(vector> *filter_infos) { - // For each filter, we fill keep track of the index of the equivalent relation set - // the left and right relation needs to be added to. - for (auto &filter : *filter_infos) { - if (SingleColumnFilter(filter.get())) { - // Filter on one relation, (i.e string or range filter on a column). - // Grab the first relation and add it to the equivalence_relations - AddRelationTdom(filter.get()); - continue; - } else if (EmptyFilter(filter.get())) { - continue; + for (auto &candidate : candidates) { + DeliminatorPlanUpdater updater(context); + if (RemoveCandidate(&op, candidate, updater)) { + updater.VisitOperator(*op); } - D_ASSERT(filter->left_set->count >= 1); - D_ASSERT(filter->right_set->count >= 1); - - auto matching_equivalent_sets = DetermineMatchingEquivalentSets(filter.get()); - AddToEquivalenceSets(filter.get(), matching_equivalent_sets); } + return op; } -void CardinalityEstimator::VerifySymmetry(JoinNode *result, JoinNode *entry) { - if (result->GetCardinality() != entry->GetCardinality()) { - // Currently it's possible that some entries are cartesian joins. - // When this is the case, you don't always have symmetry, but - // if the cost of the result is less, then just assure the cardinality - // is also less, then you have the same effect of symmetry. - D_ASSERT(ceil(result->GetCardinality()) <= ceil(entry->GetCardinality()) || - floor(result->GetCardinality()) <= floor(entry->GetCardinality())); +void Deliminator::FindCandidates(unique_ptr *op_ptr, + vector *> &candidates) { + auto op = op_ptr->get(); + // search children before adding, so the deepest candidates get added first + for (auto &child : op->children) { + FindCandidates(&child, candidates); + } + // search for projection/aggregate + if (op->type != LogicalOperatorType::LOGICAL_PROJECTION && + op->type != LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY) { + return; + } + // followed by a join + if (op->children[0]->type != LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { + return; + } + auto &join = *op->children[0]; + // with a DelimGet as a direct child (left or right) + if (join.children[0]->type == LogicalOperatorType::LOGICAL_DELIM_GET || + join.children[1]->type == LogicalOperatorType::LOGICAL_DELIM_GET) { + candidates.push_back(op_ptr); + return; + } + // or a filter followed by a DelimGet (left) + if (join.children[0]->type == LogicalOperatorType::LOGICAL_FILTER && + join.children[0]->children[0]->type == LogicalOperatorType::LOGICAL_DELIM_GET) { + candidates.push_back(op_ptr); + return; + } + // filter followed by a DelimGet (right) + if (join.children[1]->type == LogicalOperatorType::LOGICAL_FILTER && + join.children[1]->children[0]->type == LogicalOperatorType::LOGICAL_DELIM_GET) { + candidates.push_back(op_ptr); + return; } } -void CardinalityEstimator::InitTotalDomains() { - auto remove_start = std::remove_if(relations_to_tdoms.begin(), relations_to_tdoms.end(), - [](RelationsToTDom &r_2_tdom) { return r_2_tdom.equivalent_relations.empty(); }); - relations_to_tdoms.erase(remove_start, relations_to_tdoms.end()); -} - -double CardinalityEstimator::ComputeCost(JoinNode *left, JoinNode *right, double expected_cardinality) { - return expected_cardinality + left->GetCost() + right->GetCost(); +static bool OperatorIsDelimGet(LogicalOperator &op) { + if (op.type == LogicalOperatorType::LOGICAL_DELIM_GET) { + return true; + } + if (op.type == LogicalOperatorType::LOGICAL_FILTER && + op.children[0]->type == LogicalOperatorType::LOGICAL_DELIM_GET) { + return true; + } + return false; } -double CardinalityEstimator::EstimateCrossProduct(const JoinNode *left, const JoinNode *right) { - // need to explicity use double here, otherwise auto converts it to an int, then - // there is an autocast in the return. - return left->GetCardinality() >= (NumericLimits::Maximum() / right->GetCardinality()) - ? NumericLimits::Maximum() - : left->GetCardinality() * right->GetCardinality(); +static bool ChildJoinTypeCanBeDeliminated(JoinType &join_type) { + switch (join_type) { + case JoinType::INNER: + case JoinType::SEMI: + return true; + default: + return false; + } } -void CardinalityEstimator::AddRelationColumnMapping(LogicalGet *get, idx_t relation_id) { - for (idx_t it = 0; it < get->column_ids.size(); it++) { - auto key = ColumnBinding(relation_id, it); - auto value = ColumnBinding(get->table_index, get->column_ids[it]); - AddRelationToColumnMapping(key, value); +bool Deliminator::RemoveCandidate(unique_ptr *plan, unique_ptr *candidate, + DeliminatorPlanUpdater &updater) { + auto &proj_or_agg = **candidate; + auto &join = (LogicalComparisonJoin &)*proj_or_agg.children[0]; + if (!ChildJoinTypeCanBeDeliminated(join.join_type)) { + return false; } -} - -void UpdateDenom(Subgraph2Denominator *relation_2_denom, RelationsToTDom *relation_to_tdom) { - relation_2_denom->denom *= - relation_to_tdom->has_tdom_hll ? relation_to_tdom->tdom_hll : relation_to_tdom->tdom_no_hll; -} -void FindSubgraphMatchAndMerge(Subgraph2Denominator &merge_to, idx_t find_me, - vector::iterator subgraph, - vector::iterator end) { - for (; subgraph != end; subgraph++) { - if (subgraph->relations.count(find_me) >= 1) { - for (auto &relation : subgraph->relations) { - merge_to.relations.insert(relation); - } - subgraph->relations.clear(); - merge_to.denom *= subgraph->denom; - return; - } + // get the index (left or right) of the DelimGet side of the join + idx_t delim_idx = OperatorIsDelimGet(*join.children[0]) ? 0 : 1; + D_ASSERT(OperatorIsDelimGet(*join.children[delim_idx])); + // get the filter (if any) + LogicalFilter *filter = nullptr; + if (join.children[delim_idx]->type == LogicalOperatorType::LOGICAL_FILTER) { + filter = (LogicalFilter *)join.children[delim_idx].get(); } -} - -double CardinalityEstimator::EstimateCardinalityWithSet(JoinRelationSet *new_set) { - double numerator = 1; - unordered_set actual_set; - for (idx_t i = 0; i < new_set->count; i++) { - numerator *= relation_attributes[new_set->relations[i]].cardinality; - actual_set.insert(new_set->relations[i]); + auto &delim_get = (LogicalDelimGet &)*(filter ? filter->children[0].get() : join.children[delim_idx].get()); + if (join.conditions.size() != delim_get.chunk_types.size()) { + // joining with DelimGet adds new information + return false; } - vector subgraphs; - bool done = false; - bool found_match = false; - - // Finding the denominator is tricky. You need to go through the tdoms in decreasing order - // Then loop through all filters in the equivalence set of the tdom to see if both the - // left and right relations are in the new set, if so you can use that filter. - // You must also make sure that the filters all relations in the given set, so we use subgraphs - // that should eventually merge into one connected graph that joins all the relations - // TODO: Implement a method to cache subgraphs so you don't have to build them up every - // time the cardinality of a new set is requested - - // relations_to_tdoms has already been sorted. - for (auto &relation_2_tdom : relations_to_tdoms) { - // loop through each filter in the tdom. - if (done) { - break; + // check if joining with the DelimGet is redundant, and collect relevant column information + bool all_equality_conditions = true; + vector nulls_are_not_equal_exprs; + for (auto &cond : join.conditions) { + all_equality_conditions = all_equality_conditions && IsEqualityJoinCondition(cond); + auto delim_side = delim_idx == 0 ? cond.left.get() : cond.right.get(); + auto other_side = delim_idx == 0 ? cond.right.get() : cond.left.get(); + if (delim_side->type != ExpressionType::BOUND_COLUMN_REF) { + // non-colref e.g. expression -(4, 1) in 4-i=j where i is from DelimGet + // FIXME: might be possible to also eliminate these + return false; } - for (auto &filter : relation_2_tdom.filters) { - if (actual_set.count(filter->left_binding.table_index) == 0 || - actual_set.count(filter->right_binding.table_index) == 0) { - continue; - } - // the join filter is on relations in the new set. - found_match = false; - vector::iterator it; - for (it = subgraphs.begin(); it != subgraphs.end(); it++) { - auto left_in = it->relations.count(filter->left_binding.table_index); - auto right_in = it->relations.count(filter->right_binding.table_index); - if (left_in && right_in) { - // if both left and right bindings are in the subgraph, continue. - // This means another filter is connecting relations already in the - // subgraph it, but it has a tdom that is less, and we don't care. - found_match = true; - continue; - } - if (!left_in && !right_in) { - // if both left and right bindings are *not* in the subgraph, continue - // without finding a match. This will trigger the process to add a new - // subgraph - continue; - } - idx_t find_table; - if (left_in) { - find_table = filter->right_binding.table_index; - } else { - D_ASSERT(right_in); - find_table = filter->left_binding.table_index; + updater.expr_map[delim_side] = other_side; + if (cond.comparison != ExpressionType::COMPARE_NOT_DISTINCT_FROM) { + nulls_are_not_equal_exprs.push_back(other_side); + } + } + + // removed DelimGet columns are assigned a new ColumnBinding by Projection/Aggregation, keep track here + if (proj_or_agg.type == LogicalOperatorType::LOGICAL_PROJECTION) { + for (auto &cb : proj_or_agg.GetColumnBindings()) { + updater.projection_map[cb] = true; + updater.reverse_proj_or_agg_map[cb] = proj_or_agg.expressions[cb.column_index].get(); + for (auto &expr : nulls_are_not_equal_exprs) { + if (proj_or_agg.expressions[cb.column_index]->Equals(expr)) { + updater.projection_map[cb] = false; + break; } - auto next_subgraph = it + 1; - // iterate through other subgraphs and merge. - FindSubgraphMatchAndMerge(*it, find_table, next_subgraph, subgraphs.end()); - // Now insert the right binding and update denominator with the - // tdom of the filter - it->relations.insert(find_table); - UpdateDenom(&(*it), &relation_2_tdom); - found_match = true; - break; - } - // means that the filter joins relations in the given set, but there is no - // connection to any subgraph in subgraphs. Add a new subgraph, and maybe later there will be - // a connection. - if (!found_match) { - subgraphs.emplace_back(Subgraph2Denominator()); - auto subgraph = &subgraphs.back(); - subgraph->relations.insert(filter->left_binding.table_index); - subgraph->relations.insert(filter->right_binding.table_index); - UpdateDenom(subgraph, &relation_2_tdom); } - auto remove_start = std::remove_if(subgraphs.begin(), subgraphs.end(), - [](Subgraph2Denominator &s) { return s.relations.empty(); }); - subgraphs.erase(remove_start, subgraphs.end()); + } + } else { + auto &agg = (LogicalAggregate &)proj_or_agg; - if (subgraphs.size() == 1 && subgraphs.at(0).relations.size() == new_set->count) { - // You have found enough filters to connect the relations. These are guaranteed - // to be the filters with the highest Tdoms. - done = true; - break; - } + // Create a vector of all exprs in the agg + vector all_agg_exprs; + all_agg_exprs.reserve(agg.groups.size() + agg.expressions.size()); + for (auto &expr : agg.groups) { + all_agg_exprs.push_back(expr.get()); } - } - double denom = 1; - // TODO: It's possible cross-products were added and are not present in the filters in the relation_2_tdom - // structures. When that's the case, multiply the denom structures that have no intersection - for (auto &match : subgraphs) { - // It's possible that in production, one of the D_ASSERTS above will fail and not all subgraphs - // were connected. When this happens, just use the largest denominator of all the subgraphs. - if (match.denom > denom) { - denom = match.denom; + for (auto &expr : agg.expressions) { + all_agg_exprs.push_back(expr.get()); } - } - // can happen if a table has cardinality 0, or a tdom is set to 0 - if (denom == 0) { - denom = 1; - } - return numerator / denom; -} - -static bool IsLogicalFilter(LogicalOperator *op) { - return op->type == LogicalOperatorType::LOGICAL_FILTER; -} -static LogicalGet *GetLogicalGet(LogicalOperator *op) { - LogicalGet *get = nullptr; - switch (op->type) { - case LogicalOperatorType::LOGICAL_GET: - get = (LogicalGet *)op; - break; - case LogicalOperatorType::LOGICAL_FILTER: - get = GetLogicalGet(op->children.at(0).get()); - break; - case LogicalOperatorType::LOGICAL_PROJECTION: - get = GetLogicalGet(op->children.at(0).get()); - break; - case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: { - LogicalComparisonJoin *join = (LogicalComparisonJoin *)op; - if (join->join_type == JoinType::MARK || join->join_type == JoinType::LEFT) { - auto child = join->children.at(0).get(); - get = GetLogicalGet(child); + for (auto &cb : agg.GetColumnBindings()) { + updater.projection_map[cb] = true; + updater.reverse_proj_or_agg_map[cb] = all_agg_exprs[cb.column_index]; + for (auto &expr : nulls_are_not_equal_exprs) { + if ((cb.table_index == agg.group_index && agg.groups[cb.column_index]->Equals(expr)) || + (cb.table_index == agg.aggregate_index && agg.expressions[cb.column_index]->Equals(expr))) { + updater.projection_map[cb] = false; + break; + } + } } - break; - } - default: - // return null pointer, maybe there is no logical get under this child - break; } - return get; -} -void CardinalityEstimator::MergeBindings(idx_t binding_index, idx_t relation_id, - vector> &child_binding_maps) { - for (auto &map_set : child_binding_maps) { - for (auto &mapping : map_set) { - ColumnBinding relation_bindings = mapping.first; - ColumnBinding actual_bindings = mapping.second; + if (!all_equality_conditions) { + // we can get rid of an inequality join with a DelimGet, but only under specific circumstances + if (!RemoveInequalityCandidate(plan, candidate, updater)) { + return false; + } + } - if (actual_bindings.table_index == binding_index) { - auto key = ColumnBinding(relation_id, relation_bindings.column_index); - AddRelationToColumnMapping(key, actual_bindings); + // make a filter if needed + if (!nulls_are_not_equal_exprs.empty() || filter != nullptr) { + auto filter_op = make_unique(); + if (!nulls_are_not_equal_exprs.empty()) { + // add an IS NOT NULL filter that was implicitly in JoinCondition::null_values_are_equal + for (auto &expr : nulls_are_not_equal_exprs) { + auto is_not_null_expr = + make_unique(ExpressionType::OPERATOR_IS_NOT_NULL, LogicalType::BOOLEAN); + is_not_null_expr->children.push_back(expr->Copy()); + filter_op->expressions.push_back(std::move(is_not_null_expr)); + } + } + if (filter != nullptr) { + for (auto &expr : filter->expressions) { + filter_op->expressions.push_back(std::move(expr)); } } + filter_op->children.push_back(std::move(join.children[1 - delim_idx])); + join.children[1 - delim_idx] = std::move(filter_op); } + // temporarily save deleted operator so its expressions are still available + updater.temp_ptr = std::move(proj_or_agg.children[0]); + // replace the redundant join + proj_or_agg.children[0] = std::move(join.children[1 - delim_idx]); + return true; } -bool SortTdoms(const RelationsToTDom &a, const RelationsToTDom &b) { - if (a.has_tdom_hll && b.has_tdom_hll) { - return a.tdom_hll > b.tdom_hll; - } - if (a.has_tdom_hll) { - return a.tdom_hll > b.tdom_no_hll; +static void GetDelimJoins(LogicalOperator &op, vector &delim_joins) { + for (auto &child : op.children) { + GetDelimJoins(*child, delim_joins); } - if (b.has_tdom_hll) { - return a.tdom_no_hll > b.tdom_hll; + if (op.type == LogicalOperatorType::LOGICAL_DELIM_JOIN) { + delim_joins.push_back(&op); } - return a.tdom_no_hll > b.tdom_no_hll; } -void CardinalityEstimator::InitCardinalityEstimatorProps(vector *node_ops, - vector> *filter_infos) { - InitEquivalentRelations(filter_infos); - InitTotalDomains(); - for (idx_t i = 0; i < node_ops->size(); i++) { - auto join_node = (*node_ops)[i].node.get(); - auto op = (*node_ops)[i].op; - join_node->SetBaseTableCardinality(op->EstimateCardinality(context)); - if (op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { - auto &join = (LogicalComparisonJoin &)*op; - if (join.join_type == JoinType::LEFT) { - // TODO: inspect child operators to get a more accurate cost - // and cardinality estimation. If an base op is a Logical Comparison join - // it is probably a left join, so cost of the larger table is a fine - // estimate - // No need to update a mark join cost because I say so. - join_node->SetCost(join_node->GetBaseTableCardinality()); - } +static bool HasChild(LogicalOperator *haystack, LogicalOperator *needle, idx_t &side) { + if (haystack == needle) { + return true; + } + for (idx_t i = 0; i < haystack->children.size(); i++) { + auto &child = haystack->children[i]; + idx_t dummy_side; + if (HasChild(child.get(), needle, dummy_side)) { + side = i; + return true; } - // update cardinality with filters - EstimateBaseTableCardinality(join_node, op); - UpdateTotalDomains(join_node, op); } - - // sort relations from greatest tdom to lowest tdom. - std::sort(relations_to_tdoms.begin(), relations_to_tdoms.end(), SortTdoms); + return false; } -void CardinalityEstimator::UpdateTotalDomains(JoinNode *node, LogicalOperator *op) { - auto relation_id = node->set->relations[0]; - relation_attributes[relation_id].cardinality = node->GetCardinality(); - TableCatalogEntry *catalog_table = nullptr; - auto get = GetLogicalGet(op); - if (get) { - catalog_table = GetCatalogTableEntry(get); +bool Deliminator::RemoveInequalityCandidate(unique_ptr *plan, unique_ptr *candidate, + DeliminatorPlanUpdater &updater) { + auto &proj_or_agg = **candidate; + // first, we find a DelimJoin in "plan" that has only one DelimGet as a child, which is in "candidate" + if (DelimGetCount(proj_or_agg) != 1) { + // the candidate therefore must have only a single DelimGet in its children + return false; } - //! Initialize the tdoms for all columns the relation uses in join conditions. - unordered_set::iterator ite; - idx_t count = node->GetBaseTableCardinality(); - - bool direct_filter = false; - for (auto &column : relation_attributes[relation_id].columns) { - //! for every column in the relation, get the count via either HLL, or assume it to be - //! the cardinality - ColumnBinding key = ColumnBinding(relation_id, column); - - if (catalog_table) { - relation_attributes[relation_id].original_name = catalog_table->name; - // Get HLL stats here - auto actual_binding = relation_column_to_original_column[key]; - - auto base_stats = catalog_table->GetStatistics(context, actual_binding.column_index); - if (base_stats) { - count = base_stats->GetDistinctCount(); - } - - // means you have a direct filter on a column. The count/total domain for the column - // should be decreased to match the predicted total domain matching the filter. - // We decrease the total domain for all columns in the equivalence set because filter pushdown - // will mean all columns are affected. - if (direct_filter) { - count = node->GetCardinality(); - } + vector delim_joins; + GetDelimJoins(**plan, delim_joins); - // HLL has estimation error, count can't be greater than cardinality of the table before filters - if (count > node->GetBaseTableCardinality()) { - count = node->GetBaseTableCardinality(); - } - } else { - // No HLL. So if we know there is a direct filter, reduce count to cardinality with filter - // otherwise assume the total domain is still the cardinality - if (direct_filter) { - count = node->GetCardinality(); - } else { - count = node->GetBaseTableCardinality(); - } + LogicalOperator *parent = nullptr; + idx_t parent_delim_get_side = 0; + for (auto dj : delim_joins) { + D_ASSERT(dj->type == LogicalOperatorType::LOGICAL_DELIM_JOIN); + if (!HasChild(dj, &proj_or_agg, parent_delim_get_side)) { + continue; + } + // we found a parent DelimJoin + if (DelimGetCount(*dj) != 1) { + // it has more than one DelimGet children + continue; } - for (auto &relation_to_tdom : relations_to_tdoms) { - column_binding_set_t i_set = relation_to_tdom.equivalent_relations; - if (i_set.count(key) != 1) { - continue; - } - if (catalog_table) { - if (relation_to_tdom.tdom_hll < count) { - relation_to_tdom.tdom_hll = count; - relation_to_tdom.has_tdom_hll = true; - } - if (relation_to_tdom.tdom_no_hll > count) { - relation_to_tdom.tdom_no_hll = count; - } - } else { - // Here we don't have catalog statistics, and the following is how we determine - // the tdom - // 1. If there is any hll data in the equivalence set, use that - // 2. Otherwise, use the table with the smallest cardinality - if (relation_to_tdom.tdom_no_hll > count && !relation_to_tdom.has_tdom_hll) { - relation_to_tdom.tdom_no_hll = count; - } - } - break; + // we can only remove inequality join with a DelimGet if the parent DelimJoin has one of these join types + auto &delim_join = (LogicalDelimJoin &)*dj; + if (!InequalityDelimJoinCanBeEliminated(delim_join.join_type)) { + continue; } + + parent = dj; + break; + } + if (!parent) { + return false; } -} -TableFilterSet *CardinalityEstimator::GetTableFilters(LogicalOperator *op) { - // First check table filters - auto get = GetLogicalGet(op); - return get ? &get->table_filters : nullptr; -} + // we found the parent delim join, and we may be able to remove the child DelimGet join + // but we need to make sure that their conditions refer to exactly the same columns + auto &parent_delim_join = (LogicalDelimJoin &)*parent; + auto &join = (LogicalComparisonJoin &)*proj_or_agg.children[0]; + if (parent_delim_join.conditions.size() != join.conditions.size()) { + // different number of conditions, can't replace + return false; + } -idx_t CardinalityEstimator::InspectConjunctionAND(idx_t cardinality, idx_t column_index, ConjunctionAndFilter *filter, - unique_ptr base_stats) { - auto has_equality_filter = false; - auto cardinality_after_filters = cardinality; - for (auto &child_filter : filter->child_filters) { - if (child_filter->filter_type != TableFilterType::CONSTANT_COMPARISON) { - continue; - } - auto comparison_filter = (ConstantFilter &)*child_filter; - if (comparison_filter.comparison_type != ExpressionType::COMPARE_EQUAL) { - continue; + // we can only do this optimization under the following conditions: + // 1. all join expressions coming from the DelimGet side are colrefs + // 2. these expressions refer to colrefs coming from the proj/agg on top of the child DelimGet join + // 3. the expression (before it was proj/agg) can be found in the conditions of the child DelimGet join + for (auto &parent_cond : parent_delim_join.conditions) { + auto &parent_expr = parent_delim_get_side == 0 ? parent_cond.left : parent_cond.right; + if (parent_expr->type != ExpressionType::BOUND_COLUMN_REF) { + // can only deal with colrefs + return false; } - auto column_count = 0; - if (base_stats) { - column_count = base_stats->GetDistinctCount(); + auto &parent_colref = (BoundColumnRefExpression &)*parent_expr; + auto it = updater.reverse_proj_or_agg_map.find(parent_colref.binding); + if (it == updater.reverse_proj_or_agg_map.end()) { + // refers to a column that was not in the child DelimGet join + return false; } - auto filtered_card = cardinality; - // column_count = 0 when there is no column count (i.e parquet scans) - if (column_count > 0) { - // we want the ceil of cardinality/column_count. We also want to avoid compiler errors - filtered_card = (cardinality + column_count - 1) / column_count; - cardinality_after_filters = filtered_card; + // try to find the corresponding child condition + // TODO: can be more flexible - allow CAST + auto child_expr = it->second; + bool found = false; + for (auto &child_cond : join.conditions) { + if (child_cond.left->Equals(child_expr) || child_cond.right->Equals(child_expr)) { + found = true; + break; + } } - if (has_equality_filter) { - cardinality_after_filters = MinValue(filtered_card, cardinality_after_filters); + if (!found) { + // could not find the mapped expression in the child condition expressions + return false; } - has_equality_filter = true; } - return cardinality_after_filters; -} -idx_t CardinalityEstimator::InspectConjunctionOR(idx_t cardinality, idx_t column_index, ConjunctionOrFilter *filter, - unique_ptr base_stats) { - auto has_equality_filter = false; - auto cardinality_after_filters = cardinality; - for (auto &child_filter : filter->child_filters) { - if (child_filter->filter_type != TableFilterType::CONSTANT_COMPARISON) { - continue; + // TODO: we cannot perform the optimization here because our pure inequality joins don't implement + // JoinType::SINGLE yet + if (parent_delim_join.join_type == JoinType::SINGLE) { + bool has_one_equality = false; + for (auto &cond : join.conditions) { + has_one_equality = has_one_equality || IsEqualityJoinCondition(cond); } - auto comparison_filter = (ConstantFilter &)*child_filter; - if (comparison_filter.comparison_type == ExpressionType::COMPARE_EQUAL) { - auto column_count = cardinality_after_filters; - if (base_stats) { - column_count = base_stats->GetDistinctCount(); - } - auto increment = MaxValue(((cardinality + column_count - 1) / column_count), 1); - if (has_equality_filter) { - cardinality_after_filters += increment; - } else { - cardinality_after_filters = increment; - } - has_equality_filter = true; + if (!has_one_equality) { + return false; } } - D_ASSERT(cardinality_after_filters > 0); - return cardinality_after_filters; -} -idx_t CardinalityEstimator::InspectTableFilters(idx_t cardinality, LogicalOperator *op, TableFilterSet *table_filters) { - idx_t cardinality_after_filters = cardinality; - auto get = GetLogicalGet(op); - unique_ptr column_statistics; - for (auto &it : table_filters->filters) { - column_statistics = nullptr; - if (get->bind_data && get->function.name.compare("seq_scan") == 0) { - auto &table_scan_bind_data = (TableScanBindData &)*get->bind_data; - column_statistics = get->function.statistics(context, &table_scan_bind_data, it.first); - } - if (it.second->filter_type == TableFilterType::CONJUNCTION_AND) { - auto &filter = (ConjunctionAndFilter &)*it.second; - idx_t cardinality_with_and_filter = - InspectConjunctionAND(cardinality, it.first, &filter, move(column_statistics)); - cardinality_after_filters = MinValue(cardinality_after_filters, cardinality_with_and_filter); - } else if (it.second->filter_type == TableFilterType::CONJUNCTION_OR) { - auto &filter = (ConjunctionOrFilter &)*it.second; - idx_t cardinality_with_or_filter = - InspectConjunctionOR(cardinality, it.first, &filter, move(column_statistics)); - cardinality_after_filters = MinValue(cardinality_after_filters, cardinality_with_or_filter); + // we are now sure that we can remove the child DelimGet join, so we basically do the same loop as above + // this time without checks because we already did them, and replace the expressions + for (auto &parent_cond : parent_delim_join.conditions) { + auto &parent_expr = parent_delim_get_side == 0 ? parent_cond.left : parent_cond.right; + auto &parent_colref = (BoundColumnRefExpression &)*parent_expr; + auto it = updater.reverse_proj_or_agg_map.find(parent_colref.binding); + auto child_expr = it->second; + for (auto &child_cond : join.conditions) { + if (!child_cond.left->Equals(child_expr) && !child_cond.right->Equals(child_expr)) { + continue; + } + parent_expr = + make_unique(parent_expr->alias, parent_expr->return_type, it->first); + parent_cond.comparison = + parent_delim_get_side == 0 ? child_cond.comparison : FlipComparisionExpression(child_cond.comparison); + break; } } - // if the above code didn't find an equality filter (i.e country_code = "[us]") - // and there are other table filters, use default selectivity. - bool has_equality_filter = (cardinality_after_filters != cardinality); - if (!has_equality_filter && !table_filters->filters.empty()) { - cardinality_after_filters = MaxValue(cardinality * DEFAULT_SELECTIVITY, 1); - } - return cardinality_after_filters; -} -void CardinalityEstimator::EstimateBaseTableCardinality(JoinNode *node, LogicalOperator *op) { - auto has_logical_filter = IsLogicalFilter(op); - auto table_filters = GetTableFilters(op); + // no longer needs to be a delim join + parent_delim_join.duplicate_eliminated_columns.clear(); + parent_delim_join.type = LogicalOperatorType::LOGICAL_COMPARISON_JOIN; - auto card_after_filters = node->GetBaseTableCardinality(); - // Logical Filter on a seq scan - if (has_logical_filter) { - card_after_filters *= DEFAULT_SELECTIVITY; - } else if (table_filters) { - double inspect_result = (double)InspectTableFilters(card_after_filters, op, table_filters); - card_after_filters = MinValue(inspect_result, (double)card_after_filters); - } - node->SetEstimatedCardinality(card_after_filters); + return true; } } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/column_lifetime_optimizer.hpp +// duckdb/optimizer/expression_heuristics.hpp // // //===----------------------------------------------------------------------===// @@ -163423,1324 +173225,344 @@ void CardinalityEstimator::EstimateBaseTableCardinality(JoinNode *node, LogicalO - namespace duckdb { -class BoundColumnRefExpression; -//! The ColumnLifetimeAnalyzer optimizer traverses the logical operator tree and ensures that columns are removed from -//! the plan when no longer required -class ColumnLifetimeAnalyzer : public LogicalOperatorVisitor { +class ExpressionHeuristics : public LogicalOperatorVisitor { public: - explicit ColumnLifetimeAnalyzer(bool is_root = false) : everything_referenced(is_root) { + explicit ExpressionHeuristics(Optimizer &optimizer) : optimizer(optimizer) { } - void VisitOperator(LogicalOperator &op) override; + Optimizer &optimizer; + unique_ptr root; -protected: - unique_ptr VisitReplace(BoundColumnRefExpression &expr, unique_ptr *expr_ptr) override; - unique_ptr VisitReplace(BoundReferenceExpression &expr, unique_ptr *expr_ptr) override; +public: + //! Search for filters to be reordered + unique_ptr Rewrite(unique_ptr op); + //! Reorder the expressions of a filter + void ReorderExpressions(vector> &expressions); + //! Return the cost of an expression + idx_t Cost(Expression &expr); -private: - //! Whether or not all the columns are referenced. This happens in the case of the root expression (because the - //! output implicitly refers all the columns below it) - bool everything_referenced; - //! The set of column references - column_binding_set_t column_references; + unique_ptr VisitReplace(BoundConjunctionExpression &expr, unique_ptr *expr_ptr) override; + //! Override this function to search for filter operators + void VisitOperator(LogicalOperator &op) override; private: - void StandardVisitOperator(LogicalOperator &op); + unordered_map function_costs = { + {"+", 5}, {"-", 5}, {"&", 5}, {"#", 5}, + {">>", 5}, {"<<", 5}, {"abs", 5}, {"*", 10}, + {"%", 10}, {"/", 15}, {"date_part", 20}, {"year", 20}, + {"round", 100}, {"~~", 200}, {"!~~", 200}, {"regexp_matches", 200}, + {"||", 200}}; - void ExtractUnusedColumnBindings(vector bindings, column_binding_set_t &unused_bindings); - void GenerateProjectionMap(vector bindings, column_binding_set_t &unused_bindings, - vector &map); + idx_t ExpressionCost(BoundBetweenExpression &expr); + idx_t ExpressionCost(BoundCaseExpression &expr); + idx_t ExpressionCost(BoundCastExpression &expr); + idx_t ExpressionCost(BoundComparisonExpression &expr); + idx_t ExpressionCost(BoundConjunctionExpression &expr); + idx_t ExpressionCost(BoundFunctionExpression &expr); + idx_t ExpressionCost(BoundOperatorExpression &expr, ExpressionType &expr_type); + idx_t ExpressionCost(PhysicalType return_type, idx_t multiplier); }; } // namespace duckdb +namespace duckdb { + +unique_ptr ExpressionHeuristics::Rewrite(unique_ptr op) { + VisitOperator(*op); + return op; +} +void ExpressionHeuristics::VisitOperator(LogicalOperator &op) { + if (op.type == LogicalOperatorType::LOGICAL_FILTER) { + // reorder all filter expressions + if (op.expressions.size() > 1) { + ReorderExpressions(op.expressions); + } + } + // traverse recursively through the operator tree + VisitOperatorChildren(op); + VisitOperatorExpressions(op); +} +unique_ptr ExpressionHeuristics::VisitReplace(BoundConjunctionExpression &expr, + unique_ptr *expr_ptr) { + ReorderExpressions(expr.children); + return nullptr; +} +void ExpressionHeuristics::ReorderExpressions(vector> &expressions) { -namespace duckdb { + struct ExpressionCosts { + unique_ptr expr; + idx_t cost; -void ColumnLifetimeAnalyzer::ExtractUnusedColumnBindings(vector bindings, - column_binding_set_t &unused_bindings) { - for (idx_t i = 0; i < bindings.size(); i++) { - if (column_references.find(bindings[i]) == column_references.end()) { - unused_bindings.insert(bindings[i]); + bool operator==(const ExpressionCosts &p) const { + return cost == p.cost; } - } -} - -void ColumnLifetimeAnalyzer::GenerateProjectionMap(vector bindings, - column_binding_set_t &unused_bindings, - vector &projection_map) { - if (unused_bindings.empty()) { - return; - } - // now iterate over the result bindings of the child - for (idx_t i = 0; i < bindings.size(); i++) { - // if this binding does not belong to the unused bindings, add it to the projection map - if (unused_bindings.find(bindings[i]) == unused_bindings.end()) { - projection_map.push_back(i); + bool operator<(const ExpressionCosts &p) const { + return cost < p.cost; } + }; + + vector expression_costs; + // iterate expressions, get cost for each one + for (idx_t i = 0; i < expressions.size(); i++) { + idx_t cost = Cost(*expressions[i]); + expression_costs.push_back({std::move(expressions[i]), cost}); } - if (projection_map.size() == bindings.size()) { - projection_map.clear(); + + // sort by cost and put back in place + sort(expression_costs.begin(), expression_costs.end()); + for (idx_t i = 0; i < expression_costs.size(); i++) { + expressions[i] = std::move(expression_costs[i].expr); } } -void ColumnLifetimeAnalyzer::StandardVisitOperator(LogicalOperator &op) { - LogicalOperatorVisitor::VisitOperatorExpressions(op); - if (op.type == LogicalOperatorType::LOGICAL_DELIM_JOIN) { - // visit the duplicate eliminated columns on the LHS, if any - auto &delim_join = (LogicalDelimJoin &)op; - for (auto &expr : delim_join.duplicate_eliminated_columns) { - VisitExpression(&expr); - } - } - LogicalOperatorVisitor::VisitOperatorChildren(op); +idx_t ExpressionHeuristics::ExpressionCost(BoundBetweenExpression &expr) { + return Cost(*expr.input) + Cost(*expr.lower) + Cost(*expr.upper) + 10; } -void ColumnLifetimeAnalyzer::VisitOperator(LogicalOperator &op) { - switch (op.type) { - case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY: { - // FIXME: groups that are not referenced can be removed from projection - // recurse into the children of the aggregate - ColumnLifetimeAnalyzer analyzer; - analyzer.VisitOperatorExpressions(op); - analyzer.VisitOperator(*op.children[0]); - return; +idx_t ExpressionHeuristics::ExpressionCost(BoundCaseExpression &expr) { + // CASE WHEN check THEN result_if_true ELSE result_if_false END + idx_t case_cost = 0; + for (auto &case_check : expr.case_checks) { + case_cost += Cost(*case_check.then_expr); + case_cost += Cost(*case_check.when_expr); } - case LogicalOperatorType::LOGICAL_DELIM_JOIN: - case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: { - if (everything_referenced) { - break; - } - auto &comp_join = (LogicalComparisonJoin &)op; - if (comp_join.join_type == JoinType::MARK || comp_join.join_type == JoinType::SEMI || - comp_join.join_type == JoinType::ANTI) { - break; - } - // FIXME for now, we only push into the projection map for equality (hash) joins - // FIXME: add projection to LHS as well - bool has_equality = false; - for (auto &cond : comp_join.conditions) { - if (cond.comparison == ExpressionType::COMPARE_EQUAL) { - has_equality = true; - } - } - if (!has_equality) { - break; + case_cost += Cost(*expr.else_expr); + return case_cost; +} + +idx_t ExpressionHeuristics::ExpressionCost(BoundCastExpression &expr) { + // OPERATOR_CAST + // determine cast cost by comparing cast_expr.source_type and cast_expr_target_type + idx_t cast_cost = 0; + if (expr.return_type != expr.source_type()) { + // if cast from or to varchar + // TODO: we might want to add more cases + if (expr.return_type.id() == LogicalTypeId::VARCHAR || expr.source_type().id() == LogicalTypeId::VARCHAR || + expr.return_type.id() == LogicalTypeId::BLOB || expr.source_type().id() == LogicalTypeId::BLOB) { + cast_cost = 200; + } else { + cast_cost = 5; } - // now, for each of the columns of the RHS, check which columns need to be projected - column_binding_set_t unused_bindings; - ExtractUnusedColumnBindings(op.children[1]->GetColumnBindings(), unused_bindings); + } + return Cost(*expr.child) + cast_cost; +} - // now recurse into the filter and its children - StandardVisitOperator(op); +idx_t ExpressionHeuristics::ExpressionCost(BoundComparisonExpression &expr) { + // COMPARE_EQUAL, COMPARE_NOTEQUAL, COMPARE_GREATERTHAN, COMPARE_GREATERTHANOREQUALTO, COMPARE_LESSTHAN, + // COMPARE_LESSTHANOREQUALTO + return Cost(*expr.left) + 5 + Cost(*expr.right); +} - // then generate the projection map - GenerateProjectionMap(op.children[1]->GetColumnBindings(), unused_bindings, comp_join.right_projection_map); - return; +idx_t ExpressionHeuristics::ExpressionCost(BoundConjunctionExpression &expr) { + // CONJUNCTION_AND, CONJUNCTION_OR + idx_t cost = 5; + for (auto &child : expr.children) { + cost += Cost(*child); } - case LogicalOperatorType::LOGICAL_UNION: - case LogicalOperatorType::LOGICAL_EXCEPT: - case LogicalOperatorType::LOGICAL_INTERSECT: - // for set operations we don't remove anything, just recursively visit the children - // FIXME: for UNION we can remove unreferenced columns as long as everything_referenced is false (i.e. we - // encounter a UNION node that is not preceded by a DISTINCT) - for (auto &child : op.children) { - ColumnLifetimeAnalyzer analyzer(true); - analyzer.VisitOperator(*child); - } - return; - case LogicalOperatorType::LOGICAL_PROJECTION: { - // then recurse into the children of this projection - ColumnLifetimeAnalyzer analyzer; - analyzer.VisitOperatorExpressions(op); - analyzer.VisitOperator(*op.children[0]); - return; + return cost; +} + +idx_t ExpressionHeuristics::ExpressionCost(BoundFunctionExpression &expr) { + idx_t cost_children = 0; + for (auto &child : expr.children) { + cost_children += Cost(*child); } - case LogicalOperatorType::LOGICAL_DISTINCT: { - // distinct, all projected columns are used for the DISTINCT computation - // mark all columns as used and continue to the children - // FIXME: DISTINCT with expression list does not implicitly reference everything - everything_referenced = true; - break; + + auto cost_function = function_costs.find(expr.function.name); + if (cost_function != function_costs.end()) { + return cost_children + cost_function->second; + } else { + return cost_children + 1000; } - case LogicalOperatorType::LOGICAL_FILTER: { - auto &filter = (LogicalFilter &)op; - if (everything_referenced) { - break; - } - // filter, figure out which columns are not needed after the filter - column_binding_set_t unused_bindings; - ExtractUnusedColumnBindings(op.children[0]->GetColumnBindings(), unused_bindings); +} - // now recurse into the filter and its children - StandardVisitOperator(op); +idx_t ExpressionHeuristics::ExpressionCost(BoundOperatorExpression &expr, ExpressionType &expr_type) { + idx_t sum = 0; + for (auto &child : expr.children) { + sum += Cost(*child); + } - // then generate the projection map - GenerateProjectionMap(op.children[0]->GetColumnBindings(), unused_bindings, filter.projection_map); - return; + // OPERATOR_IS_NULL, OPERATOR_IS_NOT_NULL + if (expr_type == ExpressionType::OPERATOR_IS_NULL || expr_type == ExpressionType::OPERATOR_IS_NOT_NULL) { + return sum + 5; + } else if (expr_type == ExpressionType::COMPARE_IN || expr_type == ExpressionType::COMPARE_NOT_IN) { + // COMPARE_IN, COMPARE_NOT_IN + return sum + (expr.children.size() - 1) * 100; + } else if (expr_type == ExpressionType::OPERATOR_NOT) { + // OPERATOR_NOT + return sum + 10; // TODO: evaluate via measured runtimes + } else { + return sum + 1000; } +} + +idx_t ExpressionHeuristics::ExpressionCost(PhysicalType return_type, idx_t multiplier) { + // TODO: ajust values according to benchmark results + switch (return_type) { + case PhysicalType::VARCHAR: + return 5 * multiplier; + case PhysicalType::FLOAT: + case PhysicalType::DOUBLE: + return 2 * multiplier; default: - break; + return 1 * multiplier; } - StandardVisitOperator(op); } -unique_ptr ColumnLifetimeAnalyzer::VisitReplace(BoundColumnRefExpression &expr, - unique_ptr *expr_ptr) { - column_references.insert(expr.binding); - return nullptr; -} +idx_t ExpressionHeuristics::Cost(Expression &expr) { + switch (expr.expression_class) { + case ExpressionClass::BOUND_CASE: { + auto &case_expr = (BoundCaseExpression &)expr; + return ExpressionCost(case_expr); + } + case ExpressionClass::BOUND_BETWEEN: { + auto &between_expr = (BoundBetweenExpression &)expr; + return ExpressionCost(between_expr); + } + case ExpressionClass::BOUND_CAST: { + auto &cast_expr = (BoundCastExpression &)expr; + return ExpressionCost(cast_expr); + } + case ExpressionClass::BOUND_COMPARISON: { + auto &comp_expr = (BoundComparisonExpression &)expr; + return ExpressionCost(comp_expr); + } + case ExpressionClass::BOUND_CONJUNCTION: { + auto &conj_expr = (BoundConjunctionExpression &)expr; + return ExpressionCost(conj_expr); + } + case ExpressionClass::BOUND_FUNCTION: { + auto &func_expr = (BoundFunctionExpression &)expr; + return ExpressionCost(func_expr); + } + case ExpressionClass::BOUND_OPERATOR: { + auto &op_expr = (BoundOperatorExpression &)expr; + return ExpressionCost(op_expr, expr.type); + } + case ExpressionClass::BOUND_COLUMN_REF: { + auto &col_expr = (BoundColumnRefExpression &)expr; + return ExpressionCost(col_expr.return_type.InternalType(), 8); + } + case ExpressionClass::BOUND_CONSTANT: { + auto &const_expr = (BoundConstantExpression &)expr; + return ExpressionCost(const_expr.return_type.InternalType(), 1); + } + case ExpressionClass::BOUND_PARAMETER: { + auto &const_expr = (BoundParameterExpression &)expr; + return ExpressionCost(const_expr.return_type.InternalType(), 1); + } + case ExpressionClass::BOUND_REF: { + auto &col_expr = (BoundColumnRefExpression &)expr; + return ExpressionCost(col_expr.return_type.InternalType(), 8); + } + default: { + break; + } + } -unique_ptr ColumnLifetimeAnalyzer::VisitReplace(BoundReferenceExpression &expr, - unique_ptr *expr_ptr) { - // BoundReferenceExpression should not be used here yet, they only belong in the physical plan - throw InternalException("BoundReferenceExpression should not be used here yet!"); + // return a very high value if nothing matches + return 1000; } } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/optimizer/common_aggregate_optimizer.hpp -// -// -//===----------------------------------------------------------------------===// - -namespace duckdb { -//! The CommonAggregateOptimizer optimizer eliminates duplicate aggregates from aggregate nodes -class CommonAggregateOptimizer : public LogicalOperatorVisitor { -public: - void VisitOperator(LogicalOperator &op) override; -private: - unique_ptr VisitReplace(BoundColumnRefExpression &expr, unique_ptr *expr_ptr) override; - void ExtractCommonAggregates(LogicalAggregate &aggr); -private: - column_binding_map_t aggregate_map; -}; -} // namespace duckdb +namespace duckdb { +unique_ptr ExpressionRewriter::ApplyRules(LogicalOperator &op, const vector &rules, + unique_ptr expr, bool &changes_made, bool is_root) { + for (auto &rule : rules) { + vector bindings; + if (rule->root->Match(expr.get(), bindings)) { + // the rule matches! try to apply it + bool rule_made_change = false; + auto result = rule->Apply(op, bindings, rule_made_change, is_root); + if (result) { + changes_made = true; + // the base node changed: the rule applied changes + // rerun on the new node + return ExpressionRewriter::ApplyRules(op, rules, std::move(result), changes_made); + } else if (rule_made_change) { + changes_made = true; + // the base node didn't change, but changes were made, rerun + return expr; + } + // else nothing changed, continue to the next rule + continue; + } + } + // no changes could be made to this node + // recursively run on the children of this node + ExpressionIterator::EnumerateChildren(*expr, [&](unique_ptr &child) { + child = ExpressionRewriter::ApplyRules(op, rules, std::move(child), changes_made); + }); + return expr; +} +unique_ptr ExpressionRewriter::ConstantOrNull(unique_ptr child, Value value) { + vector> children; + children.push_back(make_unique(value)); + children.push_back(std::move(child)); + return ConstantOrNull(std::move(children), std::move(value)); +} +unique_ptr ExpressionRewriter::ConstantOrNull(vector> children, Value value) { + auto type = value.type(); + children.insert(children.begin(), make_unique(value)); + return make_unique(type, ConstantOrNull::GetFunction(type), std::move(children), + ConstantOrNull::Bind(std::move(value))); +} +void ExpressionRewriter::VisitOperator(LogicalOperator &op) { + VisitOperatorChildren(op); + this->op = &op; + to_apply_rules.clear(); + for (auto &rule : rules) { + if (rule->logical_root && !rule->logical_root->Match(op.type)) { + // this rule does not apply to this type of LogicalOperator + continue; + } + to_apply_rules.push_back(rule.get()); + } + if (to_apply_rules.empty()) { + // no rules to apply on this node + return; + } -namespace duckdb { + VisitOperatorExpressions(op); -void CommonAggregateOptimizer::VisitOperator(LogicalOperator &op) { - LogicalOperatorVisitor::VisitOperator(op); - switch (op.type) { - case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY: - ExtractCommonAggregates((LogicalAggregate &)op); - break; - default: - break; + // if it is a LogicalFilter, we split up filter conjunctions again + if (op.type == LogicalOperatorType::LOGICAL_FILTER) { + auto &filter = (LogicalFilter &)op; + filter.SplitPredicates(); } } -unique_ptr CommonAggregateOptimizer::VisitReplace(BoundColumnRefExpression &expr, - unique_ptr *expr_ptr) { - // check if this column ref points to an aggregate that was remapped; if it does we remap it - auto entry = aggregate_map.find(expr.binding); - if (entry != aggregate_map.end()) { - expr.binding = entry->second; - } - return nullptr; +void ExpressionRewriter::VisitExpression(unique_ptr *expression) { + bool changes_made; + do { + changes_made = false; + *expression = ExpressionRewriter::ApplyRules(*op, to_apply_rules, std::move(*expression), changes_made, true); + } while (changes_made); } -void CommonAggregateOptimizer::ExtractCommonAggregates(LogicalAggregate &aggr) { - expression_map_t aggregate_remap; - idx_t total_erased = 0; - for (idx_t i = 0; i < aggr.expressions.size(); i++) { - idx_t original_index = i + total_erased; - auto entry = aggregate_remap.find(aggr.expressions[i].get()); - if (entry == aggregate_remap.end()) { - // aggregate does not exist yet: add it to the map - aggregate_remap[aggr.expressions[i].get()] = i; - if (i != original_index) { - // this aggregate is not erased, however an agregate BEFORE it has been erased - // so we need to remap this aggregaet - ColumnBinding original_binding(aggr.aggregate_index, original_index); - ColumnBinding new_binding(aggr.aggregate_index, i); - aggregate_map[original_binding] = new_binding; - } - } else { - // aggregate already exists! we can remove this entry - total_erased++; - aggr.expressions.erase(aggr.expressions.begin() + i); - i--; - // we need to remap any references to this aggregate so they point to the other aggregate - ColumnBinding original_binding(aggr.aggregate_index, original_index); - ColumnBinding new_binding(aggr.aggregate_index, entry->second); - aggregate_map[original_binding] = new_binding; - } - } -} - -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/optimizer/cse_optimizer.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - -namespace duckdb { -class Binder; -struct CSEReplacementState; - -//! The CommonSubExpression optimizer traverses the expressions of a LogicalOperator to look for duplicate expressions -//! if there are any, it pushes a projection under the operator that resolves these expressions -class CommonSubExpressionOptimizer : public LogicalOperatorVisitor { -public: - explicit CommonSubExpressionOptimizer(Binder &binder) : binder(binder) { - } - -public: - void VisitOperator(LogicalOperator &op) override; - -private: - //! First iteration: count how many times each expression occurs - void CountExpressions(Expression &expr, CSEReplacementState &state); - //! Second iteration: perform the actual replacement of the duplicate expressions with common subexpressions nodes - void PerformCSEReplacement(unique_ptr *expr, CSEReplacementState &state); - - //! Main method to extract common subexpressions - void ExtractCommonSubExpresions(LogicalOperator &op); - -private: - Binder &binder; -}; -} // namespace duckdb - - - - - - - - - -namespace duckdb { - -//! The CSENode contains information about a common subexpression; how many times it occurs, and the column index in the -//! underlying projection -struct CSENode { - idx_t count; - idx_t column_index; - - CSENode() : count(1), column_index(DConstants::INVALID_INDEX) { - } -}; - -//! The CSEReplacementState -struct CSEReplacementState { - //! The projection index of the new projection - idx_t projection_index; - //! Map of expression -> CSENode - expression_map_t expression_count; - //! Map of column bindings to column indexes in the projection expression list - column_binding_map_t column_map; - //! The set of expressions of the resulting projection - vector> expressions; - //! Cached expressions that are kept around so the expression_map always contains valid expressions - vector> cached_expressions; -}; - -void CommonSubExpressionOptimizer::VisitOperator(LogicalOperator &op) { - switch (op.type) { - case LogicalOperatorType::LOGICAL_PROJECTION: - case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY: - ExtractCommonSubExpresions(op); - break; - default: - break; - } - LogicalOperatorVisitor::VisitOperator(op); -} - -void CommonSubExpressionOptimizer::CountExpressions(Expression &expr, CSEReplacementState &state) { - // we only consider expressions with children for CSE elimination - switch (expr.expression_class) { - case ExpressionClass::BOUND_COLUMN_REF: - case ExpressionClass::BOUND_CONSTANT: - case ExpressionClass::BOUND_PARAMETER: - // skip conjunctions and case, since short-circuiting might be incorrectly disabled otherwise - case ExpressionClass::BOUND_CONJUNCTION: - case ExpressionClass::BOUND_CASE: - return; - default: - break; - } - if (expr.expression_class != ExpressionClass::BOUND_AGGREGATE && !expr.HasSideEffects()) { - // we can't move aggregates to a projection, so we only consider the children of the aggregate - auto node = state.expression_count.find(&expr); - if (node == state.expression_count.end()) { - // first time we encounter this expression, insert this node with [count = 1] - state.expression_count[&expr] = CSENode(); - } else { - // we encountered this expression before, increment the occurrence count - node->second.count++; - } - } - // recursively count the children - ExpressionIterator::EnumerateChildren(expr, [&](Expression &child) { CountExpressions(child, state); }); -} - -void CommonSubExpressionOptimizer::PerformCSEReplacement(unique_ptr *expr_ptr, CSEReplacementState &state) { - Expression &expr = **expr_ptr; - if (expr.expression_class == ExpressionClass::BOUND_COLUMN_REF) { - auto &bound_column_ref = (BoundColumnRefExpression &)expr; - // bound column ref, check if this one has already been recorded in the expression list - auto column_entry = state.column_map.find(bound_column_ref.binding); - if (column_entry == state.column_map.end()) { - // not there yet: push the expression - idx_t new_column_index = state.expressions.size(); - state.column_map[bound_column_ref.binding] = new_column_index; - state.expressions.push_back(make_unique( - bound_column_ref.alias, bound_column_ref.return_type, bound_column_ref.binding)); - bound_column_ref.binding = ColumnBinding(state.projection_index, new_column_index); - } else { - // else: just update the column binding! - bound_column_ref.binding = ColumnBinding(state.projection_index, column_entry->second); - } - return; - } - // check if this child is eligible for CSE elimination - bool can_cse = expr.expression_class != ExpressionClass::BOUND_CONJUNCTION && - expr.expression_class != ExpressionClass::BOUND_CASE; - if (can_cse && state.expression_count.find(&expr) != state.expression_count.end()) { - auto &node = state.expression_count[&expr]; - if (node.count > 1) { - // this expression occurs more than once! push it into the projection - // check if it has already been pushed into the projection - auto alias = expr.alias; - auto type = expr.return_type; - if (node.column_index == DConstants::INVALID_INDEX) { - // has not been pushed yet: push it - node.column_index = state.expressions.size(); - state.expressions.push_back(move(*expr_ptr)); - } else { - state.cached_expressions.push_back(move(*expr_ptr)); - } - // replace the original expression with a bound column ref - *expr_ptr = make_unique(alias, type, - ColumnBinding(state.projection_index, node.column_index)); - return; - } - } - // this expression only occurs once, we can't perform CSE elimination - // look into the children to see if we can replace them - ExpressionIterator::EnumerateChildren(expr, - [&](unique_ptr &child) { PerformCSEReplacement(&child, state); }); -} - -void CommonSubExpressionOptimizer::ExtractCommonSubExpresions(LogicalOperator &op) { - D_ASSERT(op.children.size() == 1); - - // first we count for each expression with children how many types it occurs - CSEReplacementState state; - LogicalOperatorVisitor::EnumerateExpressions( - op, [&](unique_ptr *child) { CountExpressions(**child, state); }); - // check if there are any expressions to extract - bool perform_replacement = false; - for (auto &expr : state.expression_count) { - if (expr.second.count > 1) { - perform_replacement = true; - break; - } - } - if (!perform_replacement) { - // no CSEs to extract - return; - } - state.projection_index = binder.GenerateTableIndex(); - // we found common subexpressions to extract - // now we iterate over all the expressions and perform the actual CSE elimination - LogicalOperatorVisitor::EnumerateExpressions( - op, [&](unique_ptr *child) { PerformCSEReplacement(child, state); }); - D_ASSERT(state.expressions.size() > 0); - // create a projection node as the child of this node - auto projection = make_unique(state.projection_index, move(state.expressions)); - projection->children.push_back(move(op.children[0])); - op.children[0] = move(projection); -} - -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/optimizer/deliminator.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - - -namespace duckdb { - -class Optimizer; -class DeliminatorPlanUpdater; - -//! The Deliminator optimizer traverses the logical operator tree and removes any redundant DelimGets/DelimJoins -class Deliminator { -public: - Deliminator() { - } - //! Perform DelimJoin elimination - unique_ptr Optimize(unique_ptr op); - -private: - //! Find Joins with a DelimGet that can be removed - void FindCandidates(unique_ptr *op_ptr, vector *> &candidates); - //! Try to remove a Join with a DelimGet, returns true if it was successful - bool RemoveCandidate(unique_ptr *plan, unique_ptr *candidate, - DeliminatorPlanUpdater &updater); - //! Try to remove an inequality Join with a DelimGet, returns true if it was successful - bool RemoveInequalityCandidate(unique_ptr *plan, unique_ptr *candidate, - DeliminatorPlanUpdater &updater); -}; - -} // namespace duckdb - - - - - - - - - - - -namespace duckdb { - -class DeliminatorPlanUpdater : LogicalOperatorVisitor { -public: - DeliminatorPlanUpdater() { - } - //! Update the plan after a DelimGet has been removed - void VisitOperator(LogicalOperator &op) override; - void VisitExpression(unique_ptr *expression) override; - -public: - expression_map_t expr_map; - column_binding_map_t projection_map; - column_binding_map_t reverse_proj_or_agg_map; - unique_ptr temp_ptr; -}; - -static idx_t DelimGetCount(LogicalOperator &op) { - if (op.type == LogicalOperatorType::LOGICAL_DELIM_GET) { - return 1; - } - idx_t child_count = 0; - for (auto &child : op.children) { - child_count += DelimGetCount(*child); - } - return child_count; -} - -static bool IsEqualityJoinCondition(JoinCondition &cond) { - switch (cond.comparison) { - case ExpressionType::COMPARE_EQUAL: - case ExpressionType::COMPARE_NOT_DISTINCT_FROM: - return true; - default: - return false; - } -} - -static bool InequalityDelimJoinCanBeEliminated(JoinType &join_type) { - switch (join_type) { - case JoinType::ANTI: - case JoinType::MARK: - case JoinType::SEMI: - case JoinType::SINGLE: - return true; - default: - return false; - } -} - -void DeliminatorPlanUpdater::VisitOperator(LogicalOperator &op) { - VisitOperatorChildren(op); - VisitOperatorExpressions(op); - if (op.type == LogicalOperatorType::LOGICAL_DELIM_JOIN && DelimGetCount(op) == 0) { - auto &delim_join = (LogicalDelimJoin &)op; - auto decs = &delim_join.duplicate_eliminated_columns; - for (auto &cond : delim_join.conditions) { - if (!IsEqualityJoinCondition(cond)) { - continue; - } - auto rhs = cond.right.get(); - while (rhs->type == ExpressionType::OPERATOR_CAST) { - auto &cast = (BoundCastExpression &)*rhs; - rhs = cast.child.get(); - } - if (rhs->type != ExpressionType::BOUND_COLUMN_REF) { - throw InternalException("Error in Deliminator: expected a bound column reference"); - } - auto &colref = (BoundColumnRefExpression &)*rhs; - if (projection_map.find(colref.binding) != projection_map.end()) { - // value on the right is a projection of removed DelimGet - for (idx_t i = 0; i < decs->size(); i++) { - if (decs->at(i)->Equals(cond.left.get())) { - // the value on the left no longer needs to be a duplicate-eliminated column - decs->erase(decs->begin() + i); - break; - } - } - // whether we applied an IS NOT NULL filter - cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM; - } - } - // change type if there are no more duplicate-eliminated columns - if (decs->empty()) { - delim_join.type = LogicalOperatorType::LOGICAL_COMPARISON_JOIN; - } - } -} - -void DeliminatorPlanUpdater::VisitExpression(unique_ptr *expression) { - if (expr_map.find(expression->get()) != expr_map.end()) { - *expression = expr_map[expression->get()]->Copy(); - } else { - VisitExpressionChildren(**expression); - } -} - -unique_ptr Deliminator::Optimize(unique_ptr op) { - vector *> candidates; - FindCandidates(&op, candidates); - - for (auto &candidate : candidates) { - DeliminatorPlanUpdater updater; - if (RemoveCandidate(&op, candidate, updater)) { - updater.VisitOperator(*op); - } - } - return op; -} - -void Deliminator::FindCandidates(unique_ptr *op_ptr, - vector *> &candidates) { - auto op = op_ptr->get(); - // search children before adding, so the deepest candidates get added first - for (auto &child : op->children) { - FindCandidates(&child, candidates); - } - // search for projection/aggregate - if (op->type != LogicalOperatorType::LOGICAL_PROJECTION && - op->type != LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY) { - return; - } - // followed by a join - if (op->children[0]->type != LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { - return; - } - auto &join = *op->children[0]; - // with a DelimGet as a direct child (left or right) - if (join.children[0]->type == LogicalOperatorType::LOGICAL_DELIM_GET || - join.children[1]->type == LogicalOperatorType::LOGICAL_DELIM_GET) { - candidates.push_back(op_ptr); - return; - } - // or a filter followed by a DelimGet (left) - if (join.children[0]->type == LogicalOperatorType::LOGICAL_FILTER && - join.children[0]->children[0]->type == LogicalOperatorType::LOGICAL_DELIM_GET) { - candidates.push_back(op_ptr); - return; - } - // filter followed by a DelimGet (right) - if (join.children[1]->type == LogicalOperatorType::LOGICAL_FILTER && - join.children[1]->children[0]->type == LogicalOperatorType::LOGICAL_DELIM_GET) { - candidates.push_back(op_ptr); - return; - } -} - -static bool OperatorIsDelimGet(LogicalOperator &op) { - if (op.type == LogicalOperatorType::LOGICAL_DELIM_GET) { - return true; - } - if (op.type == LogicalOperatorType::LOGICAL_FILTER && - op.children[0]->type == LogicalOperatorType::LOGICAL_DELIM_GET) { - return true; - } - return false; -} - -static bool ChildJoinTypeCanBeDeliminated(JoinType &join_type) { - switch (join_type) { - case JoinType::INNER: - case JoinType::SEMI: - return true; - default: - return false; - } -} - -bool Deliminator::RemoveCandidate(unique_ptr *plan, unique_ptr *candidate, - DeliminatorPlanUpdater &updater) { - auto &proj_or_agg = **candidate; - auto &join = (LogicalComparisonJoin &)*proj_or_agg.children[0]; - if (!ChildJoinTypeCanBeDeliminated(join.join_type)) { - return false; - } - - // get the index (left or right) of the DelimGet side of the join - idx_t delim_idx = OperatorIsDelimGet(*join.children[0]) ? 0 : 1; - D_ASSERT(OperatorIsDelimGet(*join.children[delim_idx])); - // get the filter (if any) - LogicalFilter *filter = nullptr; - if (join.children[delim_idx]->type == LogicalOperatorType::LOGICAL_FILTER) { - filter = (LogicalFilter *)join.children[delim_idx].get(); - } - auto &delim_get = (LogicalDelimGet &)*(filter ? filter->children[0].get() : join.children[delim_idx].get()); - if (join.conditions.size() != delim_get.chunk_types.size()) { - // joining with DelimGet adds new information - return false; - } - // check if joining with the DelimGet is redundant, and collect relevant column information - bool all_equality_conditions = true; - vector nulls_are_not_equal_exprs; - for (auto &cond : join.conditions) { - all_equality_conditions = all_equality_conditions && IsEqualityJoinCondition(cond); - auto delim_side = delim_idx == 0 ? cond.left.get() : cond.right.get(); - auto other_side = delim_idx == 0 ? cond.right.get() : cond.left.get(); - if (delim_side->type != ExpressionType::BOUND_COLUMN_REF) { - // non-colref e.g. expression -(4, 1) in 4-i=j where i is from DelimGet - // FIXME: might be possible to also eliminate these - return false; - } - updater.expr_map[delim_side] = other_side; - if (cond.comparison != ExpressionType::COMPARE_NOT_DISTINCT_FROM) { - nulls_are_not_equal_exprs.push_back(other_side); - } - } - - // removed DelimGet columns are assigned a new ColumnBinding by Projection/Aggregation, keep track here - if (proj_or_agg.type == LogicalOperatorType::LOGICAL_PROJECTION) { - for (auto &cb : proj_or_agg.GetColumnBindings()) { - updater.projection_map[cb] = true; - updater.reverse_proj_or_agg_map[cb] = proj_or_agg.expressions[cb.column_index].get(); - for (auto &expr : nulls_are_not_equal_exprs) { - if (proj_or_agg.expressions[cb.column_index]->Equals(expr)) { - updater.projection_map[cb] = false; - break; - } - } - } - } else { - auto &agg = (LogicalAggregate &)proj_or_agg; - - // Create a vector of all exprs in the agg - vector all_agg_exprs; - for (auto &expr : agg.groups) { - all_agg_exprs.push_back(expr.get()); - } - for (auto &expr : agg.expressions) { - all_agg_exprs.push_back(expr.get()); - } - - for (auto &cb : agg.GetColumnBindings()) { - updater.projection_map[cb] = true; - updater.reverse_proj_or_agg_map[cb] = all_agg_exprs[cb.column_index]; - for (auto &expr : nulls_are_not_equal_exprs) { - if ((cb.table_index == agg.group_index && agg.groups[cb.column_index]->Equals(expr)) || - (cb.table_index == agg.aggregate_index && agg.expressions[cb.column_index]->Equals(expr))) { - updater.projection_map[cb] = false; - break; - } - } - } - } - - if (!all_equality_conditions) { - // we can get rid of an inequality join with a DelimGet, but only under specific circumstances - if (!RemoveInequalityCandidate(plan, candidate, updater)) { - return false; - } - } - - // make a filter if needed - if (!nulls_are_not_equal_exprs.empty() || filter != nullptr) { - auto filter_op = make_unique(); - if (!nulls_are_not_equal_exprs.empty()) { - // add an IS NOT NULL filter that was implicitly in JoinCondition::null_values_are_equal - for (auto &expr : nulls_are_not_equal_exprs) { - auto is_not_null_expr = - make_unique(ExpressionType::OPERATOR_IS_NOT_NULL, LogicalType::BOOLEAN); - is_not_null_expr->children.push_back(expr->Copy()); - filter_op->expressions.push_back(move(is_not_null_expr)); - } - } - if (filter != nullptr) { - for (auto &expr : filter->expressions) { - filter_op->expressions.push_back(move(expr)); - } - } - filter_op->children.push_back(move(join.children[1 - delim_idx])); - join.children[1 - delim_idx] = move(filter_op); - } - // temporarily save deleted operator so its expressions are still available - updater.temp_ptr = move(proj_or_agg.children[0]); - // replace the redundant join - proj_or_agg.children[0] = move(join.children[1 - delim_idx]); - return true; -} - -static void GetDelimJoins(LogicalOperator &op, vector &delim_joins) { - for (auto &child : op.children) { - GetDelimJoins(*child, delim_joins); - } - if (op.type == LogicalOperatorType::LOGICAL_DELIM_JOIN) { - delim_joins.push_back(&op); - } -} - -static bool HasChild(LogicalOperator *haystack, LogicalOperator *needle, idx_t &side) { - if (haystack == needle) { - return true; - } - for (idx_t i = 0; i < haystack->children.size(); i++) { - auto &child = haystack->children[i]; - idx_t dummy_side; - if (HasChild(child.get(), needle, dummy_side)) { - side = i; - return true; - } - } - return false; -} - -bool Deliminator::RemoveInequalityCandidate(unique_ptr *plan, unique_ptr *candidate, - DeliminatorPlanUpdater &updater) { - auto &proj_or_agg = **candidate; - // first, we find a DelimJoin in "plan" that has only one DelimGet as a child, which is in "candidate" - if (DelimGetCount(proj_or_agg) != 1) { - // the candidate therefore must have only a single DelimGet in its children - return false; - } - - vector delim_joins; - GetDelimJoins(**plan, delim_joins); - - LogicalOperator *parent = nullptr; - idx_t parent_delim_get_side; - for (auto dj : delim_joins) { - D_ASSERT(dj->type == LogicalOperatorType::LOGICAL_DELIM_JOIN); - if (!HasChild(dj, &proj_or_agg, parent_delim_get_side)) { - continue; - } - // we found a parent DelimJoin - if (DelimGetCount(*dj) != 1) { - // it has more than one DelimGet children - continue; - } - - // we can only remove inequality join with a DelimGet if the parent DelimJoin has one of these join types - auto &delim_join = (LogicalDelimJoin &)*dj; - if (!InequalityDelimJoinCanBeEliminated(delim_join.join_type)) { - continue; - } - - parent = dj; - break; - } - if (!parent) { - return false; - } - - // we found the parent delim join, and we may be able to remove the child DelimGet join - // but we need to make sure that their conditions refer to exactly the same columns - auto &parent_delim_join = (LogicalDelimJoin &)*parent; - auto &join = (LogicalComparisonJoin &)*proj_or_agg.children[0]; - if (parent_delim_join.conditions.size() != join.conditions.size()) { - // different number of conditions, can't replace - return false; - } - - // we can only do this optimization under the following conditions: - // 1. all join expressions coming from the DelimGet side are colrefs - // 2. these expressions refer to colrefs coming from the proj/agg on top of the child DelimGet join - // 3. the expression (before it was proj/agg) can be found in the conditions of the child DelimGet join - for (auto &parent_cond : parent_delim_join.conditions) { - auto &parent_expr = parent_delim_get_side == 0 ? parent_cond.left : parent_cond.right; - if (parent_expr->type != ExpressionType::BOUND_COLUMN_REF) { - // can only deal with colrefs - return false; - } - auto &parent_colref = (BoundColumnRefExpression &)*parent_expr; - auto it = updater.reverse_proj_or_agg_map.find(parent_colref.binding); - if (it == updater.reverse_proj_or_agg_map.end()) { - // refers to a column that was not in the child DelimGet join - return false; - } - // try to find the corresponding child condition - // TODO: can be more flexible - allow CAST - auto child_expr = it->second; - bool found = false; - for (auto &child_cond : join.conditions) { - if (child_cond.left->Equals(child_expr) || child_cond.right->Equals(child_expr)) { - found = true; - break; - } - } - if (!found) { - // could not find the mapped expression in the child condition expressions - return false; - } - } - - // TODO: we cannot perform the optimization here because our pure inequality joins don't implement - // JoinType::SINGLE yet - if (parent_delim_join.join_type == JoinType::SINGLE) { - bool has_one_equality = false; - for (auto &cond : join.conditions) { - has_one_equality = has_one_equality || IsEqualityJoinCondition(cond); - } - if (!has_one_equality) { - return false; - } - } - - // we are now sure that we can remove the child DelimGet join, so we basically do the same loop as above - // this time without checks because we already did them, and replace the expressions - for (auto &parent_cond : parent_delim_join.conditions) { - auto &parent_expr = parent_delim_get_side == 0 ? parent_cond.left : parent_cond.right; - auto &parent_colref = (BoundColumnRefExpression &)*parent_expr; - auto it = updater.reverse_proj_or_agg_map.find(parent_colref.binding); - auto child_expr = it->second; - for (auto &child_cond : join.conditions) { - if (!child_cond.left->Equals(child_expr) && !child_cond.right->Equals(child_expr)) { - continue; - } - parent_expr = - make_unique(parent_expr->alias, parent_expr->return_type, it->first); - parent_cond.comparison = - parent_delim_get_side == 0 ? child_cond.comparison : FlipComparisionExpression(child_cond.comparison); - break; - } - } - - // no longer needs to be a delim join - parent_delim_join.duplicate_eliminated_columns.clear(); - parent_delim_join.type = LogicalOperatorType::LOGICAL_COMPARISON_JOIN; - - return true; -} - -} // namespace duckdb - - - -namespace duckdb { - -template <> -double EstimatedProperties::GetCardinality() const { - return cardinality; -} - -template <> -idx_t EstimatedProperties::GetCardinality() const { - auto max_idx_t = NumericLimits::Maximum() - 10000; - return MinValue(cardinality, max_idx_t); -} - -double EstimatedProperties::GetCost() const { - return cost; -} - -void EstimatedProperties::SetCardinality(double new_card) { - cardinality = new_card; -} - -void EstimatedProperties::SetCost(double new_cost) { - cost = new_cost; -} - -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/optimizer/expression_heuristics.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -namespace duckdb { - -class ExpressionHeuristics : public LogicalOperatorVisitor { -public: - explicit ExpressionHeuristics(Optimizer &optimizer) : optimizer(optimizer) { - } - - Optimizer &optimizer; - unique_ptr root; - -public: - //! Search for filters to be reordered - unique_ptr Rewrite(unique_ptr op); - //! Reorder the expressions of a filter - void ReorderExpressions(vector> &expressions); - //! Return the cost of an expression - idx_t Cost(Expression &expr); - - unique_ptr VisitReplace(BoundConjunctionExpression &expr, unique_ptr *expr_ptr) override; - //! Override this function to search for filter operators - void VisitOperator(LogicalOperator &op) override; - -private: - unordered_map function_costs = { - {"+", 5}, {"-", 5}, {"&", 5}, {"#", 5}, - {">>", 5}, {"<<", 5}, {"abs", 5}, {"*", 10}, - {"%", 10}, {"/", 15}, {"date_part", 20}, {"year", 20}, - {"round", 100}, {"~~", 200}, {"!~~", 200}, {"regexp_matches", 200}, - {"||", 200}}; - - idx_t ExpressionCost(BoundBetweenExpression &expr); - idx_t ExpressionCost(BoundCaseExpression &expr); - idx_t ExpressionCost(BoundCastExpression &expr); - idx_t ExpressionCost(BoundComparisonExpression &expr); - idx_t ExpressionCost(BoundConjunctionExpression &expr); - idx_t ExpressionCost(BoundFunctionExpression &expr); - idx_t ExpressionCost(BoundOperatorExpression &expr, ExpressionType &expr_type); - idx_t ExpressionCost(PhysicalType return_type, idx_t multiplier); -}; -} // namespace duckdb - - - -namespace duckdb { - -unique_ptr ExpressionHeuristics::Rewrite(unique_ptr op) { - VisitOperator(*op); - return op; -} - -void ExpressionHeuristics::VisitOperator(LogicalOperator &op) { - if (op.type == LogicalOperatorType::LOGICAL_FILTER) { - // reorder all filter expressions - if (op.expressions.size() > 1) { - ReorderExpressions(op.expressions); - } - } - - // traverse recursively through the operator tree - VisitOperatorChildren(op); - VisitOperatorExpressions(op); -} - -unique_ptr ExpressionHeuristics::VisitReplace(BoundConjunctionExpression &expr, - unique_ptr *expr_ptr) { - ReorderExpressions(expr.children); - return nullptr; -} - -void ExpressionHeuristics::ReorderExpressions(vector> &expressions) { - - struct ExpressionCosts { - unique_ptr expr; - idx_t cost; - - bool operator==(const ExpressionCosts &p) const { - return cost == p.cost; - } - bool operator<(const ExpressionCosts &p) const { - return cost < p.cost; - } - }; - - vector expression_costs; - // iterate expressions, get cost for each one - for (idx_t i = 0; i < expressions.size(); i++) { - idx_t cost = Cost(*expressions[i]); - expression_costs.push_back({move(expressions[i]), cost}); - } - - // sort by cost and put back in place - sort(expression_costs.begin(), expression_costs.end()); - for (idx_t i = 0; i < expression_costs.size(); i++) { - expressions[i] = move(expression_costs[i].expr); - } -} - -idx_t ExpressionHeuristics::ExpressionCost(BoundBetweenExpression &expr) { - return Cost(*expr.input) + Cost(*expr.lower) + Cost(*expr.upper) + 10; -} - -idx_t ExpressionHeuristics::ExpressionCost(BoundCaseExpression &expr) { - // CASE WHEN check THEN result_if_true ELSE result_if_false END - idx_t case_cost = 0; - for (auto &case_check : expr.case_checks) { - case_cost += Cost(*case_check.then_expr); - case_cost += Cost(*case_check.when_expr); - } - case_cost += Cost(*expr.else_expr); - return case_cost; -} - -idx_t ExpressionHeuristics::ExpressionCost(BoundCastExpression &expr) { - // OPERATOR_CAST - // determine cast cost by comparing cast_expr.source_type and cast_expr_target_type - idx_t cast_cost = 0; - if (expr.return_type != expr.source_type()) { - // if cast from or to varchar - // TODO: we might want to add more cases - if (expr.return_type.id() == LogicalTypeId::VARCHAR || expr.source_type().id() == LogicalTypeId::VARCHAR || - expr.return_type.id() == LogicalTypeId::BLOB || expr.source_type().id() == LogicalTypeId::BLOB) { - cast_cost = 200; - } else { - cast_cost = 5; - } - } - return Cost(*expr.child) + cast_cost; -} - -idx_t ExpressionHeuristics::ExpressionCost(BoundComparisonExpression &expr) { - // COMPARE_EQUAL, COMPARE_NOTEQUAL, COMPARE_GREATERTHAN, COMPARE_GREATERTHANOREQUALTO, COMPARE_LESSTHAN, - // COMPARE_LESSTHANOREQUALTO - return Cost(*expr.left) + 5 + Cost(*expr.right); -} - -idx_t ExpressionHeuristics::ExpressionCost(BoundConjunctionExpression &expr) { - // CONJUNCTION_AND, CONJUNCTION_OR - idx_t cost = 5; - for (auto &child : expr.children) { - cost += Cost(*child); - } - return cost; -} - -idx_t ExpressionHeuristics::ExpressionCost(BoundFunctionExpression &expr) { - idx_t cost_children = 0; - for (auto &child : expr.children) { - cost_children += Cost(*child); - } - - auto cost_function = function_costs.find(expr.function.name); - if (cost_function != function_costs.end()) { - return cost_children + cost_function->second; - } else { - return cost_children + 1000; - } -} - -idx_t ExpressionHeuristics::ExpressionCost(BoundOperatorExpression &expr, ExpressionType &expr_type) { - idx_t sum = 0; - for (auto &child : expr.children) { - sum += Cost(*child); - } - - // OPERATOR_IS_NULL, OPERATOR_IS_NOT_NULL - if (expr_type == ExpressionType::OPERATOR_IS_NULL || expr_type == ExpressionType::OPERATOR_IS_NOT_NULL) { - return sum + 5; - } else if (expr_type == ExpressionType::COMPARE_IN || expr_type == ExpressionType::COMPARE_NOT_IN) { - // COMPARE_IN, COMPARE_NOT_IN - return sum + (expr.children.size() - 1) * 100; - } else if (expr_type == ExpressionType::OPERATOR_NOT) { - // OPERATOR_NOT - return sum + 10; // TODO: evaluate via measured runtimes - } else { - return sum + 1000; - } -} - -idx_t ExpressionHeuristics::ExpressionCost(PhysicalType return_type, idx_t multiplier) { - // TODO: ajust values according to benchmark results - switch (return_type) { - case PhysicalType::VARCHAR: - return 5 * multiplier; - case PhysicalType::FLOAT: - case PhysicalType::DOUBLE: - return 2 * multiplier; - default: - return 1 * multiplier; - } -} - -idx_t ExpressionHeuristics::Cost(Expression &expr) { - switch (expr.expression_class) { - case ExpressionClass::BOUND_CASE: { - auto &case_expr = (BoundCaseExpression &)expr; - return ExpressionCost(case_expr); - } - case ExpressionClass::BOUND_BETWEEN: { - auto &between_expr = (BoundBetweenExpression &)expr; - return ExpressionCost(between_expr); - } - case ExpressionClass::BOUND_CAST: { - auto &cast_expr = (BoundCastExpression &)expr; - return ExpressionCost(cast_expr); - } - case ExpressionClass::BOUND_COMPARISON: { - auto &comp_expr = (BoundComparisonExpression &)expr; - return ExpressionCost(comp_expr); - } - case ExpressionClass::BOUND_CONJUNCTION: { - auto &conj_expr = (BoundConjunctionExpression &)expr; - return ExpressionCost(conj_expr); - } - case ExpressionClass::BOUND_FUNCTION: { - auto &func_expr = (BoundFunctionExpression &)expr; - return ExpressionCost(func_expr); - } - case ExpressionClass::BOUND_OPERATOR: { - auto &op_expr = (BoundOperatorExpression &)expr; - return ExpressionCost(op_expr, expr.type); - } - case ExpressionClass::BOUND_COLUMN_REF: { - auto &col_expr = (BoundColumnRefExpression &)expr; - return ExpressionCost(col_expr.return_type.InternalType(), 8); - } - case ExpressionClass::BOUND_CONSTANT: { - auto &const_expr = (BoundConstantExpression &)expr; - return ExpressionCost(const_expr.return_type.InternalType(), 1); - } - case ExpressionClass::BOUND_PARAMETER: { - auto &const_expr = (BoundParameterExpression &)expr; - return ExpressionCost(const_expr.return_type.InternalType(), 1); - } - case ExpressionClass::BOUND_REF: { - auto &col_expr = (BoundColumnRefExpression &)expr; - return ExpressionCost(col_expr.return_type.InternalType(), 8); - } - default: { - break; - } - } - - // return a very high value if nothing matches - return 1000; -} - -} // namespace duckdb - - - - - - - - - -namespace duckdb { - -unique_ptr ExpressionRewriter::ApplyRules(LogicalOperator &op, const vector &rules, - unique_ptr expr, bool &changes_made, bool is_root) { - for (auto &rule : rules) { - vector bindings; - if (rule->root->Match(expr.get(), bindings)) { - // the rule matches! try to apply it - bool rule_made_change = false; - auto result = rule->Apply(op, bindings, rule_made_change, is_root); - if (result) { - changes_made = true; - // the base node changed: the rule applied changes - // rerun on the new node - return ExpressionRewriter::ApplyRules(op, rules, move(result), changes_made); - } else if (rule_made_change) { - changes_made = true; - // the base node didn't change, but changes were made, rerun - return expr; - } - // else nothing changed, continue to the next rule - continue; - } - } - // no changes could be made to this node - // recursively run on the children of this node - ExpressionIterator::EnumerateChildren(*expr, [&](unique_ptr &child) { - child = ExpressionRewriter::ApplyRules(op, rules, move(child), changes_made); - }); - return expr; -} - -unique_ptr ExpressionRewriter::ConstantOrNull(unique_ptr child, Value value) { - vector> children; - children.push_back(make_unique(value)); - children.push_back(move(child)); - return ConstantOrNull(move(children), move(value)); -} - -unique_ptr ExpressionRewriter::ConstantOrNull(vector> children, Value value) { - auto type = value.type(); - children.insert(children.begin(), make_unique(value)); - return make_unique(type, ConstantOrNull::GetFunction(type), move(children), - ConstantOrNull::Bind(move(value))); -} - -void ExpressionRewriter::VisitOperator(LogicalOperator &op) { - VisitOperatorChildren(op); - this->op = &op; - - to_apply_rules.clear(); - for (auto &rule : rules) { - if (rule->logical_root && !rule->logical_root->Match(op.type)) { - // this rule does not apply to this type of LogicalOperator - continue; - } - to_apply_rules.push_back(rule.get()); - } - if (to_apply_rules.empty()) { - // no rules to apply on this node - return; - } - - VisitOperatorExpressions(op); - - // if it is a LogicalFilter, we split up filter conjunctions again - if (op.type == LogicalOperatorType::LOGICAL_FILTER) { - auto &filter = (LogicalFilter &)op; - filter.SplitPredicates(); - } -} - -void ExpressionRewriter::VisitExpression(unique_ptr *expression) { - bool changes_made; - do { - changes_made = false; - *expression = ExpressionRewriter::ApplyRules(*op, to_apply_rules, move(*expression), changes_made, true); - } while (changes_made); -} - -ClientContext &Rule::GetContext() const { - return rewriter.context; +ClientContext &Rule::GetContext() const { + return rewriter.context; } } // namespace duckdb @@ -164786,7 +173608,7 @@ Expression *FilterCombiner::GetNode(Expression *expr) { auto copy = expr->Copy(); auto pointer_copy = copy.get(); D_ASSERT(stored_expressions.find(pointer_copy) == stored_expressions.end()); - stored_expressions.insert(make_pair(pointer_copy, move(copy))); + stored_expressions.insert(make_pair(pointer_copy, std::move(copy))); return pointer_copy; } @@ -164840,7 +173662,7 @@ FilterResult FilterCombiner::AddFilter(unique_ptr expr) { auto result = AddFilter(expr.get()); if (result == FilterResult::UNSUPPORTED) { // unsupported filter, push into remaining filters - remaining_filters.push_back(move(expr)); + remaining_filters.push_back(std::move(expr)); return FilterResult::SUCCESS; } return result; @@ -164849,7 +173671,7 @@ FilterResult FilterCombiner::AddFilter(unique_ptr expr) { void FilterCombiner::GenerateFilters(const std::function filter)> &callback) { // first loop over the remaining filters for (auto &filter : remaining_filters) { - callback(move(filter)); + callback(std::move(filter)); } remaining_filters.clear(); // now loop over the equivalence sets @@ -164862,11 +173684,13 @@ void FilterCombiner::GenerateFilters(const std::function(ExpressionType::COMPARE_EQUAL, entries[i]->Copy(), entries[k]->Copy()); - callback(move(comparison)); + callback(std::move(comparison)); } // for each entry also create a comparison with each constant - int lower_index = -1, upper_index = -1; - bool lower_inclusive, upper_inclusive; + int lower_index = -1; + int upper_index = -1; + bool lower_inclusive = false; + bool upper_inclusive = false; for (idx_t k = 0; k < constant_list.size(); k++) { auto &info = constant_list[k]; if (info.comparison_type == ExpressionType::COMPARE_GREATERTHAN || @@ -164880,29 +173704,30 @@ void FilterCombiner::GenerateFilters(const std::function(info.constant); auto comparison = make_unique(info.comparison_type, entries[i]->Copy(), - move(constant)); - callback(move(comparison)); + std::move(constant)); + callback(std::move(comparison)); } } if (lower_index >= 0 && upper_index >= 0) { // found both lower and upper index, create a BETWEEN expression auto lower_constant = make_unique(constant_list[lower_index].constant); auto upper_constant = make_unique(constant_list[upper_index].constant); - auto between = make_unique( - entries[i]->Copy(), move(lower_constant), move(upper_constant), lower_inclusive, upper_inclusive); - callback(move(between)); + auto between = + make_unique(entries[i]->Copy(), std::move(lower_constant), + std::move(upper_constant), lower_inclusive, upper_inclusive); + callback(std::move(between)); } else if (lower_index >= 0) { // only lower index found, create simple comparison expression auto constant = make_unique(constant_list[lower_index].constant); auto comparison = make_unique(constant_list[lower_index].comparison_type, - entries[i]->Copy(), move(constant)); - callback(move(comparison)); + entries[i]->Copy(), std::move(constant)); + callback(std::move(comparison)); } else if (upper_index >= 0) { // only upper index found, create simple comparison expression auto constant = make_unique(constant_list[upper_index].constant); auto comparison = make_unique(constant_list[upper_index].comparison_type, - entries[i]->Copy(), move(constant)); - callback(move(comparison)); + entries[i]->Copy(), std::move(constant)); + callback(std::move(comparison)); } } } @@ -165168,7 +173993,7 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector &column_id for (idx_t k = 0; k < constant_list.size(); k++) { auto constant_filter = make_unique(constant_value.second[k].comparison_type, constant_value.second[k].constant); - table_filters.PushFilter(column_index, move(constant_filter)); + table_filters.PushFilter(column_index, std::move(constant_filter)); } table_filters.PushFilter(column_index, make_unique()); } @@ -165198,8 +174023,8 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector &column_id make_unique(ExpressionType::COMPARE_GREATERTHANOREQUALTO, Value(like_string)); like_string[like_string.size() - 1]++; auto upper_bound = make_unique(ExpressionType::COMPARE_LESSTHAN, Value(like_string)); - table_filters.PushFilter(column_index, move(lower_bound)); - table_filters.PushFilter(column_index, move(upper_bound)); + table_filters.PushFilter(column_index, std::move(lower_bound)); + table_filters.PushFilter(column_index, std::move(upper_bound)); table_filters.PushFilter(column_index, make_unique()); } if (func.function.name == "~~" && func.children[0]->expression_class == ExpressionClass::BOUND_COLUMN_REF && @@ -165225,7 +174050,7 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector &column_id if (equality) { //! Here the like can be transformed to an equality query auto equal_filter = make_unique(ExpressionType::COMPARE_EQUAL, Value(prefix)); - table_filters.PushFilter(column_index, move(equal_filter)); + table_filters.PushFilter(column_index, std::move(equal_filter)); table_filters.PushFilter(column_index, make_unique()); } else { //! Here the like must be transformed to a BOUND COMPARISON geq le @@ -165233,8 +174058,8 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector &column_id make_unique(ExpressionType::COMPARE_GREATERTHANOREQUALTO, Value(prefix)); prefix[prefix.size() - 1]++; auto upper_bound = make_unique(ExpressionType::COMPARE_LESSTHAN, Value(prefix)); - table_filters.PushFilter(column_index, move(lower_bound)); - table_filters.PushFilter(column_index, move(upper_bound)); + table_filters.PushFilter(column_index, std::move(lower_bound)); + table_filters.PushFilter(column_index, std::move(upper_bound)); table_filters.PushFilter(column_index, make_unique()); } } @@ -165297,8 +174122,8 @@ TableFilterSet FilterCombiner::GenerateTableScanFilters(vector &column_id Value::Numeric(type, in_values.front())); auto upper_bound = make_unique(ExpressionType::COMPARE_LESSTHANOREQUALTO, Value::Numeric(type, in_values.back())); - table_filters.PushFilter(column_index, move(lower_bound)); - table_filters.PushFilter(column_index, move(upper_bound)); + table_filters.PushFilter(column_index, std::move(lower_bound)); + table_filters.PushFilter(column_index, std::move(upper_bound)); table_filters.PushFilter(column_index, make_unique()); remaining_filters.erase(remaining_filters.begin() + rem_fil_idx); @@ -165325,7 +174150,7 @@ FilterResult FilterCombiner::AddBoundComparisonFilter(Expression *expr) { comparison.type != ExpressionType::COMPARE_GREATERTHAN && comparison.type != ExpressionType::COMPARE_GREATERTHANOREQUALTO && comparison.type != ExpressionType::COMPARE_EQUAL && comparison.type != ExpressionType::COMPARE_NOTEQUAL) { - // only support [>, >=, <, <=, ==] expressions + // only support [>, >=, <, <=, ==, !=] expressions return FilterResult::UNSUPPORTED; } // check if one of the sides is a scalar value @@ -165353,6 +174178,7 @@ FilterResult FilterCombiner::AddBoundComparisonFilter(Expression *expr) { // get the current bucket of constant values D_ASSERT(constant_values.find(equivalence_set) != constant_values.end()); auto &info_list = constant_values.find(equivalence_set)->second; + D_ASSERT(node->return_type == info.constant.type()); // check the existing constant comparisons to see if we can do any pruning auto ret = AddConstantComparison(info_list, info); @@ -165362,7 +174188,7 @@ FilterResult FilterCombiner::AddBoundComparisonFilter(Expression *expr) { // try to add transitive filters if (AddTransitiveFilters((BoundComparisonExpression &)*transitive_filter) == FilterResult::UNSUPPORTED) { // in case of unsuccessful re-add filter into remaining ones - remaining_filters.push_back(move(transitive_filter)); + remaining_filters.push_back(std::move(transitive_filter)); } } return ret; @@ -165473,7 +174299,7 @@ FilterResult FilterCombiner::AddFilter(Expression *expr) { : ExpressionType::COMPARE_LESSTHAN; auto left = comparison.lower->Copy(); auto right = comparison.input->Copy(); - auto lower_comp = make_unique(type, move(left), move(right)); + auto lower_comp = make_unique(type, std::move(left), std::move(right)); result = AddBoundComparisonFilter(lower_comp.get()); } @@ -165508,7 +174334,7 @@ FilterResult FilterCombiner::AddFilter(Expression *expr) { : ExpressionType::COMPARE_LESSTHAN; auto left = comparison.input->Copy(); auto right = comparison.upper->Copy(); - auto upper_comp = make_unique(type, move(left), move(right)); + auto upper_comp = make_unique(type, std::move(left), std::move(right)); result = AddBoundComparisonFilter(upper_comp.get()); } @@ -165538,7 +174364,8 @@ FilterResult FilterCombiner::AddTransitiveFilters(BoundComparisonExpression &com for (auto &stored_exp : stored_expressions) { if (stored_exp.first->type == ExpressionType::BOUND_COLUMN_REF) { auto &st_col_ref = (BoundColumnRefExpression &)*stored_exp.second; - if (st_col_ref.binding == col_ref.binding) { + if (st_col_ref.binding == col_ref.binding && + bound_cast_expr.return_type == stored_exp.second->return_type) { bound_cast_expr.child = stored_exp.second->Copy(); right_node = GetNode(bound_cast_expr.child.get()); break; @@ -165587,7 +174414,7 @@ FilterResult FilterCombiner::AddTransitiveFilters(BoundComparisonExpression &com // Add the filter j >= i in the remaing filters auto filter = make_unique(comparison.type, comparison.left->Copy(), comparison.right->Copy()); - remaining_filters.push_back(move(filter)); + remaining_filters.push_back(std::move(filter)); is_inserted = true; } } else if ((comparison.type == ExpressionType::COMPARE_GREATERTHAN && @@ -165602,7 +174429,7 @@ FilterResult FilterCombiner::AddTransitiveFilters(BoundComparisonExpression &com // Add the filter j [>, <] i auto filter = make_unique(comparison.type, comparison.left->Copy(), comparison.right->Copy()); - remaining_filters.push_back(move(filter)); + remaining_filters.push_back(std::move(filter)); is_inserted = true; } } else { @@ -165622,7 +174449,7 @@ FilterResult FilterCombiner::AddTransitiveFilters(BoundComparisonExpression &com // try to add transitive filters if (AddTransitiveFilters((BoundComparisonExpression &)*transitive_filter) == FilterResult::UNSUPPORTED) { // in case of unsuccessful re-add filter into remaining ones - remaining_filters.push_back(move(transitive_filter)); + remaining_filters.push_back(std::move(transitive_filter)); } } return FilterResult::SUCCESS; @@ -165643,7 +174470,7 @@ unique_ptr FilterCombiner::FindTransitiveFilter(Expression *expr) { if (remaining_filters[i]->GetExpressionClass() == ExpressionClass::BOUND_COMPARISON) { auto comparison = (BoundComparisonExpression *)remaining_filters[i].get(); if (expr->Equals(comparison->right.get()) && comparison->type != ExpressionType::COMPARE_NOTEQUAL) { - auto filter = move(remaining_filters[i]); + auto filter = std::move(remaining_filters[i]); remaining_filters.erase(remaining_filters.begin() + i); return filter; } @@ -165890,11 +174717,11 @@ ValueComparisonResult CompareValueInformation(ExpressionValueInformation &left, // or_conjunction->children.emplace_back(comparison_expr->Copy()); // // unique_ptr conjs_to_push = make_unique(); -// conjs_to_push->conjunctions.emplace_back(move(or_conjunction)); +// conjs_to_push->conjunctions.emplace_back(std::move(or_conjunction)); // conjs_to_push->root_or = cur_root_or; // // auto &&vec_col_conjs = map_col_conjunctions[column_ref]; -// vec_col_conjs.emplace_back(move(conjs_to_push)); +// vec_col_conjs.emplace_back(std::move(conjs_to_push)); // vec_colref_insertion_order.emplace_back(column_ref); // return true; // } @@ -165924,7 +174751,7 @@ ValueComparisonResult CompareValueInformation(ExpressionValueInformation &left, // } else { // auto new_conjunction = make_unique(cur_conjunction->GetExpressionType()); // new_conjunction->children.emplace_back(comparison_expr->Copy()); -// conjunctions_to_push->conjunctions.emplace_back(move(new_conjunction)); +// conjunctions_to_push->conjunctions.emplace_back(std::move(new_conjunction)); // } // return true; //} @@ -165951,7 +174778,7 @@ ValueComparisonResult CompareValueInformation(ExpressionValueInformation &left, // GenerateConjunctionFilter(conjunction.get(), last_conj_filter); // } // } -// table_filter.PushFilter(column_index, move(root_or_filter)); +// table_filter.PushFilter(column_index, std::move(root_or_filter)); // } // } // map_col_conjunctions.clear(); @@ -166038,26 +174865,26 @@ namespace duckdb { unique_ptr FilterPullup::Rewrite(unique_ptr op) { switch (op->type) { case LogicalOperatorType::LOGICAL_FILTER: - return PullupFilter(move(op)); + return PullupFilter(std::move(op)); case LogicalOperatorType::LOGICAL_PROJECTION: - return PullupProjection(move(op)); + return PullupProjection(std::move(op)); case LogicalOperatorType::LOGICAL_CROSS_PRODUCT: - return PullupCrossProduct(move(op)); + return PullupCrossProduct(std::move(op)); case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: case LogicalOperatorType::LOGICAL_ANY_JOIN: case LogicalOperatorType::LOGICAL_DELIM_JOIN: - return PullupJoin(move(op)); + return PullupJoin(std::move(op)); case LogicalOperatorType::LOGICAL_INTERSECT: case LogicalOperatorType::LOGICAL_EXCEPT: - return PullupSetOperation(move(op)); + return PullupSetOperation(std::move(op)); case LogicalOperatorType::LOGICAL_DISTINCT: case LogicalOperatorType::LOGICAL_ORDER_BY: { // we can just pull directly through these operations without any rewriting - op->children[0] = Rewrite(move(op->children[0])); + op->children[0] = Rewrite(std::move(op->children[0])); return op; } default: - return FinishPullup(move(op)); + return FinishPullup(std::move(op)); } } @@ -166068,52 +174895,54 @@ unique_ptr FilterPullup::PullupJoin(unique_ptr switch (join.join_type) { case JoinType::INNER: - return PullupInnerJoin(move(op)); + return PullupInnerJoin(std::move(op)); case JoinType::LEFT: case JoinType::ANTI: case JoinType::SEMI: { - return PullupFromLeft(move(op)); + return PullupFromLeft(std::move(op)); } default: // unsupported join type: call children pull up - return FinishPullup(move(op)); + return FinishPullup(std::move(op)); } } unique_ptr FilterPullup::PullupInnerJoin(unique_ptr op) { D_ASSERT(((LogicalJoin &)*op).join_type == JoinType::INNER); - D_ASSERT(op->type != LogicalOperatorType::LOGICAL_DELIM_JOIN); - return PullupBothSide(move(op)); + if (op->type == LogicalOperatorType::LOGICAL_DELIM_JOIN) { + return op; + } + return PullupBothSide(std::move(op)); } unique_ptr FilterPullup::PullupCrossProduct(unique_ptr op) { D_ASSERT(op->type == LogicalOperatorType::LOGICAL_CROSS_PRODUCT); - return PullupBothSide(move(op)); + return PullupBothSide(std::move(op)); } unique_ptr FilterPullup::GeneratePullupFilter(unique_ptr child, vector> &expressions) { unique_ptr filter = make_unique(); for (idx_t i = 0; i < expressions.size(); ++i) { - filter->expressions.push_back(move(expressions[i])); + filter->expressions.push_back(std::move(expressions[i])); } expressions.clear(); - filter->children.push_back(move(child)); - return move(filter); + filter->children.push_back(std::move(child)); + return std::move(filter); } unique_ptr FilterPullup::FinishPullup(unique_ptr op) { // unhandled type, first perform filter pushdown in its children for (idx_t i = 0; i < op->children.size(); i++) { FilterPullup pullup; - op->children[i] = pullup.Rewrite(move(op->children[i])); + op->children[i] = pullup.Rewrite(std::move(op->children[i])); } // now pull up any existing filters if (filters_expr_pullup.empty()) { // no filters to pull up return op; } - return GeneratePullupFilter(move(op), filters_expr_pullup); + return GeneratePullupFilter(std::move(op), filters_expr_pullup); } } // namespace duckdb @@ -166147,7 +174976,7 @@ class FilterPushdown { Filter() { } - explicit Filter(unique_ptr filter) : filter(move(filter)) { + explicit Filter(unique_ptr filter) : filter(std::move(filter)) { } void ExtractBindings(); @@ -166219,33 +175048,33 @@ unique_ptr FilterPushdown::Rewrite(unique_ptr D_ASSERT(!combiner.HasFilters()); switch (op->type) { case LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY: - return PushdownAggregate(move(op)); + return PushdownAggregate(std::move(op)); case LogicalOperatorType::LOGICAL_FILTER: - return PushdownFilter(move(op)); + return PushdownFilter(std::move(op)); case LogicalOperatorType::LOGICAL_CROSS_PRODUCT: - return PushdownCrossProduct(move(op)); + return PushdownCrossProduct(std::move(op)); case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: case LogicalOperatorType::LOGICAL_ANY_JOIN: case LogicalOperatorType::LOGICAL_DELIM_JOIN: - return PushdownJoin(move(op)); + return PushdownJoin(std::move(op)); case LogicalOperatorType::LOGICAL_PROJECTION: - return PushdownProjection(move(op)); + return PushdownProjection(std::move(op)); case LogicalOperatorType::LOGICAL_INTERSECT: case LogicalOperatorType::LOGICAL_EXCEPT: case LogicalOperatorType::LOGICAL_UNION: - return PushdownSetOperation(move(op)); + return PushdownSetOperation(std::move(op)); case LogicalOperatorType::LOGICAL_DISTINCT: case LogicalOperatorType::LOGICAL_ORDER_BY: { // we can just push directly through these operations without any rewriting - op->children[0] = Rewrite(move(op->children[0])); + op->children[0] = Rewrite(std::move(op->children[0])); return op; } case LogicalOperatorType::LOGICAL_GET: - return PushdownGet(move(op)); + return PushdownGet(std::move(op)); case LogicalOperatorType::LOGICAL_LIMIT: - return PushdownLimit(move(op)); + return PushdownLimit(std::move(op)); default: - return FinishPushdown(move(op)); + return FinishPushdown(std::move(op)); } } @@ -166259,21 +175088,21 @@ unique_ptr FilterPushdown::PushdownJoin(unique_ptrfilter)); + auto result = combiner.AddFilter(std::move(f->filter)); D_ASSERT(result != FilterResult::UNSUPPORTED); (void)result; } @@ -166284,11 +175113,11 @@ FilterResult FilterPushdown::AddFilter(unique_ptr expr) { PushFilters(); // split up the filters by AND predicate vector> expressions; - expressions.push_back(move(expr)); + expressions.push_back(std::move(expr)); LogicalFilter::SplitPredicates(expressions); // push the filters into the combiner for (auto &child_expr : expressions) { - if (combiner.AddFilter(move(child_expr)) == FilterResult::UNSATISFIABLE) { + if (combiner.AddFilter(std::move(child_expr)) == FilterResult::UNSATISFIABLE) { return FilterResult::UNSATISFIABLE; } } @@ -166302,9 +175131,9 @@ void FilterPushdown::GenerateFilters() { } combiner.GenerateFilters([&](unique_ptr filter) { auto f = make_unique(); - f->filter = move(filter); + f->filter = std::move(filter); f->ExtractBindings(); - filters.push_back(move(f)); + filters.push_back(std::move(f)); }); } @@ -166312,7 +175141,7 @@ unique_ptr FilterPushdown::FinishPushdown(unique_ptrchildren) { FilterPushdown pushdown(optimizer); - child = pushdown.Rewrite(move(child)); + child = pushdown.Rewrite(std::move(child)); } // now push any existing filters if (filters.empty()) { @@ -166321,10 +175150,10 @@ unique_ptr FilterPushdown::FinishPushdown(unique_ptr(); for (auto &f : filters) { - filter->expressions.push_back(move(f->filter)); + filter->expressions.push_back(std::move(f->filter)); } - filter->children.push_back(move(op)); - return move(filter); + filter->children.push_back(std::move(op)); + return std::move(filter); } void FilterPushdown::Filter::ExtractBindings() { @@ -166379,13 +175208,13 @@ namespace duckdb { unique_ptr InClauseRewriter::Rewrite(unique_ptr op) { if (op->children.size() == 1) { - root = move(op->children[0]); + root = std::move(op->children[0]); VisitOperatorExpressions(*op); - op->children[0] = move(root); + op->children[0] = std::move(root); } for (auto &child : op->children) { - child = Rewrite(move(child)); + child = Rewrite(std::move(child)); } return op; } @@ -166412,7 +175241,7 @@ unique_ptr InClauseRewriter::VisitReplace(BoundOperatorExpression &e // NOT IN: turn into X <> 1 return make_unique(is_regular_in ? ExpressionType::COMPARE_EQUAL : ExpressionType::COMPARE_NOTEQUAL, - move(expr.children[0]), move(expr.children[1])); + std::move(expr.children[0]), std::move(expr.children[1])); } if (expr.children.size() < 6 || !all_scalar) { // low amount of children or not all scalar @@ -166423,9 +175252,9 @@ unique_ptr InClauseRewriter::VisitReplace(BoundOperatorExpression &e for (idx_t i = 1; i < expr.children.size(); i++) { conjunction->children.push_back(make_unique( is_regular_in ? ExpressionType::COMPARE_EQUAL : ExpressionType::COMPARE_NOTEQUAL, - expr.children[0]->Copy(), move(expr.children[i]))); + expr.children[0]->Copy(), std::move(expr.children[i]))); } - return move(conjunction); + return std::move(conjunction); } // IN clause with many constant children // generate a mark join that replaces this IN expression @@ -166451,21 +175280,21 @@ unique_ptr InClauseRewriter::VisitReplace(BoundOperatorExpression &e } // now generate a ChunkGet that scans this collection auto chunk_index = optimizer.binder.GenerateTableIndex(); - auto chunk_scan = make_unique(chunk_index, types, move(collection)); + auto chunk_scan = make_unique(chunk_index, types, std::move(collection)); // then we generate the MARK join with the chunk scan on the RHS auto join = make_unique(JoinType::MARK); join->mark_index = chunk_index; - join->AddChild(move(root)); - join->AddChild(move(chunk_scan)); + join->AddChild(std::move(root)); + join->AddChild(std::move(chunk_scan)); // create the JOIN condition JoinCondition cond; - cond.left = move(expr.children[0]); + cond.left = std::move(expr.children[0]); cond.right = make_unique(in_type, ColumnBinding(chunk_index, 0)); cond.comparison = ExpressionType::COMPARE_EQUAL; - join->conditions.push_back(move(cond)); - root = move(join); + join->conditions.push_back(std::move(cond)); + root = std::move(join); // we replace the original subquery with a BoundColumnRefExpression referring to the mark column unique_ptr result = @@ -166473,8 +175302,8 @@ unique_ptr InClauseRewriter::VisitReplace(BoundOperatorExpression &e if (!is_regular_in) { // NOT IN: invert auto invert = make_unique(ExpressionType::OPERATOR_NOT, LogicalType::BOOLEAN); - invert->children.push_back(move(result)); - result = move(invert); + invert->children.push_back(std::move(result)); + result = std::move(invert); } return result; } @@ -166491,6 +175320,618 @@ unique_ptr InClauseRewriter::VisitReplace(BoundOperatorExpression &e +namespace duckdb { + +static TableCatalogEntry *GetCatalogTableEntry(LogicalOperator *op) { + if (op->type == LogicalOperatorType::LOGICAL_GET) { + auto get = (LogicalGet *)op; + TableCatalogEntry *entry = get->GetTable(); + return entry; + } + for (auto &child : op->children) { + TableCatalogEntry *entry = GetCatalogTableEntry(child.get()); + if (entry != nullptr) { + return entry; + } + } + return nullptr; +} + +// The filter was made on top of a logical sample or other projection, +// but no specific columns are referenced. See issue 4978 number 4. +bool CardinalityEstimator::EmptyFilter(FilterInfo *filter_info) { + if (!filter_info->left_set && !filter_info->right_set) { + return true; + } + return false; +} + +void CardinalityEstimator::AddRelationTdom(FilterInfo *filter_info) { + D_ASSERT(filter_info->set->count >= 1); + for (const RelationsToTDom &r2tdom : relations_to_tdoms) { + auto &i_set = r2tdom.equivalent_relations; + if (i_set.find(filter_info->left_binding) != i_set.end()) { + // found an equivalent filter + return; + } + } + auto key = ColumnBinding(filter_info->left_binding.table_index, filter_info->left_binding.column_index); + column_binding_set_t tmp({key}); + relations_to_tdoms.emplace_back(RelationsToTDom(tmp)); +} + +bool CardinalityEstimator::SingleColumnFilter(FilterInfo *filter_info) { + if (filter_info->left_set && filter_info->right_set) { + // Both set + return false; + } + if (EmptyFilter(filter_info)) { + return false; + } + return true; +} + +vector CardinalityEstimator::DetermineMatchingEquivalentSets(FilterInfo *filter_info) { + vector matching_equivalent_sets; + auto equivalent_relation_index = 0; + + for (const RelationsToTDom &r2tdom : relations_to_tdoms) { + auto &i_set = r2tdom.equivalent_relations; + if (i_set.find(filter_info->left_binding) != i_set.end()) { + matching_equivalent_sets.push_back(equivalent_relation_index); + } else if (i_set.find(filter_info->right_binding) != i_set.end()) { + // don't add both left and right to the matching_equivalent_sets + // since both left and right get added to that index anyway. + matching_equivalent_sets.push_back(equivalent_relation_index); + } + equivalent_relation_index++; + } + return matching_equivalent_sets; +} + +void CardinalityEstimator::AddToEquivalenceSets(FilterInfo *filter_info, vector matching_equivalent_sets) { + D_ASSERT(matching_equivalent_sets.size() <= 2); + if (matching_equivalent_sets.size() > 1) { + // an equivalence relation is connecting to sets of equivalence relations + // so push all relations from the second set into the first. Later we will delete + // the second set. + for (ColumnBinding i : relations_to_tdoms.at(matching_equivalent_sets[1]).equivalent_relations) { + relations_to_tdoms.at(matching_equivalent_sets[0]).equivalent_relations.insert(i); + } + relations_to_tdoms.at(matching_equivalent_sets[1]).equivalent_relations.clear(); + relations_to_tdoms.at(matching_equivalent_sets[0]).filters.push_back(filter_info); + // add all values of one set to the other, delete the empty one + } else if (matching_equivalent_sets.size() == 1) { + auto &tdom_i = relations_to_tdoms.at(matching_equivalent_sets.at(0)); + tdom_i.equivalent_relations.insert(filter_info->left_binding); + tdom_i.equivalent_relations.insert(filter_info->right_binding); + tdom_i.filters.push_back(filter_info); + } else if (matching_equivalent_sets.empty()) { + column_binding_set_t tmp; + tmp.insert(filter_info->left_binding); + tmp.insert(filter_info->right_binding); + relations_to_tdoms.emplace_back(RelationsToTDom(tmp)); + relations_to_tdoms.back().filters.push_back(filter_info); + } +} + +void CardinalityEstimator::AddRelationToColumnMapping(ColumnBinding key, ColumnBinding value) { + relation_column_to_original_column[key] = value; +} + +void CardinalityEstimator::CopyRelationMap(column_binding_map_t &child_binding_map) { + for (auto &binding_map : relation_column_to_original_column) { + child_binding_map[binding_map.first] = binding_map.second; + } +} + +void CardinalityEstimator::AddColumnToRelationMap(idx_t table_index, idx_t column_index) { + relation_attributes[table_index].columns.insert(column_index); +} + +void CardinalityEstimator::InitEquivalentRelations(vector> *filter_infos) { + // For each filter, we fill keep track of the index of the equivalent relation set + // the left and right relation needs to be added to. + for (auto &filter : *filter_infos) { + if (SingleColumnFilter(filter.get())) { + // Filter on one relation, (i.e string or range filter on a column). + // Grab the first relation and add it to the equivalence_relations + AddRelationTdom(filter.get()); + continue; + } else if (EmptyFilter(filter.get())) { + continue; + } + D_ASSERT(filter->left_set->count >= 1); + D_ASSERT(filter->right_set->count >= 1); + + auto matching_equivalent_sets = DetermineMatchingEquivalentSets(filter.get()); + AddToEquivalenceSets(filter.get(), matching_equivalent_sets); + } +} + +void CardinalityEstimator::VerifySymmetry(JoinNode *result, JoinNode *entry) { + if (result->GetCardinality() != entry->GetCardinality()) { + // Currently it's possible that some entries are cartesian joins. + // When this is the case, you don't always have symmetry, but + // if the cost of the result is less, then just assure the cardinality + // is also less, then you have the same effect of symmetry. + D_ASSERT(ceil(result->GetCardinality()) <= ceil(entry->GetCardinality()) || + floor(result->GetCardinality()) <= floor(entry->GetCardinality())); + } +} + +void CardinalityEstimator::InitTotalDomains() { + auto remove_start = std::remove_if(relations_to_tdoms.begin(), relations_to_tdoms.end(), + [](RelationsToTDom &r_2_tdom) { return r_2_tdom.equivalent_relations.empty(); }); + relations_to_tdoms.erase(remove_start, relations_to_tdoms.end()); +} + +double CardinalityEstimator::ComputeCost(JoinNode *left, JoinNode *right, double expected_cardinality) { + return expected_cardinality + left->GetCost() + right->GetCost(); +} + +double CardinalityEstimator::EstimateCrossProduct(const JoinNode *left, const JoinNode *right) { + // need to explicity use double here, otherwise auto converts it to an int, then + // there is an autocast in the return. + return left->GetCardinality() >= (NumericLimits::Maximum() / right->GetCardinality()) + ? NumericLimits::Maximum() + : left->GetCardinality() * right->GetCardinality(); +} + +void CardinalityEstimator::AddRelationColumnMapping(LogicalGet *get, idx_t relation_id) { + for (idx_t it = 0; it < get->column_ids.size(); it++) { + auto key = ColumnBinding(relation_id, it); + auto value = ColumnBinding(get->table_index, get->column_ids[it]); + AddRelationToColumnMapping(key, value); + } +} + +void UpdateDenom(Subgraph2Denominator *relation_2_denom, RelationsToTDom *relation_to_tdom) { + relation_2_denom->denom *= + relation_to_tdom->has_tdom_hll ? relation_to_tdom->tdom_hll : relation_to_tdom->tdom_no_hll; +} + +void FindSubgraphMatchAndMerge(Subgraph2Denominator &merge_to, idx_t find_me, + vector::iterator subgraph, + vector::iterator end) { + for (; subgraph != end; subgraph++) { + if (subgraph->relations.count(find_me) >= 1) { + for (auto &relation : subgraph->relations) { + merge_to.relations.insert(relation); + } + subgraph->relations.clear(); + merge_to.denom *= subgraph->denom; + return; + } + } +} + +double CardinalityEstimator::EstimateCardinalityWithSet(JoinRelationSet *new_set) { + double numerator = 1; + unordered_set actual_set; + for (idx_t i = 0; i < new_set->count; i++) { + numerator *= relation_attributes[new_set->relations[i]].cardinality; + actual_set.insert(new_set->relations[i]); + } + vector subgraphs; + bool done = false; + bool found_match = false; + + // Finding the denominator is tricky. You need to go through the tdoms in decreasing order + // Then loop through all filters in the equivalence set of the tdom to see if both the + // left and right relations are in the new set, if so you can use that filter. + // You must also make sure that the filters all relations in the given set, so we use subgraphs + // that should eventually merge into one connected graph that joins all the relations + // TODO: Implement a method to cache subgraphs so you don't have to build them up every + // time the cardinality of a new set is requested + + // relations_to_tdoms has already been sorted. + for (auto &relation_2_tdom : relations_to_tdoms) { + // loop through each filter in the tdom. + if (done) { + break; + } + for (auto &filter : relation_2_tdom.filters) { + if (actual_set.count(filter->left_binding.table_index) == 0 || + actual_set.count(filter->right_binding.table_index) == 0) { + continue; + } + // the join filter is on relations in the new set. + found_match = false; + vector::iterator it; + for (it = subgraphs.begin(); it != subgraphs.end(); it++) { + auto left_in = it->relations.count(filter->left_binding.table_index); + auto right_in = it->relations.count(filter->right_binding.table_index); + if (left_in && right_in) { + // if both left and right bindings are in the subgraph, continue. + // This means another filter is connecting relations already in the + // subgraph it, but it has a tdom that is less, and we don't care. + found_match = true; + continue; + } + if (!left_in && !right_in) { + // if both left and right bindings are *not* in the subgraph, continue + // without finding a match. This will trigger the process to add a new + // subgraph + continue; + } + idx_t find_table; + if (left_in) { + find_table = filter->right_binding.table_index; + } else { + D_ASSERT(right_in); + find_table = filter->left_binding.table_index; + } + auto next_subgraph = it + 1; + // iterate through other subgraphs and merge. + FindSubgraphMatchAndMerge(*it, find_table, next_subgraph, subgraphs.end()); + // Now insert the right binding and update denominator with the + // tdom of the filter + it->relations.insert(find_table); + UpdateDenom(&(*it), &relation_2_tdom); + found_match = true; + break; + } + // means that the filter joins relations in the given set, but there is no + // connection to any subgraph in subgraphs. Add a new subgraph, and maybe later there will be + // a connection. + if (!found_match) { + subgraphs.emplace_back(Subgraph2Denominator()); + auto subgraph = &subgraphs.back(); + subgraph->relations.insert(filter->left_binding.table_index); + subgraph->relations.insert(filter->right_binding.table_index); + UpdateDenom(subgraph, &relation_2_tdom); + } + auto remove_start = std::remove_if(subgraphs.begin(), subgraphs.end(), + [](Subgraph2Denominator &s) { return s.relations.empty(); }); + subgraphs.erase(remove_start, subgraphs.end()); + + if (subgraphs.size() == 1 && subgraphs.at(0).relations.size() == new_set->count) { + // You have found enough filters to connect the relations. These are guaranteed + // to be the filters with the highest Tdoms. + done = true; + break; + } + } + } + double denom = 1; + // TODO: It's possible cross-products were added and are not present in the filters in the relation_2_tdom + // structures. When that's the case, multiply the denom structures that have no intersection + for (auto &match : subgraphs) { + // It's possible that in production, one of the D_ASSERTS above will fail and not all subgraphs + // were connected. When this happens, just use the largest denominator of all the subgraphs. + if (match.denom > denom) { + denom = match.denom; + } + } + // can happen if a table has cardinality 0, or a tdom is set to 0 + if (denom == 0) { + denom = 1; + } + return numerator / denom; +} + +static bool IsLogicalFilter(LogicalOperator *op) { + return op->type == LogicalOperatorType::LOGICAL_FILTER; +} + +static LogicalGet *GetLogicalGet(LogicalOperator *op) { + LogicalGet *get = nullptr; + switch (op->type) { + case LogicalOperatorType::LOGICAL_GET: + get = (LogicalGet *)op; + break; + case LogicalOperatorType::LOGICAL_FILTER: + get = GetLogicalGet(op->children.at(0).get()); + break; + case LogicalOperatorType::LOGICAL_PROJECTION: + get = GetLogicalGet(op->children.at(0).get()); + break; + case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: { + LogicalComparisonJoin *join = (LogicalComparisonJoin *)op; + if (join->join_type == JoinType::MARK || join->join_type == JoinType::LEFT) { + auto child = join->children.at(0).get(); + get = GetLogicalGet(child); + } + break; + } + default: + // return null pointer, maybe there is no logical get under this child + break; + } + return get; +} + +void CardinalityEstimator::MergeBindings(idx_t binding_index, idx_t relation_id, + vector> &child_binding_maps) { + for (auto &map_set : child_binding_maps) { + for (auto &mapping : map_set) { + ColumnBinding relation_bindings = mapping.first; + ColumnBinding actual_bindings = mapping.second; + + if (actual_bindings.table_index == binding_index) { + auto key = ColumnBinding(relation_id, relation_bindings.column_index); + AddRelationToColumnMapping(key, actual_bindings); + } + } + } +} + +bool SortTdoms(const RelationsToTDom &a, const RelationsToTDom &b) { + if (a.has_tdom_hll && b.has_tdom_hll) { + return a.tdom_hll > b.tdom_hll; + } + if (a.has_tdom_hll) { + return a.tdom_hll > b.tdom_no_hll; + } + if (b.has_tdom_hll) { + return a.tdom_no_hll > b.tdom_hll; + } + return a.tdom_no_hll > b.tdom_no_hll; +} + +void CardinalityEstimator::InitCardinalityEstimatorProps(vector *node_ops, + vector> *filter_infos) { + InitEquivalentRelations(filter_infos); + InitTotalDomains(); + for (idx_t i = 0; i < node_ops->size(); i++) { + auto join_node = (*node_ops)[i].node.get(); + auto op = (*node_ops)[i].op; + join_node->SetBaseTableCardinality(op->EstimateCardinality(context)); + if (op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { + auto &join = (LogicalComparisonJoin &)*op; + if (join.join_type == JoinType::LEFT) { + // TODO: inspect child operators to get a more accurate cost + // and cardinality estimation. If an base op is a Logical Comparison join + // it is probably a left join, so cost of the larger table is a fine + // estimate + // No need to update a mark join cost because I say so. + join_node->SetCost(join_node->GetBaseTableCardinality()); + } + } + // update cardinality with filters + EstimateBaseTableCardinality(join_node, op); + UpdateTotalDomains(join_node, op); + } + + // sort relations from greatest tdom to lowest tdom. + std::sort(relations_to_tdoms.begin(), relations_to_tdoms.end(), SortTdoms); +} + +void CardinalityEstimator::UpdateTotalDomains(JoinNode *node, LogicalOperator *op) { + auto relation_id = node->set->relations[0]; + relation_attributes[relation_id].cardinality = node->GetCardinality(); + TableCatalogEntry *catalog_table = nullptr; + auto get = GetLogicalGet(op); + if (get) { + catalog_table = GetCatalogTableEntry(get); + } + + //! Initialize the tdoms for all columns the relation uses in join conditions. + unordered_set::iterator ite; + idx_t count = node->GetBaseTableCardinality(); + + bool direct_filter = false; + for (auto &column : relation_attributes[relation_id].columns) { + //! for every column in the relation, get the count via either HLL, or assume it to be + //! the cardinality + ColumnBinding key = ColumnBinding(relation_id, column); + + if (catalog_table) { + relation_attributes[relation_id].original_name = catalog_table->name; + // Get HLL stats here + auto actual_binding = relation_column_to_original_column[key]; + + auto base_stats = catalog_table->GetStatistics(context, actual_binding.column_index); + if (base_stats) { + count = base_stats->GetDistinctCount(); + } + + // means you have a direct filter on a column. The count/total domain for the column + // should be decreased to match the predicted total domain matching the filter. + // We decrease the total domain for all columns in the equivalence set because filter pushdown + // will mean all columns are affected. + if (direct_filter) { + count = node->GetCardinality(); + } + + // HLL has estimation error, count can't be greater than cardinality of the table before filters + if (count > node->GetBaseTableCardinality()) { + count = node->GetBaseTableCardinality(); + } + } else { + // No HLL. So if we know there is a direct filter, reduce count to cardinality with filter + // otherwise assume the total domain is still the cardinality + if (direct_filter) { + count = node->GetCardinality(); + } else { + count = node->GetBaseTableCardinality(); + } + } + + for (auto &relation_to_tdom : relations_to_tdoms) { + column_binding_set_t i_set = relation_to_tdom.equivalent_relations; + if (i_set.count(key) != 1) { + continue; + } + if (catalog_table) { + if (relation_to_tdom.tdom_hll < count) { + relation_to_tdom.tdom_hll = count; + relation_to_tdom.has_tdom_hll = true; + } + if (relation_to_tdom.tdom_no_hll > count) { + relation_to_tdom.tdom_no_hll = count; + } + } else { + // Here we don't have catalog statistics, and the following is how we determine + // the tdom + // 1. If there is any hll data in the equivalence set, use that + // 2. Otherwise, use the table with the smallest cardinality + if (relation_to_tdom.tdom_no_hll > count && !relation_to_tdom.has_tdom_hll) { + relation_to_tdom.tdom_no_hll = count; + } + } + break; + } + } +} + +TableFilterSet *CardinalityEstimator::GetTableFilters(LogicalOperator *op) { + // First check table filters + auto get = GetLogicalGet(op); + return get ? &get->table_filters : nullptr; +} + +idx_t CardinalityEstimator::InspectConjunctionAND(idx_t cardinality, idx_t column_index, ConjunctionAndFilter *filter, + unique_ptr base_stats) { + auto has_equality_filter = false; + auto cardinality_after_filters = cardinality; + for (auto &child_filter : filter->child_filters) { + if (child_filter->filter_type != TableFilterType::CONSTANT_COMPARISON) { + continue; + } + auto comparison_filter = (ConstantFilter &)*child_filter; + if (comparison_filter.comparison_type != ExpressionType::COMPARE_EQUAL) { + continue; + } + auto column_count = 0; + if (base_stats) { + column_count = base_stats->GetDistinctCount(); + } + auto filtered_card = cardinality; + // column_count = 0 when there is no column count (i.e parquet scans) + if (column_count > 0) { + // we want the ceil of cardinality/column_count. We also want to avoid compiler errors + filtered_card = (cardinality + column_count - 1) / column_count; + cardinality_after_filters = filtered_card; + } + if (has_equality_filter) { + cardinality_after_filters = MinValue(filtered_card, cardinality_after_filters); + } + has_equality_filter = true; + } + return cardinality_after_filters; +} + +idx_t CardinalityEstimator::InspectConjunctionOR(idx_t cardinality, idx_t column_index, ConjunctionOrFilter *filter, + unique_ptr base_stats) { + auto has_equality_filter = false; + auto cardinality_after_filters = cardinality; + for (auto &child_filter : filter->child_filters) { + if (child_filter->filter_type != TableFilterType::CONSTANT_COMPARISON) { + continue; + } + auto comparison_filter = (ConstantFilter &)*child_filter; + if (comparison_filter.comparison_type == ExpressionType::COMPARE_EQUAL) { + auto column_count = cardinality_after_filters; + if (base_stats) { + column_count = base_stats->GetDistinctCount(); + } + auto increment = MaxValue(((cardinality + column_count - 1) / column_count), 1); + if (has_equality_filter) { + cardinality_after_filters += increment; + } else { + cardinality_after_filters = increment; + } + has_equality_filter = true; + } + } + D_ASSERT(cardinality_after_filters > 0); + return cardinality_after_filters; +} + +idx_t CardinalityEstimator::InspectTableFilters(idx_t cardinality, LogicalOperator *op, TableFilterSet *table_filters) { + idx_t cardinality_after_filters = cardinality; + auto get = GetLogicalGet(op); + unique_ptr column_statistics; + for (auto &it : table_filters->filters) { + column_statistics = nullptr; + if (get->bind_data && get->function.name.compare("seq_scan") == 0) { + auto &table_scan_bind_data = (TableScanBindData &)*get->bind_data; + column_statistics = get->function.statistics(context, &table_scan_bind_data, it.first); + } + if (it.second->filter_type == TableFilterType::CONJUNCTION_AND) { + auto &filter = (ConjunctionAndFilter &)*it.second; + idx_t cardinality_with_and_filter = + InspectConjunctionAND(cardinality, it.first, &filter, std::move(column_statistics)); + cardinality_after_filters = MinValue(cardinality_after_filters, cardinality_with_and_filter); + } else if (it.second->filter_type == TableFilterType::CONJUNCTION_OR) { + auto &filter = (ConjunctionOrFilter &)*it.second; + idx_t cardinality_with_or_filter = + InspectConjunctionOR(cardinality, it.first, &filter, std::move(column_statistics)); + cardinality_after_filters = MinValue(cardinality_after_filters, cardinality_with_or_filter); + } + } + // if the above code didn't find an equality filter (i.e country_code = "[us]") + // and there are other table filters, use default selectivity. + bool has_equality_filter = (cardinality_after_filters != cardinality); + if (!has_equality_filter && !table_filters->filters.empty()) { + cardinality_after_filters = MaxValue(cardinality * DEFAULT_SELECTIVITY, 1); + } + return cardinality_after_filters; +} + +void CardinalityEstimator::EstimateBaseTableCardinality(JoinNode *node, LogicalOperator *op) { + auto has_logical_filter = IsLogicalFilter(op); + auto table_filters = GetTableFilters(op); + + auto card_after_filters = node->GetBaseTableCardinality(); + if (table_filters) { + double inspect_result = (double)InspectTableFilters(card_after_filters, op, table_filters); + card_after_filters = MinValue(inspect_result, (double)card_after_filters); + } + if (has_logical_filter) { + card_after_filters *= DEFAULT_SELECTIVITY; + } + node->SetEstimatedCardinality(card_after_filters); +} + +} // namespace duckdb + + + +namespace duckdb { + +template <> +double EstimatedProperties::GetCardinality() const { + return cardinality; +} + +template <> +idx_t EstimatedProperties::GetCardinality() const { + auto max_idx_t = NumericLimits::Maximum() - 10000; + return MinValue(cardinality, max_idx_t); +} + +double EstimatedProperties::GetCost() const { + return cost; +} + +void EstimatedProperties::SetCardinality(double new_card) { + cardinality = new_card; +} + +void EstimatedProperties::SetCost(double new_cost) { + cost = new_cost; +} + +} // namespace duckdb + + + + + + + + + + + + + + + + @@ -166523,8 +175964,6 @@ unique_ptr InClauseRewriter::VisitReplace(BoundOperatorExpression &e - - namespace duckdb { JoinNode::JoinNode(JoinRelationSet *set, const double base_cardinality) @@ -166594,282 +176033,6 @@ string JoinNode::ToString() { -#include - -namespace duckdb { - -using JoinRelationTreeNode = JoinRelationSetManager::JoinRelationTreeNode; - -// LCOV_EXCL_START -string JoinRelationSet::ToString() const { - string result = "["; - result += StringUtil::Join(relations, count, ", ", [](const idx_t &relation) { return to_string(relation); }); - result += "]"; - return result; -} -// LCOV_EXCL_STOP - -//! Returns true if sub is a subset of super -bool JoinRelationSet::IsSubset(JoinRelationSet *super, JoinRelationSet *sub) { - D_ASSERT(sub->count > 0); - if (sub->count > super->count) { - return false; - } - idx_t j = 0; - for (idx_t i = 0; i < super->count; i++) { - if (sub->relations[j] == super->relations[i]) { - j++; - if (j == sub->count) { - return true; - } - } - } - return false; -} - -JoinRelationSet *JoinRelationSetManager::GetJoinRelation(unique_ptr relations, idx_t count) { - // now look it up in the tree - JoinRelationTreeNode *info = &root; - for (idx_t i = 0; i < count; i++) { - auto entry = info->children.find(relations[i]); - if (entry == info->children.end()) { - // node not found, create it - auto insert_it = info->children.insert(make_pair(relations[i], make_unique())); - entry = insert_it.first; - } - // move to the next node - info = entry->second.get(); - } - // now check if the JoinRelationSet has already been created - if (!info->relation) { - // if it hasn't we need to create it - info->relation = make_unique(move(relations), count); - } - return info->relation.get(); -} - -//! Create or get a JoinRelationSet from a single node with the given index -JoinRelationSet *JoinRelationSetManager::GetJoinRelation(idx_t index) { - // create a sorted vector of the relations - auto relations = unique_ptr(new idx_t[1]); - relations[0] = index; - idx_t count = 1; - return GetJoinRelation(move(relations), count); -} - -JoinRelationSet *JoinRelationSetManager::GetJoinRelation(unordered_set &bindings) { - // create a sorted vector of the relations - unique_ptr relations = bindings.empty() ? nullptr : unique_ptr(new idx_t[bindings.size()]); - idx_t count = 0; - for (auto &entry : bindings) { - relations[count++] = entry; - } - std::sort(relations.get(), relations.get() + count); - return GetJoinRelation(move(relations), count); -} - -JoinRelationSet *JoinRelationSetManager::Union(JoinRelationSet *left, JoinRelationSet *right) { - auto relations = unique_ptr(new idx_t[left->count + right->count]); - idx_t count = 0; - // move through the left and right relations, eliminating duplicates - idx_t i = 0, j = 0; - while (true) { - if (i == left->count) { - // exhausted left relation, add remaining of right relation - for (; j < right->count; j++) { - relations[count++] = right->relations[j]; - } - break; - } else if (j == right->count) { - // exhausted right relation, add remaining of left - for (; i < left->count; i++) { - relations[count++] = left->relations[i]; - } - break; - } else if (left->relations[i] == right->relations[j]) { - // equivalent, add only one of the two pairs - relations[count++] = left->relations[i]; - i++; - j++; - } else if (left->relations[i] < right->relations[j]) { - // left is smaller, progress left and add it to the set - relations[count++] = left->relations[i]; - i++; - } else { - // right is smaller, progress right and add it to the set - relations[count++] = right->relations[j]; - j++; - } - } - return GetJoinRelation(move(relations), count); -} - -// JoinRelationSet *JoinRelationSetManager::Difference(JoinRelationSet *left, JoinRelationSet *right) { -// auto relations = unique_ptr(new idx_t[left->count]); -// idx_t count = 0; -// // move through the left and right relations -// idx_t i = 0, j = 0; -// while (true) { -// if (i == left->count) { -// // exhausted left relation, we are done -// break; -// } else if (j == right->count) { -// // exhausted right relation, add remaining of left -// for (; i < left->count; i++) { -// relations[count++] = left->relations[i]; -// } -// break; -// } else if (left->relations[i] == right->relations[j]) { -// // equivalent, add nothing -// i++; -// j++; -// } else if (left->relations[i] < right->relations[j]) { -// // left is smaller, progress left and add it to the set -// relations[count++] = left->relations[i]; -// i++; -// } else { -// // right is smaller, progress right -// j++; -// } -// } -// return GetJoinRelation(move(relations), count); -// } - -} // namespace duckdb - - - - - - - -namespace duckdb { - -using QueryEdge = QueryGraph::QueryEdge; - -// LCOV_EXCL_START -static string QueryEdgeToString(const QueryEdge *info, vector prefix) { - string result = ""; - string source = "["; - for (idx_t i = 0; i < prefix.size(); i++) { - source += to_string(prefix[i]) + (i < prefix.size() - 1 ? ", " : ""); - } - source += "]"; - for (auto &entry : info->neighbors) { - result += StringUtil::Format("%s -> %s\n", source.c_str(), entry->neighbor->ToString().c_str()); - } - for (auto &entry : info->children) { - vector new_prefix = prefix; - new_prefix.push_back(entry.first); - result += QueryEdgeToString(entry.second.get(), new_prefix); - } - return result; -} - -string QueryGraph::ToString() const { - return QueryEdgeToString(&root, {}); -} - -void QueryGraph::Print() { - Printer::Print(ToString()); -} -// LCOV_EXCL_STOP - -QueryEdge *QueryGraph::GetQueryEdge(JoinRelationSet *left) { - D_ASSERT(left && left->count > 0); - // find the EdgeInfo corresponding to the left set - QueryEdge *info = &root; - for (idx_t i = 0; i < left->count; i++) { - auto entry = info->children.find(left->relations[i]); - if (entry == info->children.end()) { - // node not found, create it - auto insert_it = info->children.insert(make_pair(left->relations[i], make_unique())); - entry = insert_it.first; - } - // move to the next node - info = entry->second.get(); - } - return info; -} - -void QueryGraph::CreateEdge(JoinRelationSet *left, JoinRelationSet *right, FilterInfo *filter_info) { - D_ASSERT(left && right && left->count > 0 && right->count > 0); - // find the EdgeInfo corresponding to the left set - auto info = GetQueryEdge(left); - // now insert the edge to the right relation, if it does not exist - for (idx_t i = 0; i < info->neighbors.size(); i++) { - if (info->neighbors[i]->neighbor == right) { - if (filter_info) { - // neighbor already exists just add the filter, if we have any - info->neighbors[i]->filters.push_back(filter_info); - } - return; - } - } - // neighbor does not exist, create it - auto n = make_unique(); - if (filter_info) { - n->filters.push_back(filter_info); - } - n->neighbor = right; - info->neighbors.push_back(move(n)); -} - -void QueryGraph::EnumerateNeighbors(JoinRelationSet *node, const std::function &callback) { - for (idx_t j = 0; j < node->count; j++) { - QueryEdge *info = &root; - for (idx_t i = j; i < node->count; i++) { - auto entry = info->children.find(node->relations[i]); - if (entry == info->children.end()) { - // node not found - break; - } - // check if any subset of the other set is in this sets neighbors - info = entry->second.get(); - for (auto &neighbor : info->neighbors) { - if (callback(neighbor.get())) { - return; - } - } - } - } -} - -//! Returns true if a JoinRelationSet is banned by the list of exclusion_set, false otherwise -static bool JoinRelationSetIsExcluded(JoinRelationSet *node, unordered_set &exclusion_set) { - return exclusion_set.find(node->relations[0]) != exclusion_set.end(); -} - -vector QueryGraph::GetNeighbors(JoinRelationSet *node, unordered_set &exclusion_set) { - unordered_set result; - EnumerateNeighbors(node, [&](NeighborInfo *info) -> bool { - if (!JoinRelationSetIsExcluded(info->neighbor, exclusion_set)) { - // add the smallest node of the neighbor to the set - result.insert(info->neighbor->relations[0]); - } - return false; - }); - vector neighbors; - neighbors.insert(neighbors.end(), result.begin(), result.end()); - return neighbors; -} - -vector QueryGraph::GetConnections(JoinRelationSet *node, JoinRelationSet *other) { - vector connections; - EnumerateNeighbors(node, [&](NeighborInfo *info) -> bool { - if (JoinRelationSet::IsSubset(other, info->neighbor)) { - connections.push_back(info); - } - return false; - }); - return connections; -} - -} // namespace duckdb - - - - @@ -166950,13 +176113,13 @@ static unique_ptr PushFilter(unique_ptr node, if (node->type != LogicalOperatorType::LOGICAL_FILTER) { // we don't, we need to create one auto filter = make_unique(); - filter->children.push_back(move(node)); - node = move(filter); + filter->children.push_back(std::move(node)); + node = std::move(filter); } // push the filter into the LogicalFilter D_ASSERT(node->type == LogicalOperatorType::LOGICAL_FILTER); auto filter = (LogicalFilter *)node.get(); - filter->expressions.push_back(move(expr)); + filter->expressions.push_back(std::move(expr)); return node; } @@ -166973,7 +176136,7 @@ bool JoinOrderOptimizer::ExtractJoinRelations(LogicalOperator &input_op, vector< op->type == LogicalOperatorType::LOGICAL_WINDOW) { // don't push filters through projection or aggregate and group by JoinOrderOptimizer optimizer(context); - op->children[0] = optimizer.Optimize(move(op->children[0])); + op->children[0] = optimizer.Optimize(std::move(op->children[0])); return false; } op = op->children[0].get(); @@ -167026,7 +176189,7 @@ bool JoinOrderOptimizer::ExtractJoinRelations(LogicalOperator &input_op, vector< for (auto &child : op->children) { child_binding_maps.emplace_back(column_binding_map_t()); JoinOrderOptimizer optimizer(context); - child = optimizer.Optimize(move(child)); + child = optimizer.Optimize(std::move(child)); // save the relation bindings from the optimized child. These later all get added to the // parent cardinality_estimator relation column binding map. optimizer.cardinality_estimator.CopyRelationMap(child_binding_maps.at(child_bindings_it)); @@ -167047,16 +176210,19 @@ bool JoinOrderOptimizer::ExtractJoinRelations(LogicalOperator &input_op, vector< cardinality_estimator.MergeBindings(it, relation_id, child_binding_maps); relation_mapping[it] = relation_id; } - relations.push_back(move(relation)); + relations.push_back(std::move(relation)); return true; } - if (op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN || - op->type == LogicalOperatorType::LOGICAL_CROSS_PRODUCT) { + + switch (op->type) { + case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: + case LogicalOperatorType::LOGICAL_CROSS_PRODUCT: { // inner join or cross product bool can_reorder_left = ExtractJoinRelations(*op->children[0], filter_operators, op); bool can_reorder_right = ExtractJoinRelations(*op->children[1], filter_operators, op); return can_reorder_left && can_reorder_right; - } else if (op->type == LogicalOperatorType::LOGICAL_GET) { + } + case LogicalOperatorType::LOGICAL_GET: { // base table scan, add to set of relations auto get = (LogicalGet *)op; auto relation = make_unique(&input_op, parent); @@ -167065,37 +176231,40 @@ bool JoinOrderOptimizer::ExtractJoinRelations(LogicalOperator &input_op, vector< auto table_index = get->table_index; relation_mapping[table_index] = relation_id; cardinality_estimator.AddRelationColumnMapping(get, relation_id); - relations.push_back(move(relation)); + relations.push_back(std::move(relation)); return true; - } else if (op->type == LogicalOperatorType::LOGICAL_EXPRESSION_GET) { + } + case LogicalOperatorType::LOGICAL_EXPRESSION_GET: { // base table scan, add to set of relations auto get = (LogicalExpressionGet *)op; auto relation = make_unique(&input_op, parent); - idx_t relation_id = relations.size(); //! make sure the optimizer has knowledge of the exact column bindings as well. - auto table_index = get->table_index; - relation_mapping[table_index] = relation_id; - relations.push_back(move(relation)); + relation_mapping[get->table_index] = relations.size(); + relations.push_back(std::move(relation)); return true; - } else if (op->type == LogicalOperatorType::LOGICAL_DUMMY_SCAN) { + } + case LogicalOperatorType::LOGICAL_DUMMY_SCAN: { // table function call, add to set of relations auto dummy_scan = (LogicalDummyScan *)op; auto relation = make_unique(&input_op, parent); relation_mapping[dummy_scan->table_index] = relations.size(); - relations.push_back(move(relation)); + relations.push_back(std::move(relation)); return true; - } else if (op->type == LogicalOperatorType::LOGICAL_PROJECTION) { + } + case LogicalOperatorType::LOGICAL_PROJECTION: { auto proj = (LogicalProjection *)op; // we run the join order optimizer witin the subquery as well JoinOrderOptimizer optimizer(context); - op->children[0] = optimizer.Optimize(move(op->children[0])); + op->children[0] = optimizer.Optimize(std::move(op->children[0])); // projection, add to the set of relations auto relation = make_unique(&input_op, parent); relation_mapping[proj->table_index] = relations.size(); - relations.push_back(move(relation)); + relations.push_back(std::move(relation)); return true; } - return false; + default: + return false; + } } //! Update the exclusion set with all entries in the subgraph @@ -167142,6 +176311,10 @@ unique_ptr JoinOrderOptimizer::CreateJoinTree(JoinRelationSet *set, return result; } +bool JoinOrderOptimizer::NodeInFullPlan(JoinNode *node) { + return join_nodes_in_full_plan.find(node->set->ToString()) != join_nodes_in_full_plan.end(); +} + void JoinOrderOptimizer::UpdateJoinNodesInFullPlan(JoinNode *node) { if (!node) { return; @@ -167197,7 +176370,7 @@ JoinNode *JoinOrderOptimizer::EmitPair(JoinRelationSet *left, JoinRelationSet *r } D_ASSERT(new_plan); - plans[new_set] = move(new_plan); + plans[new_set] = std::move(new_plan); return result; } return entry->second.get(); @@ -167372,7 +176545,7 @@ static vector> AddSuperSets(vector> cu } // works by first creating all sets with cardinality 1 -// then iterates over each previously create group of subsets and will only add a neighbor if the neighbor +// then iterates over each previously created group of subsets and will only add a neighbor if the neighbor // is greater than all relations in the set. static vector> GetAllNeighborSets(JoinRelationSet *new_set, unordered_set &exclusion_set, vector neighbors) { @@ -167408,6 +176581,11 @@ static vector> GetAllNeighborSets(JoinRelationSet *new_set, } void JoinOrderOptimizer::UpdateDPTree(JoinNode *new_plan) { + if (!NodeInFullPlan(new_plan)) { + // if the new node is not in the full plan, feel free to return + // because you won't be updating the full plan. + return; + } auto new_set = new_plan->set; // now update every plan that uses this plan unordered_set exclusion_set; @@ -167469,6 +176647,7 @@ void JoinOrderOptimizer::SolveJoinOrderApproximately() { // update the DP tree in case a plan created by the DP algorithm uses the node // that was potentially just updated by EmitPair. You will get a use-after-free // error if future plans rely on the old node that was just replaced. + // if node in FullPath, then updateDP tree. UpdateDPTree(node); if (!best_connection || node->GetCost() < best_connection->GetCost()) { @@ -167561,7 +176740,7 @@ static unique_ptr ExtractJoinRelation(SingleJoinRelation &rel) for (idx_t i = 0; i < children.size(); i++) { if (children[i].get() == rel.op) { // found it! take ownership of it from the parent - auto result = move(children[i]); + auto result = std::move(children[i]); children.erase(children.begin() + i); return result; } @@ -167581,17 +176760,17 @@ JoinOrderOptimizer::GenerateJoins(vector> &extracted if (node->info->filters.empty()) { // no filters, create a cross product - result_operator = LogicalCrossProduct::Create(move(left.second), move(right.second)); + result_operator = LogicalCrossProduct::Create(std::move(left.second), std::move(right.second)); } else { // we have filters, create a join node auto join = make_unique(JoinType::INNER); - join->children.push_back(move(left.second)); - join->children.push_back(move(right.second)); + join->children.push_back(std::move(left.second)); + join->children.push_back(std::move(right.second)); // set the join conditions from the join node for (auto &f : node->info->filters) { // extract the filter from the operator it originally belonged to D_ASSERT(filters[f->filter_index]); - auto condition = move(filters[f->filter_index]); + auto condition = std::move(filters[f->filter_index]); // now create the actual join condition D_ASSERT((JoinRelationSet::IsSubset(left.first, f->left_set) && JoinRelationSet::IsSubset(right.first, f->right_set)) || @@ -167602,18 +176781,18 @@ JoinOrderOptimizer::GenerateJoins(vector> &extracted auto &comparison = (BoundComparisonExpression &)*condition; // we need to figure out which side is which by looking at the relations available to us bool invert = !JoinRelationSet::IsSubset(left.first, f->left_set); - cond.left = !invert ? move(comparison.left) : move(comparison.right); - cond.right = !invert ? move(comparison.right) : move(comparison.left); + cond.left = !invert ? std::move(comparison.left) : std::move(comparison.right); + cond.right = !invert ? std::move(comparison.right) : std::move(comparison.left); cond.comparison = condition->type; if (invert) { // reverse comparison expression if we reverse the order of the children cond.comparison = FlipComparisionExpression(cond.comparison); } - join->conditions.push_back(move(cond)); + join->conditions.push_back(std::move(cond)); } D_ASSERT(!join->conditions.empty()); - result_operator = move(join); + result_operator = std::move(join); } left_node = left.first; right_node = right.first; @@ -167624,11 +176803,21 @@ JoinOrderOptimizer::GenerateJoins(vector> &extracted D_ASSERT(node->set->count == 1); D_ASSERT(extracted_relations[node->set->relations[0]]); result_relation = node->set; - result_operator = move(extracted_relations[node->set->relations[0]]); + result_operator = std::move(extracted_relations[node->set->relations[0]]); } - result_operator->estimated_cardinality = node->GetCardinality(); - result_operator->has_estimated_cardinality = true; result_operator->estimated_props = node->estimated_props->Copy(); + result_operator->estimated_cardinality = result_operator->estimated_props->GetCardinality(); + result_operator->has_estimated_cardinality = true; + if (result_operator->type == LogicalOperatorType::LOGICAL_FILTER && + result_operator->children[0]->type == LogicalOperatorType::LOGICAL_GET) { + // FILTER on top of GET, add estimated properties to both + auto &filter_props = *result_operator->estimated_props; + auto &child_operator = *result_operator->children[0]; + child_operator.estimated_props = make_unique( + filter_props.GetCardinality() / CardinalityEstimator::DEFAULT_SELECTIVITY, filter_props.GetCost()); + child_operator.estimated_cardinality = child_operator.estimated_props->GetCardinality(); + child_operator.has_estimated_cardinality = true; + } // check if we should do a pushdown on this node // basically, any remaining filter that is a subset of the current relation will no longer be used in joins // hence we should push it here @@ -167639,13 +176828,13 @@ JoinOrderOptimizer::GenerateJoins(vector> &extracted // now check if the filter is a subset of the current relation // note that infos with an empty relation set are a special case and we do not push them down if (info->set->count > 0 && JoinRelationSet::IsSubset(result_relation, info->set)) { - auto filter = move(filters[info->filter_index]); + auto filter = std::move(filters[info->filter_index]); // if it is, we can push the filter // we can push it either into a join or as a filter // check if we are in a join or in a base table if (!left_node || !info->left_set) { // base table or non-comparison expression, push it as a filter - result_operator = PushFilter(move(result_operator), move(filter)); + result_operator = PushFilter(std::move(result_operator), std::move(filter)); continue; } // the node below us is a join or cross product and the expression is a comparison @@ -167662,7 +176851,7 @@ JoinOrderOptimizer::GenerateJoins(vector> &extracted } if (!found_subset) { // could not be split up into left/right - result_operator = PushFilter(move(result_operator), move(filter)); + result_operator = PushFilter(std::move(result_operator), std::move(filter)); continue; } // create the join condition @@ -167670,8 +176859,8 @@ JoinOrderOptimizer::GenerateJoins(vector> &extracted D_ASSERT(filter->GetExpressionClass() == ExpressionClass::BOUND_COMPARISON); auto &comparison = (BoundComparisonExpression &)*filter; // we need to figure out which side is which by looking at the relations available to us - cond.left = !invert ? move(comparison.left) : move(comparison.right); - cond.right = !invert ? move(comparison.right) : move(comparison.left); + cond.left = !invert ? std::move(comparison.left) : std::move(comparison.right); + cond.right = !invert ? std::move(comparison.right) : std::move(comparison.left); cond.comparison = comparison.type; if (invert) { // reverse comparison expression if we reverse the order of the children @@ -167685,24 +176874,24 @@ JoinOrderOptimizer::GenerateJoins(vector> &extracted if (node->type == LogicalOperatorType::LOGICAL_CROSS_PRODUCT) { // turn into comparison join auto comp_join = make_unique(JoinType::INNER); - comp_join->children.push_back(move(node->children[0])); - comp_join->children.push_back(move(node->children[1])); - comp_join->conditions.push_back(move(cond)); + comp_join->children.push_back(std::move(node->children[0])); + comp_join->children.push_back(std::move(node->children[1])); + comp_join->conditions.push_back(std::move(cond)); if (node == result_operator.get()) { - result_operator = move(comp_join); + result_operator = std::move(comp_join); } else { D_ASSERT(result_operator->type == LogicalOperatorType::LOGICAL_FILTER); - result_operator->children[0] = move(comp_join); + result_operator->children[0] = std::move(comp_join); } } else { D_ASSERT(node->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN); auto &comp_join = (LogicalComparisonJoin &)*node; - comp_join.conditions.push_back(move(cond)); + comp_join.conditions.push_back(std::move(cond)); } } } } - return make_pair(result_relation, move(result_operator)); + return make_pair(result_relation, std::move(result_operator)); } unique_ptr JoinOrderOptimizer::RewritePlan(unique_ptr plan, JoinNode *node) { @@ -167721,14 +176910,14 @@ unique_ptr JoinOrderOptimizer::RewritePlan(unique_ptrchildren.size() == 1); // have to move up through the relations @@ -167741,7 +176930,7 @@ unique_ptr JoinOrderOptimizer::RewritePlan(unique_ptrchildren[0].get(); } // have to replace at this node - parent->children[0] = move(join_tree.second); + parent->children[0] = std::move(join_tree.second); return plan; } @@ -167769,28 +176958,28 @@ unique_ptr JoinOrderOptimizer::Optimize(unique_ptrtype == LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { - auto &join = (LogicalComparisonJoin &)*op; + for (auto &f_op : filter_operators) { + if (f_op->type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { + auto &join = (LogicalComparisonJoin &)*f_op; D_ASSERT(join.join_type == JoinType::INNER); D_ASSERT(join.expressions.empty()); for (auto &cond : join.conditions) { - auto comparison = - make_unique(cond.comparison, move(cond.left), move(cond.right)); + auto comparison = make_unique(cond.comparison, std::move(cond.left), + std::move(cond.right)); if (filter_set.find(comparison.get()) == filter_set.end()) { filter_set.insert(comparison.get()); - filters.push_back(move(comparison)); + filters.push_back(std::move(comparison)); } } join.conditions.clear(); } else { - for (auto &expression : op->expressions) { + for (auto &expression : f_op->expressions) { if (filter_set.find(expression.get()) == filter_set.end()) { filter_set.insert(expression.get()); - filters.push_back(move(expression)); + filters.push_back(std::move(expression)); } } - op->expressions.clear(); + f_op->expressions.clear(); } } // create potential edges from the comparisons @@ -167798,7 +176987,7 @@ unique_ptr JoinOrderOptimizer::Optimize(unique_ptr(); auto filter_info = info.get(); - filter_infos.push_back(move(info)); + filter_infos.push_back(std::move(info)); // first extract the relation set for the entire filter unordered_set bindings; ExtractBindings(*filter, bindings); @@ -167848,7 +177037,7 @@ unique_ptr JoinOrderOptimizer::Optimize(unique_ptrset] = move(node_op.node); + plans[node_op.node->set] = std::move(node_op.node); } // now we perform the actual dynamic programming to compute the final result SolveJoinOrder(); @@ -167876,7 +177065,7 @@ unique_ptr JoinOrderOptimizer::Optimize(unique_ptrsecond.get()); + return RewritePlan(std::move(plan), final_plan->second.get()); } } // namespace duckdb @@ -167884,107 +177073,379 @@ unique_ptr JoinOrderOptimizer::Optimize(unique_ptr &bindings) { - if (type && !type->Match(expr->return_type)) { - return false; - } - if (expr_type && !expr_type->Match(expr->type)) { - return false; - } - if (expr_class != ExpressionClass::INVALID && expr_class != expr->GetExpressionClass()) { - return false; - } - bindings.push_back(expr); - return true; -} - -bool ExpressionEqualityMatcher::Match(Expression *expr, vector &bindings) { - if (!Expression::Equals(expression, expr)) { - return false; - } - bindings.push_back(expr); - return true; -} +#include -bool CaseExpressionMatcher::Match(Expression *expr_p, vector &bindings) { - if (!ExpressionMatcher::Match(expr_p, bindings)) { - return false; - } - return true; -} +namespace duckdb { -bool ComparisonExpressionMatcher::Match(Expression *expr_p, vector &bindings) { - if (!ExpressionMatcher::Match(expr_p, bindings)) { - return false; - } - auto expr = (BoundComparisonExpression *)expr_p; - vector expressions = {expr->left.get(), expr->right.get()}; - return SetMatcher::Match(matchers, expressions, bindings, policy); -} +using JoinRelationTreeNode = JoinRelationSetManager::JoinRelationTreeNode; -bool CastExpressionMatcher::Match(Expression *expr_p, vector &bindings) { - if (!ExpressionMatcher::Match(expr_p, bindings)) { - return false; - } - if (!matcher) { - return true; - } - auto expr = (BoundCastExpression *)expr_p; - return matcher->Match(expr->child.get(), bindings); +// LCOV_EXCL_START +string JoinRelationSet::ToString() const { + string result = "["; + result += StringUtil::Join(relations, count, ", ", [](const idx_t &relation) { return to_string(relation); }); + result += "]"; + return result; } +// LCOV_EXCL_STOP -bool InClauseExpressionMatcher::Match(Expression *expr_p, vector &bindings) { - if (!ExpressionMatcher::Match(expr_p, bindings)) { +//! Returns true if sub is a subset of super +bool JoinRelationSet::IsSubset(JoinRelationSet *super, JoinRelationSet *sub) { + D_ASSERT(sub->count > 0); + if (sub->count > super->count) { return false; } - auto expr = (BoundOperatorExpression *)expr_p; - if (expr->type != ExpressionType::COMPARE_IN || expr->type == ExpressionType::COMPARE_NOT_IN) { - return false; + idx_t j = 0; + for (idx_t i = 0; i < super->count; i++) { + if (sub->relations[j] == super->relations[i]) { + j++; + if (j == sub->count) { + return true; + } + } } - return SetMatcher::Match(matchers, expr->children, bindings, policy); + return false; } -bool ConjunctionExpressionMatcher::Match(Expression *expr_p, vector &bindings) { - if (!ExpressionMatcher::Match(expr_p, bindings)) { - return false; +JoinRelationSet *JoinRelationSetManager::GetJoinRelation(unique_ptr relations, idx_t count) { + // now look it up in the tree + JoinRelationTreeNode *info = &root; + for (idx_t i = 0; i < count; i++) { + auto entry = info->children.find(relations[i]); + if (entry == info->children.end()) { + // node not found, create it + auto insert_it = info->children.insert(make_pair(relations[i], make_unique())); + entry = insert_it.first; + } + // move to the next node + info = entry->second.get(); } - auto expr = (BoundConjunctionExpression *)expr_p; - if (!SetMatcher::Match(matchers, expr->children, bindings, policy)) { - return false; + // now check if the JoinRelationSet has already been created + if (!info->relation) { + // if it hasn't we need to create it + info->relation = make_unique(std::move(relations), count); } - return true; + return info->relation.get(); } -bool FunctionExpressionMatcher::Match(Expression *expr_p, vector &bindings) { - if (!ExpressionMatcher::Match(expr_p, bindings)) { - return false; - } - auto expr = (BoundFunctionExpression *)expr_p; - if (!FunctionMatcher::Match(function, expr->function.name)) { - return false; - } - if (!SetMatcher::Match(matchers, expr->children, bindings, policy)) { - return false; - } - return true; +//! Create or get a JoinRelationSet from a single node with the given index +JoinRelationSet *JoinRelationSetManager::GetJoinRelation(idx_t index) { + // create a sorted vector of the relations + auto relations = unique_ptr(new idx_t[1]); + relations[0] = index; + idx_t count = 1; + return GetJoinRelation(std::move(relations), count); } -bool FoldableConstantMatcher::Match(Expression *expr, vector &bindings) { - // we match on ANY expression that is a scalar expression - if (!expr->IsFoldable()) { - return false; +JoinRelationSet *JoinRelationSetManager::GetJoinRelation(unordered_set &bindings) { + // create a sorted vector of the relations + unique_ptr relations = bindings.empty() ? nullptr : unique_ptr(new idx_t[bindings.size()]); + idx_t count = 0; + for (auto &entry : bindings) { + relations[count++] = entry; } - bindings.push_back(expr); - return true; + std::sort(relations.get(), relations.get() + count); + return GetJoinRelation(std::move(relations), count); } -} // namespace duckdb - - - - +JoinRelationSet *JoinRelationSetManager::Union(JoinRelationSet *left, JoinRelationSet *right) { + auto relations = unique_ptr(new idx_t[left->count + right->count]); + idx_t count = 0; + // move through the left and right relations, eliminating duplicates + idx_t i = 0, j = 0; + while (true) { + if (i == left->count) { + // exhausted left relation, add remaining of right relation + for (; j < right->count; j++) { + relations[count++] = right->relations[j]; + } + break; + } else if (j == right->count) { + // exhausted right relation, add remaining of left + for (; i < left->count; i++) { + relations[count++] = left->relations[i]; + } + break; + } else if (left->relations[i] == right->relations[j]) { + // equivalent, add only one of the two pairs + relations[count++] = left->relations[i]; + i++; + j++; + } else if (left->relations[i] < right->relations[j]) { + // left is smaller, progress left and add it to the set + relations[count++] = left->relations[i]; + i++; + } else { + // right is smaller, progress right and add it to the set + relations[count++] = right->relations[j]; + j++; + } + } + return GetJoinRelation(std::move(relations), count); +} + +// JoinRelationSet *JoinRelationSetManager::Difference(JoinRelationSet *left, JoinRelationSet *right) { +// auto relations = unique_ptr(new idx_t[left->count]); +// idx_t count = 0; +// // move through the left and right relations +// idx_t i = 0, j = 0; +// while (true) { +// if (i == left->count) { +// // exhausted left relation, we are done +// break; +// } else if (j == right->count) { +// // exhausted right relation, add remaining of left +// for (; i < left->count; i++) { +// relations[count++] = left->relations[i]; +// } +// break; +// } else if (left->relations[i] == right->relations[j]) { +// // equivalent, add nothing +// i++; +// j++; +// } else if (left->relations[i] < right->relations[j]) { +// // left is smaller, progress left and add it to the set +// relations[count++] = left->relations[i]; +// i++; +// } else { +// // right is smaller, progress right +// j++; +// } +// } +// return GetJoinRelation(std::move(relations), count); +// } + +} // namespace duckdb + + + + + + + +namespace duckdb { + +using QueryEdge = QueryGraph::QueryEdge; + +// LCOV_EXCL_START +static string QueryEdgeToString(const QueryEdge *info, vector prefix) { + string result = ""; + string source = "["; + for (idx_t i = 0; i < prefix.size(); i++) { + source += to_string(prefix[i]) + (i < prefix.size() - 1 ? ", " : ""); + } + source += "]"; + for (auto &entry : info->neighbors) { + result += StringUtil::Format("%s -> %s\n", source.c_str(), entry->neighbor->ToString().c_str()); + } + for (auto &entry : info->children) { + vector new_prefix = prefix; + new_prefix.push_back(entry.first); + result += QueryEdgeToString(entry.second.get(), new_prefix); + } + return result; +} + +string QueryGraph::ToString() const { + return QueryEdgeToString(&root, {}); +} + +void QueryGraph::Print() { + Printer::Print(ToString()); +} +// LCOV_EXCL_STOP + +QueryEdge *QueryGraph::GetQueryEdge(JoinRelationSet *left) { + D_ASSERT(left && left->count > 0); + // find the EdgeInfo corresponding to the left set + QueryEdge *info = &root; + for (idx_t i = 0; i < left->count; i++) { + auto entry = info->children.find(left->relations[i]); + if (entry == info->children.end()) { + // node not found, create it + auto insert_it = info->children.insert(make_pair(left->relations[i], make_unique())); + entry = insert_it.first; + } + // move to the next node + info = entry->second.get(); + } + return info; +} + +void QueryGraph::CreateEdge(JoinRelationSet *left, JoinRelationSet *right, FilterInfo *filter_info) { + D_ASSERT(left && right && left->count > 0 && right->count > 0); + // find the EdgeInfo corresponding to the left set + auto info = GetQueryEdge(left); + // now insert the edge to the right relation, if it does not exist + for (idx_t i = 0; i < info->neighbors.size(); i++) { + if (info->neighbors[i]->neighbor == right) { + if (filter_info) { + // neighbor already exists just add the filter, if we have any + info->neighbors[i]->filters.push_back(filter_info); + } + return; + } + } + // neighbor does not exist, create it + auto n = make_unique(); + if (filter_info) { + n->filters.push_back(filter_info); + } + n->neighbor = right; + info->neighbors.push_back(std::move(n)); +} + +void QueryGraph::EnumerateNeighbors(JoinRelationSet *node, const std::function &callback) { + for (idx_t j = 0; j < node->count; j++) { + QueryEdge *info = &root; + for (idx_t i = j; i < node->count; i++) { + auto entry = info->children.find(node->relations[i]); + if (entry == info->children.end()) { + // node not found + break; + } + // check if any subset of the other set is in this sets neighbors + info = entry->second.get(); + for (auto &neighbor : info->neighbors) { + if (callback(neighbor.get())) { + return; + } + } + } + } +} + +//! Returns true if a JoinRelationSet is banned by the list of exclusion_set, false otherwise +static bool JoinRelationSetIsExcluded(JoinRelationSet *node, unordered_set &exclusion_set) { + return exclusion_set.find(node->relations[0]) != exclusion_set.end(); +} + +vector QueryGraph::GetNeighbors(JoinRelationSet *node, unordered_set &exclusion_set) { + unordered_set result; + EnumerateNeighbors(node, [&](NeighborInfo *info) -> bool { + if (!JoinRelationSetIsExcluded(info->neighbor, exclusion_set)) { + // add the smallest node of the neighbor to the set + result.insert(info->neighbor->relations[0]); + } + return false; + }); + vector neighbors; + neighbors.insert(neighbors.end(), result.begin(), result.end()); + return neighbors; +} + +vector QueryGraph::GetConnections(JoinRelationSet *node, JoinRelationSet *other) { + vector connections; + EnumerateNeighbors(node, [&](NeighborInfo *info) -> bool { + if (JoinRelationSet::IsSubset(other, info->neighbor)) { + connections.push_back(info); + } + return false; + }); + return connections; +} + +} // namespace duckdb + + + + +namespace duckdb { + +bool ExpressionMatcher::Match(Expression *expr, vector &bindings) { + if (type && !type->Match(expr->return_type)) { + return false; + } + if (expr_type && !expr_type->Match(expr->type)) { + return false; + } + if (expr_class != ExpressionClass::INVALID && expr_class != expr->GetExpressionClass()) { + return false; + } + bindings.push_back(expr); + return true; +} + +bool ExpressionEqualityMatcher::Match(Expression *expr, vector &bindings) { + if (!Expression::Equals(expression, expr)) { + return false; + } + bindings.push_back(expr); + return true; +} + +bool CaseExpressionMatcher::Match(Expression *expr_p, vector &bindings) { + if (!ExpressionMatcher::Match(expr_p, bindings)) { + return false; + } + return true; +} + +bool ComparisonExpressionMatcher::Match(Expression *expr_p, vector &bindings) { + if (!ExpressionMatcher::Match(expr_p, bindings)) { + return false; + } + auto expr = (BoundComparisonExpression *)expr_p; + vector expressions = {expr->left.get(), expr->right.get()}; + return SetMatcher::Match(matchers, expressions, bindings, policy); +} + +bool CastExpressionMatcher::Match(Expression *expr_p, vector &bindings) { + if (!ExpressionMatcher::Match(expr_p, bindings)) { + return false; + } + if (!matcher) { + return true; + } + auto expr = (BoundCastExpression *)expr_p; + return matcher->Match(expr->child.get(), bindings); +} + +bool InClauseExpressionMatcher::Match(Expression *expr_p, vector &bindings) { + if (!ExpressionMatcher::Match(expr_p, bindings)) { + return false; + } + auto expr = (BoundOperatorExpression *)expr_p; + if (expr->type != ExpressionType::COMPARE_IN || expr->type == ExpressionType::COMPARE_NOT_IN) { + return false; + } + return SetMatcher::Match(matchers, expr->children, bindings, policy); +} + +bool ConjunctionExpressionMatcher::Match(Expression *expr_p, vector &bindings) { + if (!ExpressionMatcher::Match(expr_p, bindings)) { + return false; + } + auto expr = (BoundConjunctionExpression *)expr_p; + if (!SetMatcher::Match(matchers, expr->children, bindings, policy)) { + return false; + } + return true; +} + +bool FunctionExpressionMatcher::Match(Expression *expr_p, vector &bindings) { + if (!ExpressionMatcher::Match(expr_p, bindings)) { + return false; + } + auto expr = (BoundFunctionExpression *)expr_p; + if (!FunctionMatcher::Match(function, expr->function.name)) { + return false; + } + if (!SetMatcher::Match(matchers, expr->children, bindings, policy)) { + return false; + } + return true; +} + +bool FoldableConstantMatcher::Match(Expression *expr, vector &bindings) { + // we match on ANY expression that is a scalar expression + if (!expr->IsFoldable()) { + return false; + } + bindings.push_back(expr); + return true; +} + +} // namespace duckdb @@ -167996,6 +177457,96 @@ bool FoldableConstantMatcher::Match(Expression *expr, vector &bind +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/unnest_rewriter.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +class Optimizer; + +struct ReplaceBinding { + ReplaceBinding() {}; + ReplaceBinding(ColumnBinding old_binding, ColumnBinding new_binding) + : old_binding(old_binding), new_binding(new_binding) { + } + ColumnBinding old_binding; + ColumnBinding new_binding; +}; + +struct LHSBinding { + LHSBinding() {}; + LHSBinding(ColumnBinding binding, LogicalType type) : binding(binding), type(type) { + } + ColumnBinding binding; + LogicalType type; + string alias; +}; + +//! The UnnestRewriterPlanUpdater updates column bindings after changing the operator plan +class UnnestRewriterPlanUpdater : LogicalOperatorVisitor { +public: + UnnestRewriterPlanUpdater() { + } + //! Update each operator of the plan after moving an UNNEST into a projection + void VisitOperator(LogicalOperator &op) override; + //! Visit an expression and update its column bindings after moving and UNNEST into a projection + void VisitExpression(unique_ptr *expression) override; + + //! Contains all bindings that need to be updated + vector replace_bindings; +}; + +//! The UnnestRewriter optimizer traverses the logical operator tree and rewrites duplicate +//! eliminated joins that contain UNNESTs by moving the UNNESTs into the projection of +//! the SELECT +class UnnestRewriter { +public: + UnnestRewriter() { + } + //! Rewrite duplicate eliminated joins with UNNESTs + unique_ptr Optimize(unique_ptr op); + +private: + //! Find delim joins that contain an UNNEST + void FindCandidates(unique_ptr *op_ptr, vector *> &candidates); + //! Rewrite a delim join that contains an UNNEST + bool RewriteCandidate(unique_ptr *candidate); + //! Update the bindings of the RHS sequence of LOGICAL_PROJECTION(s) + void UpdateRHSBindings(unique_ptr *plan_ptr, unique_ptr *candidate, + UnnestRewriterPlanUpdater &updater); + //! Update the bindings of the BOUND_UNNEST expression of the LOGICAL_UNNEST + void UpdateBoundUnnestBindings(UnnestRewriterPlanUpdater &updater, unique_ptr *candidate); + + //! Store all delim columns of the delim join + void GetDelimColumns(LogicalOperator &op); + //! Store all LHS expressions of the LOGICAL_PROJECTION + void GetLHSExpressions(LogicalOperator &op); + + //! Keep track of the delim columns to find the correct UNNEST column + vector delim_columns; + //! Store the column bindings of the LHS child of the LOGICAL_DELIM_JOIN + vector lhs_bindings; + //! Stores the table index of the former child of the LOGICAL_UNNEST + idx_t overwritten_tbl_idx; +}; + +} // namespace duckdb + + + + + + //===----------------------------------------------------------------------===// // DuckDB // @@ -168471,7 +178022,6 @@ class TopN { - namespace duckdb { Optimizer::Optimizer(Binder &binder, ClientContext &context) : context(context), binder(binder), rewriter(context) { @@ -168519,7 +178069,7 @@ void Optimizer::Verify(LogicalOperator &op) { unique_ptr Optimizer::Optimize(unique_ptr plan_p) { Verify(*plan_p); - this->plan = move(plan_p); + this->plan = std::move(plan_p); // first we perform expression rewrites using the ExpressionRewriter // this does not change the logical plan structure, but only simplifies the expression trees RunOptimizer(OptimizerType::EXPRESSION_REWRITER, [&]() { rewriter.VisitOperator(*plan); }); @@ -168527,38 +178077,45 @@ unique_ptr Optimizer::Optimize(unique_ptr plan // perform filter pullup RunOptimizer(OptimizerType::FILTER_PULLUP, [&]() { FilterPullup filter_pullup; - plan = filter_pullup.Rewrite(move(plan)); + plan = filter_pullup.Rewrite(std::move(plan)); }); // perform filter pushdown RunOptimizer(OptimizerType::FILTER_PUSHDOWN, [&]() { FilterPushdown filter_pushdown(*this); - plan = filter_pushdown.Rewrite(move(plan)); + plan = filter_pushdown.Rewrite(std::move(plan)); }); RunOptimizer(OptimizerType::REGEX_RANGE, [&]() { RegexRangeFilter regex_opt; - plan = regex_opt.Rewrite(move(plan)); + plan = regex_opt.Rewrite(std::move(plan)); }); RunOptimizer(OptimizerType::IN_CLAUSE, [&]() { InClauseRewriter rewriter(context, *this); - plan = rewriter.Rewrite(move(plan)); + plan = rewriter.Rewrite(std::move(plan)); }); // then we perform the join ordering optimization // this also rewrites cross products + filters into joins and performs filter pushdowns RunOptimizer(OptimizerType::JOIN_ORDER, [&]() { JoinOrderOptimizer optimizer(context); - plan = optimizer.Optimize(move(plan)); + plan = optimizer.Optimize(std::move(plan)); }); // removes any redundant DelimGets/DelimJoins RunOptimizer(OptimizerType::DELIMINATOR, [&]() { - Deliminator deliminator; - plan = deliminator.Optimize(move(plan)); + Deliminator deliminator(context); + plan = deliminator.Optimize(std::move(plan)); + }); + + // rewrites UNNESTs in DelimJoins by moving them to the projection + RunOptimizer(OptimizerType::UNNEST_REWRITER, [&]() { + UnnestRewriter unnest_rewriter; + plan = unnest_rewriter.Optimize(std::move(plan)); }); + // removes unused columns RunOptimizer(OptimizerType::UNUSED_COLUMNS, [&]() { RemoveUnusedColumns unused(binder, context, true); unused.VisitOperator(*plan); @@ -168589,13 +178146,13 @@ unique_ptr Optimizer::Optimize(unique_ptr plan // transform ORDER BY + LIMIT to TopN RunOptimizer(OptimizerType::TOP_N, [&]() { TopN topn; - plan = topn.Optimize(move(plan)); + plan = topn.Optimize(std::move(plan)); }); // apply simple expression heuristics to get an initial reordering RunOptimizer(OptimizerType::REORDER_FILTER, [&]() { ExpressionHeuristics expression_heuristics(*this); - plan = expression_heuristics.Rewrite(move(plan)); + plan = expression_heuristics.Rewrite(std::move(plan)); }); for (auto &optimizer_extension : DBConfig::GetConfig(context).optimizer_extensions) { @@ -168606,7 +178163,7 @@ unique_ptr Optimizer::Optimize(unique_ptr plan Planner::VerifyPlan(context, plan); - return move(plan); + return std::move(plan); } } // namespace duckdb @@ -168617,18 +178174,18 @@ namespace duckdb { unique_ptr FilterPullup::PullupBothSide(unique_ptr op) { FilterPullup left_pullup(true, can_add_column); FilterPullup right_pullup(true, can_add_column); - op->children[0] = left_pullup.Rewrite(move(op->children[0])); - op->children[1] = right_pullup.Rewrite(move(op->children[1])); + op->children[0] = left_pullup.Rewrite(std::move(op->children[0])); + op->children[1] = right_pullup.Rewrite(std::move(op->children[1])); D_ASSERT(left_pullup.can_add_column == can_add_column); D_ASSERT(right_pullup.can_add_column == can_add_column); // merging filter expressions for (idx_t i = 0; i < right_pullup.filters_expr_pullup.size(); ++i) { - left_pullup.filters_expr_pullup.push_back(move(right_pullup.filters_expr_pullup[i])); + left_pullup.filters_expr_pullup.push_back(std::move(right_pullup.filters_expr_pullup[i])); } if (!left_pullup.filters_expr_pullup.empty()) { - return GeneratePullupFilter(move(op), left_pullup.filters_expr_pullup); + return GeneratePullupFilter(std::move(op), left_pullup.filters_expr_pullup); } return op; } @@ -168647,15 +178204,15 @@ unique_ptr FilterPullup::PullupFilter(unique_ptr child = move(op->children[0]); - child = Rewrite(move(child)); + unique_ptr child = std::move(op->children[0]); + child = Rewrite(std::move(child)); // moving filter's expressions for (idx_t i = 0; i < op->expressions.size(); ++i) { - filters_expr_pullup.push_back(move(op->expressions[i])); + filters_expr_pullup.push_back(std::move(op->expressions[i])); } return child; } - op->children[0] = Rewrite(move(op->children[0])); + op->children[0] = Rewrite(std::move(op->children[0])); return op; } @@ -168674,12 +178231,12 @@ unique_ptr FilterPullup::PullupFromLeft(unique_ptrchildren[0] = left_pullup.Rewrite(move(op->children[0])); - op->children[1] = right_pullup.Rewrite(move(op->children[1])); + op->children[0] = left_pullup.Rewrite(std::move(op->children[0])); + op->children[1] = right_pullup.Rewrite(std::move(op->children[1])); // check only for filters from the LHS if (!left_pullup.filters_expr_pullup.empty() && right_pullup.filters_expr_pullup.empty()) { - return GeneratePullupFilter(move(op), left_pullup.filters_expr_pullup); + return GeneratePullupFilter(std::move(op), left_pullup.filters_expr_pullup); } return op; } @@ -168697,11 +178254,11 @@ namespace duckdb { static void RevertFilterPullup(LogicalProjection &proj, vector> &expressions) { unique_ptr filter = make_unique(); for (idx_t i = 0; i < expressions.size(); ++i) { - filter->expressions.push_back(move(expressions[i])); + filter->expressions.push_back(std::move(expressions[i])); } expressions.clear(); - filter->children.push_back(move(proj.children[0])); - proj.children[0] = move(filter); + filter->children.push_back(std::move(proj.children[0])); + proj.children[0] = std::move(filter); } static void ReplaceExpressionBinding(vector> &proj_expressions, Expression &expr, @@ -168726,7 +178283,7 @@ static void ReplaceExpressionBinding(vector> &proj_expres auto new_colref = colref.Copy(); colref.binding.table_index = proj_table_idx; colref.binding.column_index = proj_expressions.size(); - proj_expressions.push_back(move(new_colref)); + proj_expressions.push_back(std::move(new_colref)); } } ExpressionIterator::EnumerateChildren( @@ -168745,7 +178302,7 @@ void FilterPullup::ProjectSetOperation(LogicalProjection &proj) { for (idx_t i = 0; i < filters_expr_pullup.size(); ++i) { auto copy_filter_expr = filters_expr_pullup[i]->Copy(); ReplaceExpressionBinding(copy_proj_expressions, (Expression &)*copy_filter_expr, proj.table_index); - changed_filter_expressions.push_back(move(copy_filter_expr)); + changed_filter_expressions.push_back(std::move(copy_filter_expr)); } /// Case new columns were added into the projection @@ -168758,13 +178315,13 @@ void FilterPullup::ProjectSetOperation(LogicalProjection &proj) { // now we must replace the filter bindings D_ASSERT(filters_expr_pullup.size() == changed_filter_expressions.size()); for (idx_t i = 0; i < filters_expr_pullup.size(); ++i) { - filters_expr_pullup[i] = move(changed_filter_expressions[i]); + filters_expr_pullup[i] = std::move(changed_filter_expressions[i]); } } unique_ptr FilterPullup::PullupProjection(unique_ptr op) { D_ASSERT(op->type == LogicalOperatorType::LOGICAL_PROJECTION); - op->children[0] = Rewrite(move(op->children[0])); + op->children[0] = Rewrite(std::move(op->children[0])); if (!filters_expr_pullup.empty()) { auto &proj = (LogicalProjection &)*op; // INTERSECT, EXCEPT, and DISTINCT @@ -168806,10 +178363,10 @@ unique_ptr FilterPullup::PullupSetOperation(unique_ptrtype == LogicalOperatorType::LOGICAL_INTERSECT) { - op = PullupBothSide(move(op)); + op = PullupBothSide(std::move(op)); } else { // EXCEPT only pull ups from LHS - op = PullupFromLeft(move(op)); + op = PullupFromLeft(std::move(op)); } if (op->type == LogicalOperatorType::LOGICAL_FILTER) { auto &filter = (LogicalFilter &)*op; @@ -168843,7 +178400,7 @@ static unique_ptr ReplaceGroupBindings(LogicalAggregate &proj, uniqu return proj.groups[colref.binding.column_index]->Copy(); } ExpressionIterator::EnumerateChildren( - *expr, [&](unique_ptr &child) { child = ReplaceGroupBindings(proj, move(child)); }); + *expr, [&](unique_ptr &child) { child = ReplaceGroupBindings(proj, std::move(child)); }); return expr; } @@ -168876,11 +178433,11 @@ unique_ptr FilterPushdown::PushdownAggregate(unique_ptr(move(op)); + return make_unique(std::move(op)); } // erase the filter from here filters.erase(filters.begin() + i); @@ -168888,8 +178445,8 @@ unique_ptr FilterPushdown::PushdownAggregate(unique_ptrchildren[0] = child_pushdown.Rewrite(move(op->children[0])); - return FinishPushdown(move(op)); + op->children[0] = child_pushdown.Rewrite(std::move(op->children[0])); + return FinishPushdown(std::move(op)); } } // namespace duckdb @@ -168904,7 +178461,7 @@ using Filter = FilterPushdown::Filter; unique_ptr FilterPushdown::PushdownCrossProduct(unique_ptr op) { D_ASSERT(op->type == LogicalOperatorType::LOGICAL_CROSS_PRODUCT); FilterPushdown left_pushdown(optimizer), right_pushdown(optimizer); - vector> join_conditions; + vector> join_expressions; unordered_set left_bindings, right_bindings; if (!filters.empty()) { // check to see into which side we should push the filters @@ -168916,25 +178473,34 @@ unique_ptr FilterPushdown::PushdownCrossProduct(unique_ptrbindings, left_bindings, right_bindings); if (side == JoinSide::LEFT) { // bindings match left side: push into left - left_pushdown.filters.push_back(move(f)); + left_pushdown.filters.push_back(std::move(f)); } else if (side == JoinSide::RIGHT) { // bindings match right side: push into right - right_pushdown.filters.push_back(move(f)); + right_pushdown.filters.push_back(std::move(f)); } else { D_ASSERT(side == JoinSide::BOTH || side == JoinSide::NONE); // bindings match both: turn into join condition - join_conditions.push_back(move(f->filter)); + join_expressions.push_back(std::move(f->filter)); } } } - op->children[0] = left_pushdown.Rewrite(move(op->children[0])); - op->children[1] = right_pushdown.Rewrite(move(op->children[1])); + op->children[0] = left_pushdown.Rewrite(std::move(op->children[0])); + op->children[1] = right_pushdown.Rewrite(std::move(op->children[1])); - if (!join_conditions.empty()) { + if (!join_expressions.empty()) { // join conditions found: turn into inner join - return LogicalComparisonJoin::CreateJoin(JoinType::INNER, move(op->children[0]), move(op->children[1]), - left_bindings, right_bindings, join_conditions); + // extract join conditions + vector conditions; + vector> arbitrary_expressions; + auto join_type = JoinType::INNER; + LogicalComparisonJoin::ExtractJoinConditions(join_type, op->children[0], op->children[1], left_bindings, + right_bindings, join_expressions, conditions, + arbitrary_expressions); + // create the join from the join conditions + return LogicalComparisonJoin::CreateJoin(JoinType::INNER, std::move(op->children[0]), + std::move(op->children[1]), std::move(conditions), + std::move(arbitrary_expressions)); } else { // no join conditions found: keep as cross product return op; @@ -168954,17 +178520,17 @@ unique_ptr FilterPushdown::PushdownFilter(unique_ptrtype == LogicalOperatorType::LOGICAL_FILTER); auto &filter = (LogicalFilter &)*op; if (!filter.projection_map.empty()) { - return FinishPushdown(move(op)); + return FinishPushdown(std::move(op)); } // filter: gather the filters and remove the filter from the set of operations for (auto &expression : filter.expressions) { - if (AddFilter(move(expression)) == FilterResult::UNSATISFIABLE) { + if (AddFilter(std::move(expression)) == FilterResult::UNSATISFIABLE) { // filter statically evaluates to false, strip tree - return make_unique(move(op)); + return make_unique(std::move(op)); } } GenerateFilters(); - return Rewrite(move(filter.children[0])); + return Rewrite(std::move(filter.children[0])); } } // namespace duckdb @@ -168996,8 +178562,9 @@ unique_ptr FilterPushdown::PushdownGet(unique_ptr> expressions; + expressions.reserve(filters.size()); for (auto &filter : filters) { - expressions.push_back(move(filter->filter)); + expressions.push_back(std::move(filter->filter)); } filters.clear(); @@ -169009,15 +178576,15 @@ unique_ptr FilterPushdown::PushdownGet(unique_ptr(); - f->filter = move(expr); + f->filter = std::move(expr); f->ExtractBindings(); - filters.push_back(move(f)); + filters.push_back(std::move(f)); } } if (!get.table_filters.filters.empty() || !get.function.filter_pushdown) { // the table function does not support filter pushdown: push a LogicalFilter on top - return FinishPushdown(move(op)); + return FinishPushdown(std::move(op)); } PushFilters(); @@ -169044,7 +178611,7 @@ unique_ptr FilterPushdown::PushdownGet(unique_ptr FilterPushdown::PushdownInnerJoin(unique_ptr &right_bindings) { auto &join = (LogicalJoin &)*op; D_ASSERT(join.join_type == JoinType::INNER); - D_ASSERT(op->type != LogicalOperatorType::LOGICAL_DELIM_JOIN); + if (op->type == LogicalOperatorType::LOGICAL_DELIM_JOIN) { + return FinishPushdown(std::move(op)); + } // inner join: gather all the conditions of the inner join and add to the filter list if (op->type == LogicalOperatorType::LOGICAL_ANY_JOIN) { auto &any_join = (LogicalAnyJoin &)join; // any join: only one filter to add - if (AddFilter(move(any_join.condition)) == FilterResult::UNSATISFIABLE) { + if (AddFilter(std::move(any_join.condition)) == FilterResult::UNSATISFIABLE) { // filter statically evaluates to false, strip tree - return make_unique(move(op)); + return make_unique(std::move(op)); } } else { // comparison join @@ -169078,19 +178647,19 @@ unique_ptr FilterPushdown::PushdownInnerJoin(unique_ptr(move(op)); + return make_unique(std::move(op)); } } } GenerateFilters(); // turn the inner join into a cross product - auto cross_product = make_unique(move(op->children[0]), move(op->children[1])); + auto cross_product = make_unique(std::move(op->children[0]), std::move(op->children[1])); // then push down cross product - return PushdownCrossProduct(move(cross_product)); + return PushdownCrossProduct(std::move(cross_product)); } } // namespace duckdb @@ -169119,7 +178688,7 @@ static unique_ptr ReplaceColRefWithNull(unique_ptr expr, return expr; } ExpressionIterator::EnumerateChildren( - *expr, [&](unique_ptr &child) { child = ReplaceColRefWithNull(move(child), right_bindings); }); + *expr, [&](unique_ptr &child) { child = ReplaceColRefWithNull(std::move(child), right_bindings); }); return expr; } @@ -169128,11 +178697,11 @@ static bool FilterRemovesNull(ClientContext &context, ExpressionRewriter &rewrit // make a copy of the expression auto copy = expr->Copy(); // replace all BoundColumnRef expressions frmo the RHS with NULL constants in the copied expression - copy = ReplaceColRefWithNull(move(copy), right_bindings); + copy = ReplaceColRefWithNull(std::move(copy), right_bindings); // attempt to flatten the expression by running the expression rewriter on it auto filter = make_unique(); - filter->expressions.push_back(move(copy)); + filter->expressions.push_back(std::move(copy)); rewriter.VisitOperator(*filter); // check if all expressions are foldable @@ -169157,8 +178726,9 @@ unique_ptr FilterPushdown::PushdownLeftJoin(unique_ptr &left_bindings, unordered_set &right_bindings) { auto &join = (LogicalJoin &)*op; - D_ASSERT(join.join_type == JoinType::LEFT); - D_ASSERT(op->type != LogicalOperatorType::LOGICAL_DELIM_JOIN); + if (op->type == LogicalOperatorType::LOGICAL_DELIM_JOIN) { + return FinishPushdown(std::move(op)); + } FilterPushdown left_pushdown(optimizer), right_pushdown(optimizer); // for a comparison join we create a FilterCombiner that checks if we can push conditions on LHS join conditions // into the RHS of the join @@ -169182,7 +178752,7 @@ unique_ptr FilterPushdown::PushdownLeftJoin(unique_ptrfilter->Copy()); } - left_pushdown.filters.push_back(move(filters[i])); + left_pushdown.filters.push_back(std::move(filters[i])); // erase the filter from the list of filters filters.erase(filters.begin() + i); i--; @@ -169196,10 +178766,10 @@ unique_ptr FilterPushdown::PushdownLeftJoin(unique_ptr FilterPushdown::PushdownLeftJoin(unique_ptr filter) { if (JoinSide::GetJoinSide(*filter, left_bindings, right_bindings) == JoinSide::RIGHT) { - right_pushdown.AddFilter(move(filter)); + right_pushdown.AddFilter(std::move(filter)); } }); right_pushdown.GenerateFilters(); - op->children[0] = left_pushdown.Rewrite(move(op->children[0])); - op->children[1] = right_pushdown.Rewrite(move(op->children[1])); - return FinishPushdown(move(op)); + op->children[0] = left_pushdown.Rewrite(std::move(op->children[0])); + op->children[1] = right_pushdown.Rewrite(std::move(op->children[1])); + if (filters.empty()) { + // no filters to push + return op; + } + auto filter = make_unique(); + for (auto &f : filters) { + filter->expressions.push_back(std::move(f->filter)); + } + filter->children.push_back(std::move(op)); + return std::move(filter); } } // namespace duckdb @@ -169233,10 +178812,10 @@ unique_ptr FilterPushdown::PushdownLimit(unique_ptr(move(op)); + return make_unique(std::move(op)); } - return FinishPushdown(move(op)); + return FinishPushdown(std::move(op)); } } // namespace duckdb @@ -169267,7 +178846,7 @@ unique_ptr FilterPushdown::PushdownMarkJoin(unique_ptrbindings, left_bindings, right_bindings); if (side == JoinSide::LEFT) { // bindings match left side: push into left - left_pushdown.filters.push_back(move(filters[i])); + left_pushdown.filters.push_back(std::move(filters[i])); // erase the filter from the list of filters filters.erase(filters.begin() + i); i--; @@ -169317,9 +178896,9 @@ unique_ptr FilterPushdown::PushdownMarkJoin(unique_ptrchildren[0] = left_pushdown.Rewrite(move(op->children[0])); - op->children[1] = right_pushdown.Rewrite(move(op->children[1])); - return FinishPushdown(move(op)); + op->children[0] = left_pushdown.Rewrite(std::move(op->children[0])); + op->children[1] = right_pushdown.Rewrite(std::move(op->children[1])); + return FinishPushdown(std::move(op)); } } // namespace duckdb @@ -169341,7 +178920,7 @@ static unique_ptr ReplaceProjectionBindings(LogicalProjection &proj, return proj.expressions[colref.binding.column_index]->Copy(); } ExpressionIterator::EnumerateChildren( - *expr, [&](unique_ptr &child) { child = ReplaceProjectionBindings(proj, move(child)); }); + *expr, [&](unique_ptr &child) { child = ReplaceProjectionBindings(proj, std::move(child)); }); return expr; } @@ -169356,19 +178935,19 @@ unique_ptr FilterPushdown::PushdownProjection(unique_ptr(move(op)); + return make_unique(std::move(op)); } } child_pushdown.GenerateFilters(); // now push into children - op->children[0] = child_pushdown.Rewrite(move(op->children[0])); + op->children[0] = child_pushdown.Rewrite(std::move(op->children[0])); if (op->children[0]->type == LogicalOperatorType::LOGICAL_EMPTY_RESULT) { // child returns an empty result: generate an empty result here too - return make_unique(move(op)); + return make_unique(std::move(op)); } return op; } @@ -169432,18 +179011,18 @@ unique_ptr FilterPushdown::PushdownSetOperation(unique_ptrExtractBindings(); // move the filters into the child pushdown nodes - left_pushdown.filters.push_back(move(filters[i])); - right_pushdown.filters.push_back(move(right_filter)); + left_pushdown.filters.push_back(std::move(filters[i])); + right_pushdown.filters.push_back(std::move(right_filter)); } - op->children[0] = left_pushdown.Rewrite(move(op->children[0])); - op->children[1] = right_pushdown.Rewrite(move(op->children[1])); + op->children[0] = left_pushdown.Rewrite(std::move(op->children[0])); + op->children[1] = right_pushdown.Rewrite(std::move(op->children[1])); bool left_empty = op->children[0]->type == LogicalOperatorType::LOGICAL_EMPTY_RESULT; bool right_empty = op->children[1]->type == LogicalOperatorType::LOGICAL_EMPTY_RESULT; if (left_empty && right_empty) { // both empty: return empty result - return make_unique(move(op)); + return make_unique(std::move(op)); } if (left_empty) { // left child is empty result @@ -169453,14 +179032,14 @@ unique_ptr FilterPushdown::PushdownSetOperation(unique_ptrchildren[1]; projection.table_index = setop.table_index; - return move(op->children[1]); + return std::move(op->children[1]); } break; case LogicalOperatorType::LOGICAL_EXCEPT: // except: if left child is empty, return empty result case LogicalOperatorType::LOGICAL_INTERSECT: // intersect: if any child is empty, return empty result itself - return make_unique(move(op)); + return make_unique(std::move(op)); default: throw InternalException("Unsupported set operation"); } @@ -169473,12 +179052,12 @@ unique_ptr FilterPushdown::PushdownSetOperation(unique_ptrchildren[0]; projection.table_index = setop.table_index; - return move(op->children[0]); + return std::move(op->children[0]); } break; case LogicalOperatorType::LOGICAL_INTERSECT: // intersect: if any child is empty, return empty result itself - return make_unique(move(op)); + return make_unique(std::move(op)); default: throw InternalException("Unsupported set operation"); } @@ -169504,15 +179083,15 @@ unique_ptr FilterPushdown::PushdownSingleJoin(unique_ptrbindings, left_bindings, right_bindings); if (side == JoinSide::LEFT) { // bindings match left side: push into left - left_pushdown.filters.push_back(move(filters[i])); + left_pushdown.filters.push_back(std::move(filters[i])); // erase the filter from the list of filters filters.erase(filters.begin() + i); i--; } } - op->children[0] = left_pushdown.Rewrite(move(op->children[0])); - op->children[1] = right_pushdown.Rewrite(move(op->children[1])); - return FinishPushdown(move(op)); + op->children[0] = left_pushdown.Rewrite(std::move(op->children[0])); + op->children[1] = right_pushdown.Rewrite(std::move(op->children[1])); + return FinishPushdown(std::move(op)); } } // namespace duckdb @@ -169536,7 +179115,7 @@ namespace duckdb { unique_ptr RegexRangeFilter::Rewrite(unique_ptr op) { for (idx_t child_idx = 0; child_idx < op->children.size(); child_idx++) { - op->children[child_idx] = Rewrite(move(op->children[child_idx])); + op->children[child_idx] = Rewrite(std::move(op->children[child_idx])); } if (op->type != LogicalOperatorType::LOGICAL_FILTER) { @@ -169564,16 +179143,16 @@ unique_ptr RegexRangeFilter::Rewrite(unique_ptr( Value::BLOB((const_data_ptr_t)info.range_max.c_str(), info.range_max.size()))); auto filter_expr = make_unique(ExpressionType::CONJUNCTION_AND, - move(filter_left), move(filter_right)); + std::move(filter_left), std::move(filter_right)); - new_filter->expressions.push_back(move(filter_expr)); + new_filter->expressions.push_back(std::move(filter_expr)); } } if (!new_filter->expressions.empty()) { - new_filter->children = move(op->children); + new_filter->children = std::move(op->children); op->children.clear(); - op->children.push_back(move(new_filter)); + op->children.push_back(std::move(new_filter)); } return op; @@ -169723,9 +179302,9 @@ void RemoveUnusedColumns::VisitOperator(LogicalOperator &op) { make_unique(child->types[column_idx], bindings[column_idx])); } auto new_projection = - make_unique(binder.GenerateTableIndex(), move(expressions)); - new_projection->children.push_back(move(child)); - op.children[child_idx] = move(new_projection); + make_unique(binder.GenerateTableIndex(), std::move(expressions)); + new_projection->children.push_back(std::move(child)); + op.children[child_idx] = std::move(new_projection); remove.VisitOperator(*op.children[child_idx]); } @@ -169797,6 +179376,9 @@ void RemoveUnusedColumns::VisitOperator(LogicalOperator &op) { LogicalOperatorVisitor::VisitOperatorExpressions(op); if (!everything_referenced) { auto &get = (LogicalGet &)op; + if (!get.function.projection_pushdown) { + return; + } // Create "selection vector" of all column ids vector proj_sel; @@ -169836,7 +179418,7 @@ void RemoveUnusedColumns::VisitOperator(LogicalOperator &op) { for (auto col_sel_idx : col_sel) { column_ids.push_back(get.column_ids[col_sel_idx]); } - get.column_ids = move(column_ids); + get.column_ids = std::move(column_ids); if (get.function.filter_prune) { // Now set the projection cols by matching the "selection vector" that excludes filter columns @@ -169860,6 +179442,15 @@ void RemoveUnusedColumns::VisitOperator(LogicalOperator &op) { } } return; + case LogicalOperatorType::LOGICAL_FILTER: { + auto &filter = (LogicalFilter &)op; + if (!filter.projection_map.empty()) { + // if we have any entries in the filter projection map don't prune any columns + // FIXME: we can do something more clever here + everything_referenced = true; + } + break; + } case LogicalOperatorType::LOGICAL_DISTINCT: { // distinct, all projected columns are used for the DISTINCT computation // mark all columns as used and continue to the children @@ -169917,7 +179508,7 @@ ArithmeticSimplificationRule::ArithmeticSimplificationRule(ExpressionRewriter &r op->type = make_unique(); op->matchers[0]->type = make_unique(); op->matchers[1]->type = make_unique(); - root = move(op); + root = std::move(op); } unique_ptr ArithmeticSimplificationRule::Apply(LogicalOperator &op, vector &bindings, @@ -169936,21 +179527,21 @@ unique_ptr ArithmeticSimplificationRule::Apply(LogicalOperator &op, if (constant->value == 0) { // addition with 0 // we can remove the entire operator and replace it with the non-constant child - return move(root->children[1 - constant_child]); + return std::move(root->children[1 - constant_child]); } } else if (func_name == "-") { if (constant_child == 1 && constant->value == 0) { // subtraction by 0 // we can remove the entire operator and replace it with the non-constant child - return move(root->children[1 - constant_child]); + return std::move(root->children[1 - constant_child]); } } else if (func_name == "*") { if (constant->value == 1) { // multiply with 1, replace with non-constant child - return move(root->children[1 - constant_child]); + return std::move(root->children[1 - constant_child]); } else if (constant->value == 0) { // multiply by zero: replace with constant or null - return ExpressionRewriter::ConstantOrNull(move(root->children[1 - constant_child]), + return ExpressionRewriter::ConstantOrNull(std::move(root->children[1 - constant_child]), Value::Numeric(root->return_type, 0)); } } else { @@ -169958,7 +179549,7 @@ unique_ptr ArithmeticSimplificationRule::Apply(LogicalOperator &op, if (constant_child == 1) { if (constant->value == 1) { // divide by 1, replace with non-constant child - return move(root->children[1 - constant_child]); + return std::move(root->children[1 - constant_child]); } else if (constant->value == 0) { // divide by 0, replace with NULL return make_unique(Value(root->return_type)); @@ -169978,7 +179569,7 @@ namespace duckdb { CaseSimplificationRule::CaseSimplificationRule(ExpressionRewriter &rewriter) : Rule(rewriter) { // match on a CaseExpression that has a ConstantExpression as a check auto op = make_unique(); - root = move(op); + root = std::move(op); } unique_ptr CaseSimplificationRule::Apply(LogicalOperator &op, vector &bindings, @@ -170000,7 +179591,7 @@ unique_ptr CaseSimplificationRule::Apply(LogicalOperator &op, vector } else { // the condition is always true // move the THEN clause to the ELSE of the case - root->else_expr = move(case_check.then_expr); + root->else_expr = std::move(case_check.then_expr); // remove this case check and any case checks after this one root->case_checks.erase(root->case_checks.begin() + i, root->case_checks.end()); break; @@ -170009,7 +179600,7 @@ unique_ptr CaseSimplificationRule::Apply(LogicalOperator &op, vector } if (root->case_checks.empty()) { // no case checks left: return the ELSE expression - return move(root->else_expr); + return std::move(root->else_expr); } return nullptr; } @@ -170028,7 +179619,7 @@ ComparisonSimplificationRule::ComparisonSimplificationRule(ExpressionRewriter &r auto op = make_unique(); op->matchers.push_back(make_unique()); op->policy = SetMatcher::Policy::SOME; - root = move(op); + root = std::move(op); } unique_ptr ComparisonSimplificationRule::Apply(LogicalOperator &op, vector &bindings, @@ -170080,14 +179671,14 @@ unique_ptr ComparisonSimplificationRule::Apply(LogicalOperator &op, } //! We can cast, now we change our column_ref_expression from an operator cast to a column reference - auto child_expression = move(cast_expression->child); + auto child_expression = std::move(cast_expression->child); auto new_constant_expr = make_unique(cast_constant); if (column_ref_left) { - expr->left = move(child_expression); - expr->right = move(new_constant_expr); + expr->left = std::move(child_expression); + expr->right = std::move(new_constant_expr); } else { - expr->left = move(new_constant_expr); - expr->right = move(child_expression); + expr->left = std::move(new_constant_expr); + expr->right = std::move(child_expression); } } return nullptr; @@ -170107,7 +179698,7 @@ ConjunctionSimplificationRule::ConjunctionSimplificationRule(ExpressionRewriter auto op = make_unique(); op->matchers.push_back(make_unique()); op->policy = SetMatcher::Policy::SOME; - root = move(op); + root = std::move(op); } unique_ptr ConjunctionSimplificationRule::RemoveExpression(BoundConjunctionExpression &conj, @@ -170121,7 +179712,7 @@ unique_ptr ConjunctionSimplificationRule::RemoveExpression(BoundConj } if (conj.children.size() == 1) { // one expression remaining: simply return that expression and erase the conjunction - return move(conj.children[0]); + return std::move(conj.children[0]); } return nullptr; } @@ -170186,7 +179777,7 @@ class ConstantFoldingExpressionMatcher : public FoldableConstantMatcher { ConstantFoldingRule::ConstantFoldingRule(ExpressionRewriter &rewriter) : Rule(rewriter) { auto op = make_unique(); - root = move(op); + root = std::move(op); } unique_ptr ConstantFoldingRule::Apply(LogicalOperator &op, vector &bindings, @@ -170225,7 +179816,7 @@ DatePartSimplificationRule::DatePartSimplificationRule(ExpressionRewriter &rewri func->matchers.push_back(make_unique()); func->matchers.push_back(make_unique()); func->policy = SetMatcher::Policy::ORDERED; - root = move(func); + root = std::move(func); } unique_ptr DatePartSimplificationRule::Apply(LogicalOperator &op, vector &bindings, @@ -170301,11 +179892,11 @@ unique_ptr DatePartSimplificationRule::Apply(LogicalOperator &op, ve } // found a replacement function: bind it vector> children; - children.push_back(move(date_part.children[1])); + children.push_back(std::move(date_part.children[1])); string error; FunctionBinder binder(rewriter.context); - auto function = binder.BindScalarFunction(DEFAULT_SCHEMA, new_function_name, move(children), error, false); + auto function = binder.BindScalarFunction(DEFAULT_SCHEMA, new_function_name, std::move(children), error, false); if (!function) { throw BinderException(error); } @@ -170349,19 +179940,19 @@ unique_ptr DistributivityRule::ExtractExpression(BoundConjunctionExp auto &and_expr = (BoundConjunctionExpression &)*child; for (idx_t i = 0; i < and_expr.children.size(); i++) { if (Expression::Equals(and_expr.children[i].get(), &expr)) { - result = move(and_expr.children[i]); + result = std::move(and_expr.children[i]); and_expr.children.erase(and_expr.children.begin() + i); break; } } if (and_expr.children.size() == 1) { - conj.children[idx] = move(and_expr.children[0]); + conj.children[idx] = std::move(and_expr.children[0]); } } else { // not an AND node! remove the entire expression // this happens in the case of e.g. (X AND B) OR X D_ASSERT(Expression::Equals(child.get(), &expr)); - result = move(child); + result = std::move(child); conj.children[idx] = nullptr; } D_ASSERT(result); @@ -170409,7 +180000,7 @@ unique_ptr DistributivityRule::Apply(LogicalOperator &op, vectorchildren.push_back(move(result)); + new_root->children.push_back(std::move(result)); } // check if we completely erased one of the children of the OR @@ -170422,29 +180013,29 @@ unique_ptr DistributivityRule::Apply(LogicalOperator &op, vectorchildren.size(); i++) { if (!initial_or->children[i]) { if (new_root->children.size() <= 1) { - return move(new_root->children[0]); + return std::move(new_root->children[0]); } else { - return move(new_root); + return std::move(new_root); } } } // finally we need to add the remaining expressions in the OR to the new root if (initial_or->children.size() == 1) { // one child: skip the OR entirely and only add the single child - new_root->children.push_back(move(initial_or->children[0])); + new_root->children.push_back(std::move(initial_or->children[0])); } else if (initial_or->children.size() > 1) { // multiple children still remain: push them into a new OR and add that to the new root auto new_or = make_unique(ExpressionType::CONJUNCTION_OR); for (auto &child : initial_or->children) { - new_or->children.push_back(move(child)); + new_or->children.push_back(std::move(child)); } - new_root->children.push_back(move(new_or)); + new_root->children.push_back(std::move(new_or)); } // finally return the new root if (new_root->children.size() == 1) { - return move(new_root->children[0]); + return std::move(new_root->children[0]); } - return move(new_root); + return std::move(new_root); } } // namespace duckdb @@ -170468,7 +180059,7 @@ EmptyNeedleRemovalRule::EmptyNeedleRemovalRule(ExpressionRewriter &rewriter) : R unordered_set functions = {"prefix", "contains", "suffix"}; func->function = make_unique(functions); - root = move(func); + root = std::move(func); } unique_ptr EmptyNeedleRemovalRule::Apply(LogicalOperator &op, vector &bindings, @@ -170497,7 +180088,7 @@ unique_ptr EmptyNeedleRemovalRule::Apply(LogicalOperator &op, vector // PREFIX(NULL, '') is NULL // so rewrite PREFIX(x, '') to TRUE_OR_NULL(x) if (needle_string.empty()) { - return ExpressionRewriter::ConstantOrNull(move(root->children[0]), Value::BOOLEAN(true)); + return ExpressionRewriter::ConstantOrNull(std::move(root->children[0]), Value::BOOLEAN(true)); } return nullptr; } @@ -170553,9 +180144,9 @@ EnumComparisonRule::EnumComparisonRule(ExpressionRewriter &rewriter) : Rule(rewr child->type = make_unique(LogicalTypeId::VARCHAR); child->matcher = make_unique(); child->matcher->type = make_unique(LogicalTypeId::ENUM); - op->matchers.push_back(move(child)); + op->matchers.push_back(std::move(child)); } - root = move(op); + root = std::move(op); } bool AreMatchesPossible(LogicalType &left, LogicalType &right) { @@ -170587,9 +180178,9 @@ unique_ptr EnumComparisonRule::Apply(LogicalOperator &op, vectorchild->return_type, right_child->child->return_type)) { vector> children; - children.push_back(move(root->left)); - children.push_back(move(root->right)); - return ExpressionRewriter::ConstantOrNull(move(children), Value::BOOLEAN(false)); + children.push_back(std::move(root->left)); + children.push_back(std::move(root->right)); + return ExpressionRewriter::ConstantOrNull(std::move(children), Value::BOOLEAN(false)); } if (!is_root || op.type != LogicalOperatorType::LOGICAL_FILTER) { @@ -170597,8 +180188,9 @@ unique_ptr EnumComparisonRule::Apply(LogicalOperator &op, vectorchild), right_child->child->return_type, true); - return make_unique(root->type, move(cast_left_to_right), move(right_child->child)); + BoundCastExpression::AddDefaultCastToType(std::move(left_child->child), right_child->child->return_type, true); + return make_unique(root->type, std::move(cast_left_to_right), + std::move(right_child->child)); } } // namespace duckdb @@ -170620,7 +180212,7 @@ EqualOrNullSimplification::EqualOrNullSimplification(ExpressionRewriter &rewrite auto equal_child = make_unique(); equal_child->expr_type = make_unique(ExpressionType::COMPARE_EQUAL); equal_child->policy = SetMatcher::Policy::SOME; - op->matchers.push_back(move(equal_child)); + op->matchers.push_back(std::move(equal_child)); // AND conjuction on the other auto and_child = make_unique(); @@ -170633,11 +180225,11 @@ EqualOrNullSimplification::EqualOrNullSimplification(ExpressionRewriter &rewrite // I could try to use std::make_unique for a copy, but it's available from C++14 only auto isnull_child2 = make_unique(); isnull_child2->expr_type = make_unique(ExpressionType::OPERATOR_IS_NULL); - and_child->matchers.push_back(move(isnull_child)); - and_child->matchers.push_back(move(isnull_child2)); + and_child->matchers.push_back(std::move(isnull_child)); + and_child->matchers.push_back(std::move(isnull_child2)); - op->matchers.push_back(move(and_child)); - root = move(op); + op->matchers.push_back(std::move(and_child)); + root = std::move(op); } // a=b OR (a IS NULL AND b IS NULL) to a IS NOT DISTINCT FROM b @@ -170682,8 +180274,8 @@ static unique_ptr TryRewriteEqualOrIsNull(const Expression *equal_ex } } if (valid && a_is_null_found && b_is_null_found) { - return make_unique(ExpressionType::COMPARE_NOT_DISTINCT_FROM, move(equal_cast->left), - move(equal_cast->right)); + return make_unique(ExpressionType::COMPARE_NOT_DISTINCT_FROM, + std::move(equal_cast->left), std::move(equal_cast->right)); } return nullptr; } @@ -170725,7 +180317,7 @@ InClauseSimplificationRule::InClauseSimplificationRule(ExpressionRewriter &rewri // match on InClauseExpression that has a ConstantExpression as a check auto op = make_unique(); op->policy = SetMatcher::Policy::SOME; - root = move(op); + root = std::move(op); } unique_ptr InClauseSimplificationRule::Apply(LogicalOperator &op, vector &bindings, @@ -170757,17 +180349,17 @@ unique_ptr InClauseSimplificationRule::Apply(LogicalOperator &op, ve return nullptr; } else { auto new_constant_expr = make_unique(constant_value); - cast_list.push_back(move(new_constant_expr)); + cast_list.push_back(std::move(new_constant_expr)); } } //! We can cast, so we move the new constant for (size_t i = 1; i < expr->children.size(); i++) { - expr->children[i] = move(cast_list[i - 1]); + expr->children[i] = std::move(cast_list[i - 1]); - // expr->children[i] = move(new_constant_expr); + // expr->children[i] = std::move(new_constant_expr); } //! We can cast the full list, so we move the column - expr->children[0] = move(cast_expression->child); + expr->children[0] = std::move(cast_expression->child); return nullptr; } @@ -170790,7 +180382,7 @@ LikeOptimizationRule::LikeOptimizationRule(ExpressionRewriter &rewriter) : Rule( func->policy = SetMatcher::Policy::ORDERED; // we match on LIKE ("~~") and NOT LIKE ("!~~") func->function = make_unique(unordered_set {"!~~", "~~"}); - root = move(func); + root = std::move(func); } static bool PatternIsConstant(const string &pattern) { @@ -170897,7 +180489,7 @@ unique_ptr LikeOptimizationRule::Apply(LogicalOperator &op, vector(is_not_like ? ExpressionType::COMPARE_NOTEQUAL : ExpressionType::COMPARE_EQUAL, - move(root->children[0]), move(root->children[1])); + std::move(root->children[0]), std::move(root->children[1])); } else if (PatternIsPrefix(patt_str)) { // Prefix LIKE pattern : [^%_]*[%]+, ignoring underscore return ApplyRule(root, PrefixFun::GetFunction(), patt_str, is_not_like); @@ -170915,19 +180507,19 @@ unique_ptr LikeOptimizationRule::ApplyRule(BoundFunctionExpression * string pattern, bool is_not_like) { // replace LIKE by an optimized function unique_ptr result; - auto new_function = - make_unique(expr->return_type, move(function), move(expr->children), nullptr); + auto new_function = make_unique(expr->return_type, std::move(function), + std::move(expr->children), nullptr); // removing "%" from the pattern pattern.erase(std::remove(pattern.begin(), pattern.end(), '%'), pattern.end()); - new_function->children[1] = make_unique(Value(move(pattern))); + new_function->children[1] = make_unique(Value(std::move(pattern))); - result = move(new_function); + result = std::move(new_function); if (is_not_like) { auto negation = make_unique(ExpressionType::OPERATOR_NOT, LogicalType::BOOLEAN); - negation->children.push_back(move(result)); - result = move(negation); + negation->children.push_back(std::move(result)); + result = std::move(negation); } return result; @@ -170960,8 +180552,8 @@ MoveConstantsRule::MoveConstantsRule(ExpressionRewriter &rewriter) : Rule(rewrit arithmetic->matchers.push_back(make_unique()); arithmetic->matchers.push_back(make_unique()); arithmetic->policy = SetMatcher::Policy::SOME; - op->matchers.push_back(move(arithmetic)); - root = move(op); + op->matchers.push_back(std::move(arithmetic)); + root = std::move(op); } unique_ptr MoveConstantsRule::Apply(LogicalOperator &op, vector &bindings, bool &changes_made, @@ -170994,10 +180586,10 @@ unique_ptr MoveConstantsRule::Apply(LogicalOperator &op, vectorchildren[arithmetic_child_index]), + return ExpressionRewriter::ConstantOrNull(std::move(arithmetic->children[arithmetic_child_index]), Value::BOOLEAN(false)); } - outer_constant->value = move(result_value); + outer_constant->value = std::move(result_value); } else if (op_type == "-") { // [x - 1 COMP 10] O R [1 - x COMP 10] // order matters in subtraction: @@ -171010,10 +180602,10 @@ unique_ptr MoveConstantsRule::Apply(LogicalOperator &op, vectorchildren[arithmetic_child_index]), + return ExpressionRewriter::ConstantOrNull(std::move(arithmetic->children[arithmetic_child_index]), Value::BOOLEAN(false)); } - outer_constant->value = move(result_value); + outer_constant->value = std::move(result_value); } else { // [1 - x COMP 10] // change right side to 1-10=-9 @@ -171023,10 +180615,10 @@ unique_ptr MoveConstantsRule::Apply(LogicalOperator &op, vectorchildren[arithmetic_child_index]), + return ExpressionRewriter::ConstantOrNull(std::move(arithmetic->children[arithmetic_child_index]), Value::BOOLEAN(false)); } - outer_constant->value = move(result_value); + outer_constant->value = std::move(result_value); // in this case, we should also flip the comparison // e.g. if we have [4 - x < 2] then we should have [x > 2] comparison->type = FlipComparisionExpression(comparison->type); @@ -171050,7 +180642,7 @@ unique_ptr MoveConstantsRule::Apply(LogicalOperator &op, vectorchildren[arithmetic_child_index]), + return ExpressionRewriter::ConstantOrNull(std::move(arithmetic->children[arithmetic_child_index]), Value::BOOLEAN(is_inequality)); } else { // not cleanly divisible and we are doing > >= < <=, skip the simplification for now @@ -171066,19 +180658,19 @@ unique_ptr MoveConstantsRule::Apply(LogicalOperator &op, vectorchildren[arithmetic_child_index]), + return ExpressionRewriter::ConstantOrNull(std::move(arithmetic->children[arithmetic_child_index]), Value::BOOLEAN(false)); } - outer_constant->value = move(result_value); + outer_constant->value = std::move(result_value); } // replace left side with x // first extract x from the arithmetic expression - auto arithmetic_child = move(arithmetic->children[arithmetic_child_index]); + auto arithmetic_child = std::move(arithmetic->children[arithmetic_child_index]); // then place in the comparison if (comparison->left.get() == outer_constant) { - comparison->right = move(arithmetic_child); + comparison->right = std::move(arithmetic_child); } else { - comparison->left = move(arithmetic_child); + comparison->left = std::move(arithmetic_child); } changes_made = true; return nullptr; @@ -171991,7 +181583,7 @@ RegexOptimizationRule::RegexOptimizationRule(ExpressionRewriter &rewriter) : Rul func->policy = SetMatcher::Policy::ORDERED; func->matchers.push_back(make_unique()); func->matchers.push_back(make_unique()); - root = move(func); + root = std::move(func); } unique_ptr RegexOptimizationRule::Apply(LogicalOperator &op, vector &bindings, @@ -172021,10 +181613,10 @@ unique_ptr RegexOptimizationRule::Apply(LogicalOperator &op, vector< if (pattern.Regexp()->op() == duckdb_re2::kRegexpLiteralString || pattern.Regexp()->op() == duckdb_re2::kRegexpLiteral) { auto contains = make_unique(root->return_type, ContainsFun::GetFunction(), - move(root->children), nullptr); + std::move(root->children), nullptr); contains->children[1] = make_unique(Value(patt_str)); - return move(contains); + return std::move(contains); } return nullptr; } @@ -172124,13 +181716,13 @@ unique_ptr TemplatedCastToSmallestType(unique_ptr expr, auto input_type = expr->return_type; auto minimum_expr = make_unique(Value::CreateValue(signed_min_val)); vector> arguments; - arguments.push_back(move(expr)); - arguments.push_back(move(minimum_expr)); + arguments.push_back(std::move(expr)); + arguments.push_back(std::move(minimum_expr)); auto minus_expr = make_unique(input_type, SubtractFun::GetFunction(input_type, input_type), - move(arguments), nullptr, true); + std::move(arguments), nullptr, true); // Cast to smaller type - return BoundCastExpression::AddDefaultCastToType(move(minus_expr), cast_type); + return BoundCastExpression::AddDefaultCastToType(std::move(minus_expr), cast_type); } unique_ptr CastToSmallestType(unique_ptr expr, NumericStatistics &num_stats) { @@ -172140,19 +181732,19 @@ unique_ptr CastToSmallestType(unique_ptr expr, NumericSt case PhysicalType::INT8: return expr; case PhysicalType::UINT16: - return TemplatedCastToSmallestType(move(expr), num_stats); + return TemplatedCastToSmallestType(std::move(expr), num_stats); case PhysicalType::INT16: - return TemplatedCastToSmallestType(move(expr), num_stats); + return TemplatedCastToSmallestType(std::move(expr), num_stats); case PhysicalType::UINT32: - return TemplatedCastToSmallestType(move(expr), num_stats); + return TemplatedCastToSmallestType(std::move(expr), num_stats); case PhysicalType::INT32: - return TemplatedCastToSmallestType(move(expr), num_stats); + return TemplatedCastToSmallestType(std::move(expr), num_stats); case PhysicalType::UINT64: - return TemplatedCastToSmallestType(move(expr), num_stats); + return TemplatedCastToSmallestType(std::move(expr), num_stats); case PhysicalType::INT64: - return TemplatedCastToSmallestType(move(expr), num_stats); + return TemplatedCastToSmallestType(std::move(expr), num_stats); case PhysicalType::INT128: - return TemplatedCastToSmallestType(move(expr), num_stats); + return TemplatedCastToSmallestType(std::move(expr), num_stats); default: throw NotImplementedException("Unknown integer type!"); } @@ -172162,7 +181754,7 @@ void StatisticsPropagator::PropagateAndCompress(unique_ptr &expr, un stats = PropagateExpression(expr); if (stats) { if (expr->return_type.IsIntegral()) { - expr = CastToSmallestType(move(expr), (NumericStatistics &)*stats); + expr = CastToSmallestType(std::move(expr), (NumericStatistics &)*stats); } } } @@ -172208,24 +181800,26 @@ unique_ptr StatisticsPropagator::PropagateExpression(BoundBetwee upper_prune == FilterPropagateResult::FILTER_FALSE_OR_NULL) { // either one of the filters is false or null: replace with a constant or null (false) vector> children; - children.push_back(move(between.input)); - children.push_back(move(between.lower)); - children.push_back(move(between.upper)); - *expr_ptr = ExpressionRewriter::ConstantOrNull(move(children), Value::BOOLEAN(false)); + children.push_back(std::move(between.input)); + children.push_back(std::move(between.lower)); + children.push_back(std::move(between.upper)); + *expr_ptr = ExpressionRewriter::ConstantOrNull(std::move(children), Value::BOOLEAN(false)); } else if (lower_prune == FilterPropagateResult::FILTER_TRUE_OR_NULL && upper_prune == FilterPropagateResult::FILTER_TRUE_OR_NULL) { // both filters are true or null: replace with a true or null vector> children; - children.push_back(move(between.input)); - children.push_back(move(between.lower)); - children.push_back(move(between.upper)); - *expr_ptr = ExpressionRewriter::ConstantOrNull(move(children), Value::BOOLEAN(true)); + children.push_back(std::move(between.input)); + children.push_back(std::move(between.lower)); + children.push_back(std::move(between.upper)); + *expr_ptr = ExpressionRewriter::ConstantOrNull(std::move(children), Value::BOOLEAN(true)); } else if (lower_prune == FilterPropagateResult::FILTER_ALWAYS_TRUE) { // lower filter is always true: replace with upper comparison - *expr_ptr = make_unique(upper_comparison, move(between.input), move(between.upper)); + *expr_ptr = make_unique(upper_comparison, std::move(between.input), + std::move(between.upper)); } else if (upper_prune == FilterPropagateResult::FILTER_ALWAYS_TRUE) { // upper filter is always true: replace with lower comparison - *expr_ptr = make_unique(lower_comparison, move(between.input), move(between.lower)); + *expr_ptr = make_unique(lower_comparison, std::move(between.input), + std::move(between.lower)); } return nullptr; } @@ -172268,9 +181862,9 @@ static unique_ptr StatisticsOperationsNumericNumericCast(const B // overflow in cast: bailout return nullptr; } - auto stats = make_unique(target, move(min), move(max), input.stats_type); + auto stats = make_unique(target, std::move(min), std::move(max), input.stats_type); stats->CopyBase(*input_p); - return move(stats); + return std::move(stats); } static unique_ptr StatisticsNumericCastSwitch(const BaseStatistics *input, const LogicalType &target) { @@ -172442,16 +182036,16 @@ unique_ptr StatisticsPropagator::PropagateExpression(BoundCompar return PropagateExpression(*expr_ptr); case FilterPropagateResult::FILTER_TRUE_OR_NULL: { vector> children; - children.push_back(move(expr.left)); - children.push_back(move(expr.right)); - *expr_ptr = ExpressionRewriter::ConstantOrNull(move(children), Value::BOOLEAN(true)); + children.push_back(std::move(expr.left)); + children.push_back(std::move(expr.right)); + *expr_ptr = ExpressionRewriter::ConstantOrNull(std::move(children), Value::BOOLEAN(true)); return nullptr; } case FilterPropagateResult::FILTER_FALSE_OR_NULL: { vector> children; - children.push_back(move(expr.left)); - children.push_back(move(expr.right)); - *expr_ptr = ExpressionRewriter::ConstantOrNull(move(children), Value::BOOLEAN(false)); + children.push_back(std::move(expr.left)); + children.push_back(std::move(expr.right)); + *expr_ptr = ExpressionRewriter::ConstantOrNull(std::move(children), Value::BOOLEAN(false)); return nullptr; } default: @@ -172523,7 +182117,7 @@ unique_ptr StatisticsPropagator::PropagateExpression(BoundConjun return PropagateExpression(*expr_ptr); } else if (expr.children.size() == 1) { // if there is one child left, replace the conjunction with that one child - *expr_ptr = move(expr.children[0]); + *expr_ptr = std::move(expr.children[0]); } return nullptr; } @@ -172562,7 +182156,7 @@ unique_ptr StatisticsPropagator::StatisticsFromValue(const Value auto result = make_unique(input.type(), input, input, StatisticsType::GLOBAL_STATS); result->validity_stats = make_unique(input.IsNull(), !input.IsNull()); UpdateDistinctStats(*result->distinct_stats, input); - return move(result); + return std::move(result); } case PhysicalType::VARCHAR: { auto result = make_unique(input.type(), StatisticsType::GLOBAL_STATS); @@ -172572,7 +182166,7 @@ unique_ptr StatisticsPropagator::StatisticsFromValue(const Value auto &string_value = StringValue::Get(input); result->Update(string_t(string_value)); } - return move(result); + return std::move(result); } case PhysicalType::STRUCT: { auto result = make_unique(input.type()); @@ -172588,7 +182182,7 @@ unique_ptr StatisticsPropagator::StatisticsFromValue(const Value result->child_stats[i] = StatisticsFromValue(struct_children[i]); } } - return move(result); + return std::move(result); } case PhysicalType::LIST: { auto result = make_unique(input.type()); @@ -172606,7 +182200,7 @@ unique_ptr StatisticsPropagator::StatisticsFromValue(const Value } } } - return move(result); + return std::move(result); } default: return nullptr; @@ -172655,7 +182249,7 @@ unique_ptr StatisticsPropagator::PropagateExpression(BoundOperat if (!stats) { all_have_stats = false; } - child_stats.push_back(move(stats)); + child_stats.push_back(std::move(stats)); } if (!all_have_stats) { return nullptr; @@ -172688,7 +182282,7 @@ unique_ptr StatisticsPropagator::PropagateExpression(BoundOperat D_ASSERT(expr.children.size() == child_stats.size()); if (expr.children.size() == 1) { // coalesce of one entry: simply return that entry - *expr_ptr = move(expr.children[0]); + *expr_ptr = std::move(expr.children[0]); } else { // coalesce of multiple entries // merge the stats @@ -172696,7 +182290,7 @@ unique_ptr StatisticsPropagator::PropagateExpression(BoundOperat child_stats[0]->Merge(*child_stats[i]); } } - return move(child_stats[0]); + return std::move(child_stats[0]); case ExpressionType::OPERATOR_IS_NULL: if (!child_stats[0]->CanHaveNull()) { // child has no null values: x IS NULL will always be false @@ -172743,7 +182337,7 @@ unique_ptr StatisticsPropagator::PropagateStatistics(LogicalAggr continue; } ColumnBinding group_binding(aggr.group_index, group_idx); - statistics_map[group_binding] = move(stats); + statistics_map[group_binding] = std::move(stats); } // propagate statistics in the aggregates for (idx_t aggregate_idx = 0; aggregate_idx < aggr.expressions.size(); aggregate_idx++) { @@ -172752,10 +182346,10 @@ unique_ptr StatisticsPropagator::PropagateStatistics(LogicalAggr continue; } ColumnBinding aggregate_binding(aggr.aggregate_index, aggregate_idx); - statistics_map[aggregate_binding] = move(stats); + statistics_map[aggregate_binding] = std::move(stats); } // the max cardinality of an aggregate is the max cardinality of the input (i.e. when every row is a unique group) - return move(node_stats); + return std::move(node_stats); } } // namespace duckdb @@ -173016,7 +182610,7 @@ unique_ptr StatisticsPropagator::PropagateStatistics(LogicalFilt i--; if (filter.expressions.empty()) { // all conditions have been erased: remove the entire filter - *node_ptr = move(filter.children[0]); + *node_ptr = std::move(filter.children[0]); break; } } else if (ExpressionIsConstant(*condition, Value::BOOLEAN(false)) || @@ -173030,7 +182624,7 @@ unique_ptr StatisticsPropagator::PropagateStatistics(LogicalFilt } } // the max cardinality of a filter is the cardinality of the input (i.e. no tuples get filtered) - return move(node_stats); + return std::move(node_stats); } } // namespace duckdb @@ -173073,13 +182667,13 @@ unique_ptr StatisticsPropagator::PropagateStatistics(LogicalGet } if (!get.function.statistics) { // no column statistics to get - return move(node_stats); + return std::move(node_stats); } for (idx_t i = 0; i < get.column_ids.size(); i++) { auto stats = get.function.statistics(context, get.bind_data.get(), get.column_ids[i]); if (stats) { ColumnBinding binding(get.table_index, i); - statistics_map.insert(make_pair(binding, move(stats))); + statistics_map.insert(make_pair(binding, std::move(stats))); } } // push table filters into the statistics @@ -173129,7 +182723,7 @@ unique_ptr StatisticsPropagator::PropagateStatistics(LogicalGet break; } } - return move(node_stats); + return std::move(node_stats); } } // namespace duckdb @@ -173143,6 +182737,7 @@ unique_ptr StatisticsPropagator::PropagateStatistics(LogicalGet + namespace duckdb { void StatisticsPropagator::PropagateStatistics(LogicalComparisonJoin &join, unique_ptr *node_ptr) { @@ -173160,8 +182755,8 @@ void StatisticsPropagator::PropagateStatistics(LogicalComparisonJoin &join, uniq } auto prune_result = PropagateComparison(*stats_left, *stats_right, condition.comparison); // Add stats to logical_join for perfect hash join - join.join_stats.push_back(move(stats_left)); - join.join_stats.push_back(move(stats_right)); + join.join_stats.push_back(std::move(stats_left)); + join.join_stats.push_back(std::move(stats_right)); switch (prune_result) { case FilterPropagateResult::FILTER_FALSE_OR_NULL: case FilterPropagateResult::FILTER_ALWAYS_FALSE: @@ -173176,9 +182771,9 @@ void StatisticsPropagator::PropagateStatistics(LogicalComparisonJoin &join, uniq // when the right child has data, return the left child // when the right child has no data, return an empty set auto limit = make_unique(1, 0, nullptr, nullptr); - limit->AddChild(move(join.children[1])); - auto cross_product = LogicalCrossProduct::Create(move(join.children[0]), move(limit)); - *node_ptr = move(cross_product); + limit->AddChild(std::move(join.children[1])); + auto cross_product = LogicalCrossProduct::Create(std::move(join.children[0]), std::move(limit)); + *node_ptr = std::move(cross_product); return; } case JoinType::LEFT: @@ -173212,9 +182807,9 @@ void StatisticsPropagator::PropagateStatistics(LogicalComparisonJoin &join, uniq // when the right child has data, return the left child // when the right child has no data, return an empty set auto limit = make_unique(1, 0, nullptr, nullptr); - limit->AddChild(move(join.children[1])); - auto cross_product = LogicalCrossProduct::Create(move(join.children[0]), move(limit)); - *node_ptr = move(cross_product); + limit->AddChild(std::move(join.children[1])); + auto cross_product = LogicalCrossProduct::Create(std::move(join.children[0]), std::move(limit)); + *node_ptr = std::move(cross_product); return; } case JoinType::INNER: @@ -173224,8 +182819,8 @@ void StatisticsPropagator::PropagateStatistics(LogicalComparisonJoin &join, uniq // inner/left/right/full outer join, replace with cross product // since the condition is always true, left/right/outer join are equivalent to inner join here auto cross_product = - LogicalCrossProduct::Create(move(join.children[0]), move(join.children[1])); - *node_ptr = move(cross_product); + LogicalCrossProduct::Create(std::move(join.children[0]), std::move(join.children[1])); + *node_ptr = std::move(cross_product); return; } case JoinType::ANTI: @@ -173266,8 +182861,8 @@ void StatisticsPropagator::PropagateStatistics(LogicalComparisonJoin &join, uniq auto stats_right = PropagateExpression(condition.right); // Update join_stats when is already part of the join if (join.join_stats.size() == 2) { - join.join_stats[0] = move(stats_left); - join.join_stats[1] = move(stats_right); + join.join_stats[0] = std::move(stats_left); + join.join_stats[1] = std::move(stats_right); } break; } @@ -173361,7 +182956,62 @@ unique_ptr StatisticsPropagator::PropagateStatistics(LogicalJoin } } } - return move(node_stats); + return std::move(node_stats); +} + +static void MaxCardinalities(unique_ptr &stats, NodeStatistics &new_stats) { + if (!stats->has_estimated_cardinality || !new_stats.has_estimated_cardinality || !stats->has_max_cardinality || + !new_stats.has_max_cardinality) { + stats = nullptr; + return; + } + stats->estimated_cardinality = MaxValue(stats->estimated_cardinality, new_stats.estimated_cardinality); + stats->max_cardinality = MaxValue(stats->max_cardinality, new_stats.max_cardinality); +} + +unique_ptr StatisticsPropagator::PropagateStatistics(LogicalPositionalJoin &join, + unique_ptr *node_ptr) { + D_ASSERT(join.type == LogicalOperatorType::LOGICAL_POSITIONAL_JOIN); + + // first propagate through the children of the join + node_stats = PropagateStatistics(join.children[0]); + for (idx_t child_idx = 1; child_idx < join.children.size(); child_idx++) { + auto child_stats = PropagateStatistics(join.children[child_idx]); + if (!child_stats) { + node_stats = nullptr; + } else if (node_stats) { + if (!node_stats->has_estimated_cardinality || !child_stats->has_estimated_cardinality || + !node_stats->has_max_cardinality || !child_stats->has_max_cardinality) { + node_stats = nullptr; + } else { + MaxCardinalities(node_stats, *child_stats); + } + } + } + + // No conditions. + + // Positional Joins are always FULL OUTER + + // set IsNull() to true for all lhs statistics + auto left_bindings = join.children[0]->GetColumnBindings(); + for (auto &binding : left_bindings) { + auto stats = statistics_map.find(binding); + if (stats != statistics_map.end()) { + stats->second->validity_stats = make_unique(true); + } + } + + // set IsNull() to true for all rhs statistics + auto right_bindings = join.children[1]->GetColumnBindings(); + for (auto &binding : right_bindings) { + auto stats = statistics_map.find(binding); + if (stats != statistics_map.end()) { + stats->second->validity_stats = make_unique(true); + } + } + + return std::move(node_stats); } } // namespace duckdb @@ -173394,7 +183044,7 @@ unique_ptr StatisticsPropagator::PropagateStatistics(LogicalOrde for (auto &bound_order : order.orders) { PropagateAndCompress(bound_order.expression, bound_order.stats); } - return move(node_stats); + return std::move(node_stats); } } // namespace duckdb @@ -173409,7 +183059,7 @@ unique_ptr StatisticsPropagator::PropagateStatistics(LogicalProj node_stats = PropagateStatistics(proj.children[0]); if (proj.children[0]->type == LogicalOperatorType::LOGICAL_EMPTY_RESULT) { ReplaceWithEmptyResult(*node_ptr); - return move(node_stats); + return std::move(node_stats); } // then propagate to each of the expressions @@ -173417,10 +183067,10 @@ unique_ptr StatisticsPropagator::PropagateStatistics(LogicalProj auto stats = PropagateExpression(proj.expressions[i]); if (stats) { ColumnBinding binding(proj.table_index, i); - statistics_map.insert(make_pair(binding, move(stats))); + statistics_map.insert(make_pair(binding, std::move(stats))); } } - return move(node_stats); + return std::move(node_stats); } } // namespace duckdb @@ -173490,7 +183140,7 @@ unique_ptr StatisticsPropagator::PropagateStatistics(LogicalSetO throw InternalException("Unsupported setop type"); } ColumnBinding binding(setop.table_index, i); - statistics_map[binding] = move(new_stats); + statistics_map[binding] = std::move(new_stats); } if (!left_stats || !right_stats) { return nullptr; @@ -173523,7 +183173,7 @@ unique_ptr StatisticsPropagator::PropagateStatistics(LogicalWind bound_order.stats = PropagateExpression(bound_order.expression); } } - return move(node_stats); + return std::move(node_stats); } } // namespace duckdb @@ -173540,7 +183190,7 @@ StatisticsPropagator::StatisticsPropagator(ClientContext &context) : context(con } void StatisticsPropagator::ReplaceWithEmptyResult(unique_ptr &node) { - node = make_unique(move(node)); + node = make_unique(std::move(node)); } unique_ptr StatisticsPropagator::PropagateChildren(LogicalOperator &node, @@ -173569,6 +183219,8 @@ unique_ptr StatisticsPropagator::PropagateStatistics(LogicalOper case LogicalOperatorType::LOGICAL_JOIN: case LogicalOperatorType::LOGICAL_DELIM_JOIN: return PropagateStatistics((LogicalJoin &)node, node_ptr); + case LogicalOperatorType::LOGICAL_POSITIONAL_JOIN: + return PropagateStatistics((LogicalPositionalJoin &)node, node_ptr); case LogicalOperatorType::LOGICAL_UNION: case LogicalOperatorType::LOGICAL_EXCEPT: case LogicalOperatorType::LOGICAL_INTERSECT: @@ -173642,25 +183294,337 @@ unique_ptr TopN::Optimize(unique_ptr op) { // This optimization doesn't apply when OFFSET is present without LIMIT // Or if offset is not constant if (limit.limit_val != NumericLimits::Maximum() || limit.offset) { - auto topn = make_unique(move(order_by.orders), limit.limit_val, limit.offset_val); - topn->AddChild(move(order_by.children[0])); - op = move(topn); + auto topn = make_unique(std::move(order_by.orders), limit.limit_val, limit.offset_val); + topn->AddChild(std::move(order_by.children[0])); + op = std::move(topn); } } else { for (auto &child : op->children) { - child = Optimize(move(child)); + child = Optimize(std::move(child)); + } + } + return op; +} + +} // namespace duckdb + + + + + + + + + + + +namespace duckdb { + +void UnnestRewriterPlanUpdater::VisitOperator(LogicalOperator &op) { + VisitOperatorChildren(op); + VisitOperatorExpressions(op); +} + +void UnnestRewriterPlanUpdater::VisitExpression(unique_ptr *expression) { + + auto &expr = *expression; + + if (expr->expression_class == ExpressionClass::BOUND_COLUMN_REF) { + + auto &bound_column_ref = (BoundColumnRefExpression &)*expr; + for (idx_t i = 0; i < replace_bindings.size(); i++) { + if (bound_column_ref.binding == replace_bindings[i].old_binding) { + bound_column_ref.binding = replace_bindings[i].new_binding; + } + // previously pointing to the LOGICAL_DELIM_GET + if (bound_column_ref.binding.table_index == replace_bindings[i].old_binding.table_index && + replace_bindings[i].old_binding.column_index == DConstants::INVALID_INDEX) { + bound_column_ref.binding = replace_bindings[i].new_binding; + } } } + + VisitExpressionChildren(**expression); +} + +unique_ptr UnnestRewriter::Optimize(unique_ptr op) { + + UnnestRewriterPlanUpdater updater; + vector *> candidates; + FindCandidates(&op, candidates); + + // rewrite the plan and update the bindings + for (auto &candidate : candidates) { + + // rearrange the logical operators + if (RewriteCandidate(candidate)) { + // update the bindings of the BOUND_UNNEST expression + UpdateBoundUnnestBindings(updater, candidate); + // update the sequence of LOGICAL_PROJECTION(s) + UpdateRHSBindings(&op, candidate, updater); + // reset + delim_columns.clear(); + lhs_bindings.clear(); + } + } + return op; } +void UnnestRewriter::FindCandidates(unique_ptr *op_ptr, + vector *> &candidates) { + auto op = op_ptr->get(); + // search children before adding, so that we add candidates bottom-up + for (auto &child : op->children) { + FindCandidates(&child, candidates); + } + + // search for operator that has a LOGICAL_DELIM_JOIN as its child + if (op->children.size() != 1) { + return; + } + if (op->children[0]->type != LogicalOperatorType::LOGICAL_DELIM_JOIN) { + return; + } + + // found a delim join + auto &delim_join = (LogicalDelimJoin &)*op->children[0]; + // only support INNER delim joins + if (delim_join.join_type != JoinType::INNER) { + return; + } + // INNER delim join must have exactly one condition + if (delim_join.conditions.size() != 1) { + return; + } + + // LHS child is a window + if (delim_join.children[0]->type != LogicalOperatorType::LOGICAL_WINDOW) { + return; + } + + // RHS child must be projection(s) followed by an UNNEST + auto curr_op = &delim_join.children[1]; + while (curr_op->get()->type == LogicalOperatorType::LOGICAL_PROJECTION) { + if (curr_op->get()->children.size() != 1) { + break; + } + curr_op = &curr_op->get()->children[0]; + } + + if (curr_op->get()->type == LogicalOperatorType::LOGICAL_UNNEST) { + candidates.push_back(op_ptr); + } + return; +} + +bool UnnestRewriter::RewriteCandidate(unique_ptr *candidate) { + + auto &topmost_op = (LogicalOperator &)**candidate; + if (topmost_op.type != LogicalOperatorType::LOGICAL_PROJECTION && + topmost_op.type != LogicalOperatorType::LOGICAL_WINDOW && + topmost_op.type != LogicalOperatorType::LOGICAL_FILTER && + topmost_op.type != LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY && + topmost_op.type != LogicalOperatorType::LOGICAL_UNNEST) { + return false; + } + + // get the LOGICAL_DELIM_JOIN, which is a child of the candidate + D_ASSERT(topmost_op.children.size() == 1); + auto &delim_join = *(topmost_op.children[0]); + D_ASSERT(delim_join.type == LogicalOperatorType::LOGICAL_DELIM_JOIN); + GetDelimColumns(delim_join); + + // LHS of the LOGICAL_DELIM_JOIN is a LOGICAL_WINDOW that contains a LOGICAL_PROJECTION + // this lhs_proj later becomes the child of the UNNEST + auto &window = *delim_join.children[0]; + auto &lhs_op = window.children[0]; + GetLHSExpressions(*lhs_op); + + // find the LOGICAL_UNNEST + // and get the path down to the LOGICAL_UNNEST + vector *> path_to_unnest; + auto curr_op = &(delim_join.children[1]); + while (curr_op->get()->type == LogicalOperatorType::LOGICAL_PROJECTION) { + path_to_unnest.push_back(curr_op); + curr_op = &curr_op->get()->children[0]; + } + + // store the table index of the child of the LOGICAL_UNNEST + // then update the plan by making the lhs_proj the child of the LOGICAL_UNNEST + D_ASSERT(curr_op->get()->type == LogicalOperatorType::LOGICAL_UNNEST); + auto &unnest = (LogicalUnnest &)*curr_op->get(); + D_ASSERT(unnest.children[0]->type == LogicalOperatorType::LOGICAL_DELIM_GET); + overwritten_tbl_idx = ((LogicalDelimGet &)*unnest.children[0]).table_index; + unnest.children[0] = std::move(lhs_op); + + // replace the LOGICAL_DELIM_JOIN with its RHS child operator + topmost_op.children[0] = std::move(*path_to_unnest.front()); + return true; +} + +void UnnestRewriter::UpdateRHSBindings(unique_ptr *plan_ptr, unique_ptr *candidate, + UnnestRewriterPlanUpdater &updater) { + + auto &topmost_op = (LogicalOperator &)**candidate; + idx_t shift = lhs_bindings.size(); + + vector *> path_to_unnest; + auto curr_op = &(topmost_op.children[0]); + while (curr_op->get()->type == LogicalOperatorType::LOGICAL_PROJECTION) { + + path_to_unnest.push_back(curr_op); + D_ASSERT(curr_op->get()->type == LogicalOperatorType::LOGICAL_PROJECTION); + auto &proj = (LogicalProjection &)*curr_op->get(); + + // pop the two last expressions from all projections (delim_idx and UNNEST column) + D_ASSERT(proj.expressions.size() > 2); + proj.expressions.pop_back(); + proj.expressions.pop_back(); + + // store all shifted current bindings + idx_t tbl_idx = proj.table_index; + for (idx_t i = 0; i < proj.expressions.size(); i++) { + ReplaceBinding replace_binding(ColumnBinding(tbl_idx, i), ColumnBinding(tbl_idx, i + shift)); + updater.replace_bindings.push_back(replace_binding); + } + + curr_op = &curr_op->get()->children[0]; + } + + // update all bindings by shifting them + updater.VisitOperator(*plan_ptr->get()); + updater.replace_bindings.clear(); + + // update all bindings coming from the LHS to RHS bindings + D_ASSERT(topmost_op.children[0]->type == LogicalOperatorType::LOGICAL_PROJECTION); + auto &top_proj = (LogicalProjection &)*topmost_op.children[0]; + for (idx_t i = 0; i < lhs_bindings.size(); i++) { + ReplaceBinding replace_binding(lhs_bindings[i].binding, ColumnBinding(top_proj.table_index, i)); + updater.replace_bindings.push_back(replace_binding); + } + + // temporarily remove the BOUND_UNNEST and the child of the LOGICAL_UNNEST from the plan + D_ASSERT(curr_op->get()->type == LogicalOperatorType::LOGICAL_UNNEST); + auto &unnest = (LogicalUnnest &)*curr_op->get(); + auto temp_bound_unnest = std::move(unnest.expressions[0]); + auto temp_unnest_child = std::move(unnest.children[0]); + unnest.expressions.clear(); + unnest.children.clear(); + // update the bindings of the plan + updater.VisitOperator(*plan_ptr->get()); + updater.replace_bindings.clear(); + // add the child again + unnest.expressions.push_back(std::move(temp_bound_unnest)); + unnest.children.push_back(std::move(temp_unnest_child)); + + // add the LHS expressions to each LOGICAL_PROJECTION + for (idx_t i = path_to_unnest.size(); i > 0; i--) { + + D_ASSERT(path_to_unnest[i - 1]->get()->type == LogicalOperatorType::LOGICAL_PROJECTION); + auto &proj = (LogicalProjection &)*path_to_unnest[i - 1]->get(); + + // temporarily store the existing expressions + vector> existing_expressions; + for (idx_t expr_idx = 0; expr_idx < proj.expressions.size(); expr_idx++) { + existing_expressions.push_back(std::move(proj.expressions[expr_idx])); + } + + proj.expressions.clear(); + + // add the new expressions + for (idx_t expr_idx = 0; expr_idx < lhs_bindings.size(); expr_idx++) { + auto new_expr = make_unique( + lhs_bindings[expr_idx].alias, lhs_bindings[expr_idx].type, lhs_bindings[expr_idx].binding); + proj.expressions.push_back(std::move(new_expr)); + + // update the table index + lhs_bindings[expr_idx].binding.table_index = proj.table_index; + lhs_bindings[expr_idx].binding.column_index = expr_idx; + } + + // add the existing expressions again + for (idx_t expr_idx = 0; expr_idx < existing_expressions.size(); expr_idx++) { + proj.expressions.push_back(std::move(existing_expressions[expr_idx])); + } + } +} + +void UnnestRewriter::UpdateBoundUnnestBindings(UnnestRewriterPlanUpdater &updater, + unique_ptr *candidate) { + + auto &topmost_op = (LogicalOperator &)**candidate; + + // traverse LOGICAL_PROJECTION(s) + auto curr_op = &(topmost_op.children[0]); + while (curr_op->get()->type == LogicalOperatorType::LOGICAL_PROJECTION) { + curr_op = &curr_op->get()->children[0]; + } + + // found the LOGICAL_UNNEST + D_ASSERT(curr_op->get()->type == LogicalOperatorType::LOGICAL_UNNEST); + auto &unnest = (LogicalUnnest &)*curr_op->get(); + + auto unnest_child_cols = unnest.children[0]->GetColumnBindings(); + for (idx_t delim_col_idx = 0; delim_col_idx < delim_columns.size(); delim_col_idx++) { + for (idx_t child_col_idx = 0; child_col_idx < unnest_child_cols.size(); child_col_idx++) { + if (delim_columns[delim_col_idx].table_index == unnest_child_cols[child_col_idx].table_index) { + ColumnBinding old_binding(overwritten_tbl_idx, DConstants::INVALID_INDEX); + updater.replace_bindings.emplace_back(ReplaceBinding(old_binding, delim_columns[delim_col_idx])); + break; + } + } + } + + // update bindings + D_ASSERT(unnest.expressions.size() == 1); + updater.VisitExpression(&unnest.expressions[0]); + updater.replace_bindings.clear(); +} + +void UnnestRewriter::GetDelimColumns(LogicalOperator &op) { + + D_ASSERT(op.type == LogicalOperatorType::LOGICAL_DELIM_JOIN); + auto &delim_join = (LogicalDelimJoin &)op; + for (idx_t i = 0; i < delim_join.duplicate_eliminated_columns.size(); i++) { + auto &expr = *delim_join.duplicate_eliminated_columns[i]; + D_ASSERT(expr.type == ExpressionType::BOUND_COLUMN_REF); + auto &bound_colref_expr = (BoundColumnRefExpression &)expr; + delim_columns.push_back(bound_colref_expr.binding); + } +} + +void UnnestRewriter::GetLHSExpressions(LogicalOperator &op) { + + op.ResolveOperatorTypes(); + auto col_bindings = op.GetColumnBindings(); + D_ASSERT(op.types.size() == col_bindings.size()); + + bool set_alias = false; + // we can easily extract the alias for LOGICAL_PROJECTION(s) + if (op.type == LogicalOperatorType::LOGICAL_PROJECTION) { + auto &proj = (LogicalProjection &)op; + if (proj.expressions.size() == op.types.size()) { + set_alias = true; + } + } + + for (idx_t i = 0; i < op.types.size(); i++) { + lhs_bindings.emplace_back(LHSBinding(col_bindings[i], op.types[i])); + if (set_alias) { + auto &proj = (LogicalProjection &)op; + lhs_bindings.back().alias = proj.expressions[i]->alias; + } + } +} + } // namespace duckdb namespace duckdb { BasePipelineEvent::BasePipelineEvent(shared_ptr pipeline_p) - : Event(pipeline_p->executor), pipeline(move(pipeline_p)) { + : Event(pipeline_p->executor), pipeline(std::move(pipeline_p)) { } BasePipelineEvent::BasePipelineEvent(Pipeline &pipeline_p) @@ -173734,12 +183698,12 @@ void Event::FinishTask() { } void Event::InsertEvent(shared_ptr replacement_event) { - replacement_event->parents = move(parents); + replacement_event->parents = std::move(parents); #ifdef DEBUG - replacement_event->parents_raw = move(parents_raw); + replacement_event->parents_raw = std::move(parents_raw); #endif replacement_event->AddDependency(*this); - executor.AddEvent(move(replacement_event)); + executor.AddEvent(std::move(replacement_event)); } void Event::SetTasks(vector> tasks) { @@ -173748,7 +183712,7 @@ void Event::SetTasks(vector> tasks) { D_ASSERT(!tasks.empty()); this->total_tasks = tasks.size(); for (auto &task : tasks) { - ts.ScheduleTask(executor.GetToken(), move(task)); + ts.ScheduleTask(executor.GetToken(), std::move(task)); } } @@ -174005,7 +183969,7 @@ void Executor::AddEvent(shared_ptr event) { if (cancelled) { return; } - events.push_back(move(event)); + events.push_back(std::move(event)); } struct PipelineEventStack { @@ -174042,10 +184006,10 @@ void Executor::SchedulePipeline(const shared_ptr &meta_pipeline, S auto base_complete_event = make_shared(base_pipeline->executor, event_data.initial_schedule); PipelineEventStack base_stack {base_initialize_event.get(), base_event.get(), base_finish_event.get(), base_complete_event.get()}; - events.push_back(move(base_initialize_event)); - events.push_back(move(base_event)); - events.push_back(move(base_finish_event)); - events.push_back(move(base_complete_event)); + events.push_back(std::move(base_initialize_event)); + events.push_back(std::move(base_event)); + events.push_back(std::move(base_finish_event)); + events.push_back(std::move(base_complete_event)); // dependencies: initialize -> event -> finish -> complete base_stack.pipeline_event->AddDependency(*base_stack.pipeline_initialize_event); @@ -174066,14 +184030,14 @@ void Executor::SchedulePipeline(const shared_ptr &meta_pipeline, S // this pipeline has its own finish event (despite going into the same sink - Finalize twice!) auto pipeline_finish_event = make_unique(pipeline); pipeline_finish_event_ptr = pipeline_finish_event.get(); - events.push_back(move(pipeline_finish_event)); + events.push_back(std::move(pipeline_finish_event)); base_stack.pipeline_complete_event->AddDependency(*pipeline_finish_event_ptr); } else { pipeline_finish_event_ptr = base_stack.pipeline_finish_event; } PipelineEventStack pipeline_stack {base_stack.pipeline_initialize_event, pipeline_event.get(), pipeline_finish_event_ptr, base_stack.pipeline_complete_event}; - events.push_back(move(pipeline_event)); + events.push_back(std::move(pipeline_event)); // dependencies: base_initialize -> pipeline_event -> base_finish pipeline_stack.pipeline_event->AddDependency(*base_stack.pipeline_initialize_event); @@ -174251,7 +184215,7 @@ void Executor::VerifyPipelines() { void Executor::Initialize(unique_ptr physical_plan) { Reset(); - owned_plan = move(physical_plan); + owned_plan = std::move(physical_plan); InitializeInternal(owned_plan.get()); } @@ -174347,6 +184311,10 @@ void Executor::WorkOnTasks() { } } +bool Executor::ExecutionIsFinished() { + return completed_pipelines >= total_pipelines || HasError(); +} + PendingExecutionResult Executor::ExecuteTask() { if (execution_result != PendingExecutionResult::RESULT_NOT_READY) { return execution_result; @@ -174438,7 +184406,7 @@ void Executor::PushError(PreservedError exception) { // interrupt execution of any other pipelines that belong to this executor context.interrupted = true; // push the exception onto the stack - exceptions.push_back(move(exception)); + exceptions.push_back(std::move(exception)); } bool Executor::HasError() { @@ -174743,7 +184711,7 @@ class PipelineTask : public ExecutorTask { public: explicit PipelineTask(Pipeline &pipeline_p, shared_ptr event_p) - : ExecutorTask(pipeline_p.executor), pipeline(pipeline_p), event(move(event_p)) { + : ExecutorTask(pipeline_p.executor), pipeline(pipeline_p), event(std::move(event_p)) { } Pipeline &pipeline; @@ -174792,7 +184760,7 @@ bool Pipeline::GetProgress(double ¤t_percentage, idx_t &source_cardinality void Pipeline::ScheduleSequentialTask(shared_ptr &event) { vector> tasks; tasks.push_back(make_unique(*this, event)); - event->SetTasks(move(tasks)); + event->SetTasks(std::move(tasks)); } bool Pipeline::ScheduleParallel(shared_ptr &event) { @@ -174864,7 +184832,7 @@ bool Pipeline::LaunchScanTasks(shared_ptr &event, idx_t max_threads) { for (idx_t i = 0; i < max_threads; i++) { tasks.push_back(make_unique(*this, event)); } - event->SetTasks(move(tasks)); + event->SetTasks(std::move(tasks)); return true; } @@ -174982,7 +184950,7 @@ PhysicalOperator *PipelineBuildState::GetPipelineSink(Pipeline &pipeline) { } void PipelineBuildState::SetPipelineOperators(Pipeline &pipeline, vector operators) { - pipeline.operators = move(operators); + pipeline.operators = std::move(operators); } shared_ptr PipelineBuildState::CreateChildPipeline(Executor &executor, Pipeline &pipeline, @@ -175019,7 +184987,7 @@ void PipelineCompleteEvent::FinalizeFinish() { namespace duckdb { -PipelineEvent::PipelineEvent(shared_ptr pipeline_p) : BasePipelineEvent(move(pipeline_p)) { +PipelineEvent::PipelineEvent(shared_ptr pipeline_p) : BasePipelineEvent(std::move(pipeline_p)) { } void PipelineEvent::Schedule() { @@ -175064,7 +185032,7 @@ PipelineExecutor::PipelineExecutor(ClientContext &context_p, Pipeline &pipeline_ auto chunk = make_unique(); chunk->Initialize(Allocator::Get(context.client), prev_operator->GetTypes()); - intermediate_chunks.push_back(move(chunk)); + intermediate_chunks.push_back(std::move(chunk)); auto op_state = current_operator->GetOperatorState(context); intermediate_states.push_back(std::move(op_state)); @@ -175176,8 +185144,11 @@ void PipelineExecutor::FlushCachingOperatorsPull(DataChunk &result) { finalize_result = cached_final_execute_result; } else { // Flush the current operator - finalize_result = pipeline.operators[op_idx]->FinalExecute( - context, curr_chunk, *pipeline.operators[op_idx]->op_state, *intermediate_states[op_idx]); + auto current_operator = pipeline.operators[op_idx]; + StartOperator(current_operator); + finalize_result = current_operator->FinalExecute(context, curr_chunk, *current_operator->op_state, + *intermediate_states[op_idx]); + EndOperator(current_operator, &curr_chunk); } auto execute_result = Execute(curr_chunk, result, op_idx + 1); @@ -175214,8 +185185,11 @@ void PipelineExecutor::FlushCachingOperatorsPush() { do { auto &curr_chunk = op_idx + 1 >= intermediate_chunks.size() ? final_chunk : *intermediate_chunks[op_idx + 1]; - finalize_result = pipeline.operators[op_idx]->FinalExecute( - context, curr_chunk, *pipeline.operators[op_idx]->op_state, *intermediate_states[op_idx]); + auto current_operator = pipeline.operators[op_idx]; + StartOperator(current_operator); + finalize_result = current_operator->FinalExecute(context, curr_chunk, *current_operator->op_state, + *intermediate_states[op_idx]); + EndOperator(current_operator, &curr_chunk); push_result = ExecutePushInternal(curr_chunk, op_idx + 1); } while (finalize_result != OperatorFinalizeResultType::FINISHED && push_result != OperatorResultType::FINISHED); @@ -175438,7 +185412,7 @@ void PipelineExecutor::EndOperator(PhysicalOperator *op, DataChunk *chunk) { namespace duckdb { -PipelineFinishEvent::PipelineFinishEvent(shared_ptr pipeline_p) : BasePipelineEvent(move(pipeline_p)) { +PipelineFinishEvent::PipelineFinishEvent(shared_ptr pipeline_p) : BasePipelineEvent(std::move(pipeline_p)) { } void PipelineFinishEvent::Schedule() { @@ -175456,13 +185430,13 @@ void PipelineFinishEvent::FinishEvent() { namespace duckdb { PipelineInitializeEvent::PipelineInitializeEvent(shared_ptr pipeline_p) - : BasePipelineEvent(move(pipeline_p)) { + : BasePipelineEvent(std::move(pipeline_p)) { } class PipelineInitializeTask : public ExecutorTask { public: explicit PipelineInitializeTask(Pipeline &pipeline_p, shared_ptr event_p) - : ExecutorTask(pipeline_p.executor), pipeline(pipeline_p), event(move(event_p)) { + : ExecutorTask(pipeline_p.executor), pipeline(pipeline_p), event(std::move(event_p)) { } Pipeline &pipeline; @@ -175480,7 +185454,7 @@ void PipelineInitializeEvent::Schedule() { // needs to spawn a task to get the chain of tasks for the query plan going vector> tasks; tasks.push_back(make_unique(*pipeline, shared_from_this())); - SetTasks(move(tasks)); + SetTasks(std::move(tasks)); } void PipelineInitializeEvent::FinishEvent() { @@ -179619,7 +189593,7 @@ namespace duckdb { struct SchedulerThread { #ifndef DUCKDB_NO_THREADS - explicit SchedulerThread(unique_ptr thread_p) : internal_thread(move(thread_p)) { + explicit SchedulerThread(unique_ptr thread_p) : internal_thread(std::move(thread_p)) { } unique_ptr internal_thread; @@ -179647,7 +189621,7 @@ struct QueueProducerToken { void ConcurrentQueue::Enqueue(ProducerToken &token, unique_ptr task) { lock_guard producer_lock(token.producer_lock); - if (q.enqueue(token.token->queue_token, move(task))) { + if (q.enqueue(token.token->queue_token, std::move(task))) { semaphore.signal(); } else { throw InternalException("Could not schedule task!"); @@ -179670,7 +189644,7 @@ struct ConcurrentQueue { void ConcurrentQueue::Enqueue(ProducerToken &token, unique_ptr task) { lock_guard lock(qlock); - q.push(move(task)); + q.push(std::move(task)); } bool ConcurrentQueue::DequeueFromProducer(ProducerToken &token, unique_ptr &task) { @@ -179678,7 +189652,7 @@ bool ConcurrentQueue::DequeueFromProducer(ProducerToken &token, unique_ptr if (q.empty()) { return false; } - task = move(q.front()); + task = std::move(q.front()); q.pop(); return true; } @@ -179690,7 +189664,7 @@ struct QueueProducerToken { #endif ProducerToken::ProducerToken(TaskScheduler &scheduler, unique_ptr token) - : scheduler(scheduler), token(move(token)) { + : scheduler(scheduler), token(std::move(token)) { } ProducerToken::~ProducerToken() { @@ -179715,12 +189689,12 @@ TaskScheduler &TaskScheduler::GetScheduler(DatabaseInstance &db) { unique_ptr TaskScheduler::CreateProducer() { auto token = make_unique(*queue); - return make_unique(*this, move(token)); + return make_unique(*this, std::move(token)); } void TaskScheduler::ScheduleTask(ProducerToken &token, unique_ptr task) { // Enqueue a task for the given producer token and signal any sleeping threads - queue->Enqueue(token, move(task)); + queue->Enqueue(token, std::move(task)); } bool TaskScheduler::GetTaskFromProducer(ProducerToken &token, unique_ptr &task) { @@ -179842,10 +189816,10 @@ void TaskScheduler::SetThreadsInternal(int32_t n) { // launch a thread and assign it a cancellation marker auto marker = unique_ptr>(new atomic(true)); auto worker_thread = make_unique(ThreadExecuteTasks, this, marker.get()); - auto thread_wrapper = make_unique(move(worker_thread)); + auto thread_wrapper = make_unique(std::move(worker_thread)); - threads.push_back(move(thread_wrapper)); - markers.push_back(move(marker)); + threads.push_back(std::move(thread_wrapper)); + markers.push_back(std::move(marker)); } } #endif @@ -179925,7 +189899,7 @@ class CastExpression : public ParsedExpression { public: string ToString() const override; - static bool Equals(const CastExpression *a, const CastExpression *b); + static bool Equal(const CastExpression *a, const CastExpression *b); unique_ptr Copy() const override; @@ -179944,19 +189918,20 @@ class CastExpression : public ParsedExpression { namespace duckdb { -ColumnDefinition::ColumnDefinition(string name_p, LogicalType type_p) : name(move(name_p)), type(move(type_p)) { +ColumnDefinition::ColumnDefinition(string name_p, LogicalType type_p) + : name(std::move(name_p)), type(std::move(type_p)) { } ColumnDefinition::ColumnDefinition(string name_p, LogicalType type_p, unique_ptr expression, TableColumnType category) - : name(move(name_p)), type(move(type_p)), category(category) { + : name(std::move(name_p)), type(std::move(type_p)), category(category) { switch (category) { case TableColumnType::STANDARD: { - default_value = move(expression); + default_value = std::move(expression); break; } case TableColumnType::GENERATED: { - generated_expression = move(expression); + generated_expression = std::move(expression); break; } default: { @@ -179999,9 +189974,9 @@ ColumnDefinition ColumnDefinition::Deserialize(Deserializer &source) { switch (category) { case TableColumnType::STANDARD: - return ColumnDefinition(column_name, column_type, move(expression), TableColumnType::STANDARD); + return ColumnDefinition(column_name, column_type, std::move(expression), TableColumnType::STANDARD); case TableColumnType::GENERATED: - return ColumnDefinition(column_name, column_type, move(expression), TableColumnType::GENERATED); + return ColumnDefinition(column_name, column_type, std::move(expression), TableColumnType::GENERATED); default: throw NotImplementedException("Type not implemented for TableColumnType"); } @@ -180012,7 +189987,7 @@ const unique_ptr &ColumnDefinition::DefaultValue() const { } void ColumnDefinition::SetDefaultValue(unique_ptr default_value) { - this->default_value = move(default_value); + this->default_value = std::move(default_value); } const LogicalType &ColumnDefinition::Type() const { @@ -180098,6 +190073,9 @@ static void InnerGetListOfDependencies(ParsedExpression &expr, vector &d dependencies.push_back(name); } ParsedExpressionIterator::EnumerateChildren(expr, [&](const ParsedExpression &child) { + if (expr.type == ExpressionType::LAMBDA) { + throw NotImplementedException("Lambda functions are currently not supported in generated columns."); + } InnerGetListOfDependencies((ParsedExpression &)child, dependencies); }); } @@ -180124,24 +190102,24 @@ void ColumnDefinition::SetGeneratedExpression(unique_ptr expre VerifyColumnRefs(*expression); if (type.id() == LogicalTypeId::ANY) { - generated_expression = move(expression); + generated_expression = std::move(expression); return; } // Always wrap the expression in a cast, that way we can always update the cast when we change the type // Except if the type is LogicalType::ANY (no type specified) - generated_expression = make_unique_base(type, move(expression)); + generated_expression = make_unique_base(type, std::move(expression)); } void ColumnDefinition::ChangeGeneratedExpressionType(const LogicalType &type) { D_ASSERT(Generated()); // First time the type is set, add a cast around the expression D_ASSERT(this->type.id() == LogicalTypeId::ANY); - generated_expression = make_unique_base(type, move(generated_expression)); + generated_expression = make_unique_base(type, std::move(generated_expression)); // Every generated expression should be wrapped in a cast on creation // D_ASSERT(generated_expression->type == ExpressionType::OPERATOR_CAST); // auto &cast_expr = (CastExpression &)*generated_expression; - // auto base_expr = move(cast_expr.child); - // generated_expression = make_unique_base(type, move(base_expr)); + // auto base_expr = std::move(cast_expr.child); + // generated_expression = make_unique_base(type, std::move(base_expr)); } const ParsedExpression &ColumnDefinition::GeneratedExpression() const { @@ -180173,7 +190151,7 @@ void ColumnList::AddColumn(ColumnDefinition column) { } column.SetOid(columns.size()); AddToNameMap(column); - columns.push_back(move(column)); + columns.push_back(std::move(column)); } void ColumnList::Finalize() { @@ -180250,6 +190228,24 @@ const ColumnDefinition &ColumnList::GetColumn(const string &name) const { return columns[logical_index]; } +vector ColumnList::GetColumnNames() const { + vector names; + names.reserve(columns.size()); + for (auto &column : columns) { + names.push_back(column.Name()); + } + return names; +} + +vector ColumnList::GetColumnTypes() const { + vector types; + types.reserve(columns.size()); + for (auto &column : columns) { + types.push_back(column.Type()); + } + return types; +} + bool ColumnList::ColumnExists(const string &name) const { auto entry = name_map.find(name); return entry != name_map.end(); @@ -180297,7 +190293,7 @@ ColumnList ColumnList::Deserialize(FieldReader &reader) { ColumnList result; auto columns = reader.ReadRequiredSerializableList(); for (auto &col : columns) { - result.AddColumn(move(col)); + result.AddColumn(std::move(col)); } return result; } @@ -180369,7 +190365,7 @@ void Constraint::Print() const { namespace duckdb { CheckConstraint::CheckConstraint(unique_ptr expression) - : Constraint(ConstraintType::CHECK), expression(move(expression)) { + : Constraint(ConstraintType::CHECK), expression(std::move(expression)) { } string CheckConstraint::ToString() const { @@ -180386,7 +190382,7 @@ void CheckConstraint::Serialize(FieldWriter &writer) const { unique_ptr CheckConstraint::Deserialize(FieldReader &source) { auto expression = source.ReadRequiredSerializable(); - return make_unique(move(expression)); + return make_unique(std::move(expression)); } } // namespace duckdb @@ -180399,8 +190395,8 @@ unique_ptr CheckConstraint::Deserialize(FieldReader &source) { namespace duckdb { ForeignKeyConstraint::ForeignKeyConstraint(vector pk_columns, vector fk_columns, ForeignKeyInfo info) - : Constraint(ConstraintType::FOREIGN_KEY), pk_columns(move(pk_columns)), fk_columns(move(fk_columns)), - info(move(info)) { + : Constraint(ConstraintType::FOREIGN_KEY), pk_columns(std::move(pk_columns)), fk_columns(std::move(fk_columns)), + info(std::move(info)) { } string ForeignKeyConstraint::ToString() const { @@ -180462,7 +190458,7 @@ unique_ptr ForeignKeyConstraint::Deserialize(FieldReader &source) { read_info.fk_keys = source.ReadRequiredIndexList(); // column list parsed constraint - return make_unique(pk_columns, fk_columns, move(read_info)); + return make_unique(pk_columns, fk_columns, std::move(read_info)); } } // namespace duckdb @@ -180508,7 +190504,7 @@ UniqueConstraint::UniqueConstraint(LogicalIndex index, bool is_primary_key) : Constraint(ConstraintType::UNIQUE), index(index), is_primary_key(is_primary_key) { } UniqueConstraint::UniqueConstraint(vector columns, bool is_primary_key) - : Constraint(ConstraintType::UNIQUE), index(DConstants::INVALID_INDEX), columns(move(columns)), + : Constraint(ConstraintType::UNIQUE), index(DConstants::INVALID_INDEX), columns(std::move(columns)), is_primary_key(is_primary_key) { } @@ -180529,7 +190525,7 @@ unique_ptr UniqueConstraint::Copy() const { } else { auto result = make_unique(index, is_primary_key); result->columns = columns; - return move(result); + return std::move(result); } } @@ -180548,11 +190544,11 @@ unique_ptr UniqueConstraint::Deserialize(FieldReader &source) { if (index != DConstants::INVALID_INDEX) { // single column parsed constraint auto result = make_unique(LogicalIndex(index), is_primary_key); - result->columns = move(columns); - return move(result); + result->columns = std::move(columns); + return std::move(result); } else { // column list parsed constraint - return make_unique(move(columns), is_primary_key); + return make_unique(std::move(columns), is_primary_key); } } @@ -180583,7 +190579,7 @@ class BetweenExpression : public ParsedExpression { public: string ToString() const override; - static bool Equals(const BetweenExpression *a, const BetweenExpression *b); + static bool Equal(const BetweenExpression *a, const BetweenExpression *b); unique_ptr Copy() const override; @@ -180605,15 +190601,15 @@ namespace duckdb { BetweenExpression::BetweenExpression(unique_ptr input_p, unique_ptr lower_p, unique_ptr upper_p) - : ParsedExpression(ExpressionType::COMPARE_BETWEEN, ExpressionClass::BETWEEN), input(move(input_p)), - lower(move(lower_p)), upper(move(upper_p)) { + : ParsedExpression(ExpressionType::COMPARE_BETWEEN, ExpressionClass::BETWEEN), input(std::move(input_p)), + lower(std::move(lower_p)), upper(std::move(upper_p)) { } string BetweenExpression::ToString() const { return ToString(*this); } -bool BetweenExpression::Equals(const BetweenExpression *a, const BetweenExpression *b) { +bool BetweenExpression::Equal(const BetweenExpression *a, const BetweenExpression *b) { if (!a->input->Equals(b->input.get())) { return false; } @@ -180629,7 +190625,7 @@ bool BetweenExpression::Equals(const BetweenExpression *a, const BetweenExpressi unique_ptr BetweenExpression::Copy() const { auto copy = make_unique(input->Copy(), lower->Copy(), upper->Copy()); copy->CopyProperties(*this); - return move(copy); + return std::move(copy); } void BetweenExpression::Serialize(FieldWriter &writer) const { @@ -180642,7 +190638,7 @@ unique_ptr BetweenExpression::Deserialize(ExpressionType type, auto input = source.ReadRequiredSerializable(); auto lower = source.ReadRequiredSerializable(); auto upper = source.ReadRequiredSerializable(); - return make_unique(move(input), move(lower), move(upper)); + return make_unique(std::move(input), std::move(lower), std::move(upper)); } } // namespace duckdb @@ -180677,7 +190673,7 @@ class CaseExpression : public ParsedExpression { public: string ToString() const override; - static bool Equals(const CaseExpression *a, const CaseExpression *b); + static bool Equal(const CaseExpression *a, const CaseExpression *b); unique_ptr Copy() const override; @@ -180712,7 +190708,7 @@ string CaseExpression::ToString() const { return ToString(*this); } -bool CaseExpression::Equals(const CaseExpression *a, const CaseExpression *b) { +bool CaseExpression::Equal(const CaseExpression *a, const CaseExpression *b) { if (a->case_checks.size() != b->case_checks.size()) { return false; } @@ -180737,10 +190733,10 @@ unique_ptr CaseExpression::Copy() const { CaseCheck new_check; new_check.when_expr = check.when_expr->Copy(); new_check.then_expr = check.then_expr->Copy(); - copy->case_checks.push_back(move(new_check)); + copy->case_checks.push_back(std::move(new_check)); } copy->else_expr = else_expr->Copy(); - return move(copy); + return std::move(copy); } void CaseExpression::Serialize(FieldWriter &writer) const { @@ -180763,10 +190759,10 @@ unique_ptr CaseExpression::Deserialize(ExpressionType type, Fi CaseCheck new_check; new_check.when_expr = ParsedExpression::Deserialize(source); new_check.then_expr = ParsedExpression::Deserialize(source); - result->case_checks.push_back(move(new_check)); + result->case_checks.push_back(std::move(new_check)); } result->else_expr = reader.ReadRequiredSerializable(); - return move(result); + return std::move(result); } } // namespace duckdb @@ -180778,17 +190774,17 @@ unique_ptr CaseExpression::Deserialize(ExpressionType type, Fi namespace duckdb { CastExpression::CastExpression(LogicalType target, unique_ptr child, bool try_cast_p) - : ParsedExpression(ExpressionType::OPERATOR_CAST, ExpressionClass::CAST), cast_type(move(target)), + : ParsedExpression(ExpressionType::OPERATOR_CAST, ExpressionClass::CAST), cast_type(std::move(target)), try_cast(try_cast_p) { D_ASSERT(child); - this->child = move(child); + this->child = std::move(child); } string CastExpression::ToString() const { return ToString(*this); } -bool CastExpression::Equals(const CastExpression *a, const CastExpression *b) { +bool CastExpression::Equal(const CastExpression *a, const CastExpression *b) { if (!a->child->Equals(b->child.get())) { return false; } @@ -180804,7 +190800,7 @@ bool CastExpression::Equals(const CastExpression *a, const CastExpression *b) { unique_ptr CastExpression::Copy() const { auto copy = make_unique(cast_type, child->Copy(), try_cast); copy->CopyProperties(*this); - return move(copy); + return std::move(copy); } void CastExpression::Serialize(FieldWriter &writer) const { @@ -180817,7 +190813,7 @@ unique_ptr CastExpression::Deserialize(ExpressionType type, Fi auto child = reader.ReadRequiredSerializable(); auto cast_type = reader.ReadRequiredSerializable(); auto try_cast = reader.ReadRequired(); - return make_unique_base(cast_type, move(child), try_cast); + return make_unique_base(cast_type, std::move(child), try_cast); } } // namespace duckdb @@ -180848,7 +190844,7 @@ class CollateExpression : public ParsedExpression { public: string ToString() const override; - static bool Equals(const CollateExpression *a, const CollateExpression *b); + static bool Equal(const CollateExpression *a, const CollateExpression *b); unique_ptr Copy() const override; @@ -180864,16 +190860,16 @@ class CollateExpression : public ParsedExpression { namespace duckdb { CollateExpression::CollateExpression(string collation_p, unique_ptr child) - : ParsedExpression(ExpressionType::COLLATE, ExpressionClass::COLLATE), collation(move(collation_p)) { + : ParsedExpression(ExpressionType::COLLATE, ExpressionClass::COLLATE), collation(std::move(collation_p)) { D_ASSERT(child); - this->child = move(child); + this->child = std::move(child); } string CollateExpression::ToString() const { return child->ToString() + " COLLATE " + KeywordHelper::WriteOptionallyQuoted(collation); } -bool CollateExpression::Equals(const CollateExpression *a, const CollateExpression *b) { +bool CollateExpression::Equal(const CollateExpression *a, const CollateExpression *b) { if (!a->child->Equals(b->child.get())) { return false; } @@ -180886,7 +190882,7 @@ bool CollateExpression::Equals(const CollateExpression *a, const CollateExpressi unique_ptr CollateExpression::Copy() const { auto copy = make_unique(collation, child->Copy()); copy->CopyProperties(*this); - return move(copy); + return std::move(copy); } void CollateExpression::Serialize(FieldWriter &writer) const { @@ -180897,7 +190893,7 @@ void CollateExpression::Serialize(FieldWriter &writer) const { unique_ptr CollateExpression::Deserialize(ExpressionType type, FieldReader &reader) { auto child = reader.ReadRequiredSerializable(); auto collation = reader.ReadRequired(); - return make_unique_base(collation, move(child)); + return make_unique_base(collation, std::move(child)); } } // namespace duckdb @@ -180911,15 +190907,17 @@ unique_ptr CollateExpression::Deserialize(ExpressionType type, namespace duckdb { ColumnRefExpression::ColumnRefExpression(string column_name, string table_name) - : ColumnRefExpression(table_name.empty() ? vector {move(column_name)} - : vector {move(table_name), move(column_name)}) { + : ColumnRefExpression(table_name.empty() ? vector {std::move(column_name)} + : vector {std::move(table_name), std::move(column_name)}) { } -ColumnRefExpression::ColumnRefExpression(string column_name) : ColumnRefExpression(vector {move(column_name)}) { +ColumnRefExpression::ColumnRefExpression(string column_name) + : ColumnRefExpression(vector {std::move(column_name)}) { } ColumnRefExpression::ColumnRefExpression(vector column_names_p) - : ParsedExpression(ExpressionType::COLUMN_REF, ExpressionClass::COLUMN_REF), column_names(move(column_names_p)) { + : ParsedExpression(ExpressionType::COLUMN_REF, ExpressionClass::COLUMN_REF), + column_names(std::move(column_names_p)) { #ifdef DEBUG for (auto &col_name : column_names) { D_ASSERT(!col_name.empty()); @@ -180932,13 +190930,19 @@ bool ColumnRefExpression::IsQualified() const { } const string &ColumnRefExpression::GetColumnName() const { - D_ASSERT(column_names.size() <= 3); + D_ASSERT(column_names.size() <= 4); return column_names.back(); } const string &ColumnRefExpression::GetTableName() const { - D_ASSERT(column_names.size() >= 2 && column_names.size() <= 3); - return column_names.size() == 3 ? column_names[1] : column_names[0]; + D_ASSERT(column_names.size() >= 2 && column_names.size() <= 4); + if (column_names.size() == 4) { + return column_names[2]; + } + if (column_names.size() == 3) { + return column_names[1]; + } + return column_names[0]; } string ColumnRefExpression::GetName() const { @@ -180956,7 +190960,7 @@ string ColumnRefExpression::ToString() const { return result; } -bool ColumnRefExpression::Equals(const ColumnRefExpression *a, const ColumnRefExpression *b) { +bool ColumnRefExpression::Equal(const ColumnRefExpression *a, const ColumnRefExpression *b) { if (a->column_names.size() != b->column_names.size()) { return false; } @@ -180982,7 +190986,7 @@ hash_t ColumnRefExpression::Hash() const { unique_ptr ColumnRefExpression::Copy() const { auto copy = make_unique(column_names); copy->CopyProperties(*this); - return move(copy); + return std::move(copy); } void ColumnRefExpression::Serialize(FieldWriter &writer) const { @@ -180991,8 +190995,8 @@ void ColumnRefExpression::Serialize(FieldWriter &writer) const { unique_ptr ColumnRefExpression::Deserialize(ExpressionType type, FieldReader &reader) { auto column_names = reader.ReadRequiredList(); - auto expression = make_unique(move(column_names)); - return move(expression); + auto expression = make_unique(std::move(column_names)); + return std::move(expression); } } // namespace duckdb @@ -181006,14 +191010,14 @@ namespace duckdb { ComparisonExpression::ComparisonExpression(ExpressionType type, unique_ptr left, unique_ptr right) - : ParsedExpression(type, ExpressionClass::COMPARISON), left(move(left)), right(move(right)) { + : ParsedExpression(type, ExpressionClass::COMPARISON), left(std::move(left)), right(std::move(right)) { } string ComparisonExpression::ToString() const { return ToString(*this); } -bool ComparisonExpression::Equals(const ComparisonExpression *a, const ComparisonExpression *b) { +bool ComparisonExpression::Equal(const ComparisonExpression *a, const ComparisonExpression *b) { if (!a->left->Equals(b->left.get())) { return false; } @@ -181026,7 +191030,7 @@ bool ComparisonExpression::Equals(const ComparisonExpression *a, const Compariso unique_ptr ComparisonExpression::Copy() const { auto copy = make_unique(type, left->Copy(), right->Copy()); copy->CopyProperties(*this); - return move(copy); + return std::move(copy); } void ComparisonExpression::Serialize(FieldWriter &writer) const { @@ -181037,7 +191041,7 @@ void ComparisonExpression::Serialize(FieldWriter &writer) const { unique_ptr ComparisonExpression::Deserialize(ExpressionType type, FieldReader &reader) { auto left_child = reader.ReadRequiredSerializable(); auto right_child = reader.ReadRequiredSerializable(); - return make_unique(type, move(left_child), move(right_child)); + return make_unique(type, std::move(left_child), std::move(right_child)); } } // namespace duckdb @@ -181055,15 +191059,15 @@ ConjunctionExpression::ConjunctionExpression(ExpressionType type) ConjunctionExpression::ConjunctionExpression(ExpressionType type, vector> children) : ParsedExpression(type, ExpressionClass::CONJUNCTION) { for (auto &child : children) { - AddExpression(move(child)); + AddExpression(std::move(child)); } } ConjunctionExpression::ConjunctionExpression(ExpressionType type, unique_ptr left, unique_ptr right) : ParsedExpression(type, ExpressionClass::CONJUNCTION) { - AddExpression(move(left)); - AddExpression(move(right)); + AddExpression(std::move(left)); + AddExpression(std::move(right)); } void ConjunctionExpression::AddExpression(unique_ptr expr) { @@ -181071,10 +191075,10 @@ void ConjunctionExpression::AddExpression(unique_ptr expr) { // expr is a conjunction of the same type: merge the expression lists together auto &other = (ConjunctionExpression &)*expr; for (auto &child : other.children) { - children.push_back(move(child)); + children.push_back(std::move(child)); } } else { - children.push_back(move(expr)); + children.push_back(std::move(expr)); } } @@ -181082,7 +191086,7 @@ string ConjunctionExpression::ToString() const { return ToString(*this); } -bool ConjunctionExpression::Equals(const ConjunctionExpression *a, const ConjunctionExpression *b) { +bool ConjunctionExpression::Equal(const ConjunctionExpression *a, const ConjunctionExpression *b) { return ExpressionUtil::SetEquals(a->children, b->children); } @@ -181091,9 +191095,9 @@ unique_ptr ConjunctionExpression::Copy() const { for (auto &expr : children) { copy_children.push_back(expr->Copy()); } - auto copy = make_unique(type, move(copy_children)); + auto copy = make_unique(type, std::move(copy_children)); copy->CopyProperties(*this); - return move(copy); + return std::move(copy); } void ConjunctionExpression::Serialize(FieldWriter &writer) const { @@ -181103,7 +191107,7 @@ void ConjunctionExpression::Serialize(FieldWriter &writer) const { unique_ptr ConjunctionExpression::Deserialize(ExpressionType type, FieldReader &reader) { auto result = make_unique(type); result->children = reader.ReadRequiredSerializableList(); - return move(result); + return std::move(result); } } // namespace duckdb @@ -181117,14 +191121,14 @@ unique_ptr ConjunctionExpression::Deserialize(ExpressionType t namespace duckdb { ConstantExpression::ConstantExpression(Value val) - : ParsedExpression(ExpressionType::VALUE_CONSTANT, ExpressionClass::CONSTANT), value(move(val)) { + : ParsedExpression(ExpressionType::VALUE_CONSTANT, ExpressionClass::CONSTANT), value(std::move(val)) { } string ConstantExpression::ToString() const { return value.ToSQLString(); } -bool ConstantExpression::Equals(const ConstantExpression *a, const ConstantExpression *b) { +bool ConstantExpression::Equal(const ConstantExpression *a, const ConstantExpression *b) { return a->value.type() == b->value.type() && !ValueOperations::DistinctFrom(a->value, b->value); } @@ -181135,7 +191139,7 @@ hash_t ConstantExpression::Hash() const { unique_ptr ConstantExpression::Copy() const { auto copy = make_unique(value); copy->CopyProperties(*this); - return move(copy); + return std::move(copy); } void ConstantExpression::Serialize(FieldWriter &writer) const { @@ -181144,7 +191148,7 @@ void ConstantExpression::Serialize(FieldWriter &writer) const { unique_ptr ConstantExpression::Deserialize(ExpressionType type, FieldReader &reader) { Value value = reader.ReadRequiredSerializable(); - return make_unique(move(value)); + return make_unique(std::move(value)); } } // namespace duckdb @@ -181195,7 +191199,7 @@ string DefaultExpression::ToString() const { unique_ptr DefaultExpression::Copy() const { auto copy = make_unique(); copy->CopyProperties(*this); - return move(copy); + return std::move(copy); } void DefaultExpression::Serialize(FieldWriter &writer) const { @@ -181216,13 +191220,14 @@ unique_ptr DefaultExpression::Deserialize(ExpressionType type, namespace duckdb { -FunctionExpression::FunctionExpression(string schema, const string &function_name, +FunctionExpression::FunctionExpression(string catalog, string schema, const string &function_name, vector> children_p, unique_ptr filter, unique_ptr order_bys_p, bool distinct, bool is_operator, bool export_state_p) - : ParsedExpression(ExpressionType::FUNCTION, ExpressionClass::FUNCTION), schema(std::move(schema)), - function_name(StringUtil::Lower(function_name)), is_operator(is_operator), children(move(children_p)), - distinct(distinct), filter(move(filter)), order_bys(move(order_bys_p)), export_state(export_state_p) { + : ParsedExpression(ExpressionType::FUNCTION, ExpressionClass::FUNCTION), catalog(std::move(catalog)), + schema(std::move(schema)), function_name(StringUtil::Lower(function_name)), is_operator(is_operator), + children(std::move(children_p)), distinct(distinct), filter(std::move(filter)), order_bys(std::move(order_bys_p)), + export_state(export_state_p) { D_ASSERT(!function_name.empty()); if (!order_bys) { order_bys = make_unique(); @@ -181232,8 +191237,8 @@ FunctionExpression::FunctionExpression(string schema, const string &function_nam FunctionExpression::FunctionExpression(const string &function_name, vector> children_p, unique_ptr filter, unique_ptr order_bys, bool distinct, bool is_operator, bool export_state_p) - : FunctionExpression(INVALID_SCHEMA, function_name, move(children_p), move(filter), move(order_bys), distinct, - is_operator, export_state_p) { + : FunctionExpression(INVALID_CATALOG, INVALID_SCHEMA, function_name, std::move(children_p), std::move(filter), + std::move(order_bys), distinct, is_operator, export_state_p) { } string FunctionExpression::ToString() const { @@ -181241,8 +191246,9 @@ string FunctionExpression::ToString() const { filter.get(), order_bys.get(), export_state, true); } -bool FunctionExpression::Equals(const FunctionExpression *a, const FunctionExpression *b) { - if (a->schema != b->schema || a->function_name != b->function_name || b->distinct != a->distinct) { +bool FunctionExpression::Equal(const FunctionExpression *a, const FunctionExpression *b) { + if (a->catalog != b->catalog || a->schema != b->schema || a->function_name != b->function_name || + b->distinct != a->distinct) { return false; } if (b->children.size() != a->children.size()) { @@ -181288,11 +191294,11 @@ unique_ptr FunctionExpression::Copy() const { order_copy.reset(static_cast(order_bys->Copy().release())); } - auto copy = make_unique(function_name, move(copy_children), move(filter_copy), move(order_copy), - distinct, is_operator, export_state); - copy->schema = schema; + auto copy = make_unique(catalog, schema, function_name, std::move(copy_children), + std::move(filter_copy), std::move(order_copy), distinct, is_operator, + export_state); copy->CopyProperties(*this); - return move(copy); + return std::move(copy); } void FunctionExpression::Serialize(FieldWriter &writer) const { @@ -181304,6 +191310,7 @@ void FunctionExpression::Serialize(FieldWriter &writer) const { writer.WriteField(distinct); writer.WriteField(is_operator); writer.WriteField(export_state); + writer.WriteString(catalog); } unique_ptr FunctionExpression::Deserialize(ExpressionType type, FieldReader &reader) { @@ -181315,12 +191322,12 @@ unique_ptr FunctionExpression::Deserialize(ExpressionType type auto distinct = reader.ReadRequired(); auto is_operator = reader.ReadRequired(); auto export_state = reader.ReadField(false); + auto catalog = reader.ReadField(INVALID_CATALOG); unique_ptr function; - function = make_unique(function_name, move(children), move(filter), move(order_bys), distinct, - is_operator, export_state); - function->schema = schema; - return move(function); + function = make_unique(catalog, schema, function_name, std::move(children), std::move(filter), + std::move(order_bys), distinct, is_operator, export_state); + return std::move(function); } void FunctionExpression::Verify() const { @@ -181336,14 +191343,14 @@ void FunctionExpression::Verify() const { namespace duckdb { LambdaExpression::LambdaExpression(unique_ptr lhs, unique_ptr expr) - : ParsedExpression(ExpressionType::LAMBDA, ExpressionClass::LAMBDA), lhs(move(lhs)), expr(move(expr)) { + : ParsedExpression(ExpressionType::LAMBDA, ExpressionClass::LAMBDA), lhs(std::move(lhs)), expr(std::move(expr)) { } string LambdaExpression::ToString() const { return lhs->ToString() + " -> " + expr->ToString(); } -bool LambdaExpression::Equals(const LambdaExpression *a, const LambdaExpression *b) { +bool LambdaExpression::Equal(const LambdaExpression *a, const LambdaExpression *b) { return a->lhs->Equals(b->lhs.get()) && a->expr->Equals(b->expr.get()); } @@ -181357,7 +191364,7 @@ hash_t LambdaExpression::Hash() const { unique_ptr LambdaExpression::Copy() const { auto copy = make_unique(lhs->Copy(), expr->Copy()); copy->CopyProperties(*this); - return move(copy); + return std::move(copy); } void LambdaExpression::Serialize(FieldWriter &writer) const { @@ -181368,7 +191375,7 @@ void LambdaExpression::Serialize(FieldWriter &writer) const { unique_ptr LambdaExpression::Deserialize(ExpressionType type, FieldReader &reader) { auto lhs = reader.ReadRequiredSerializable(); auto expr = reader.ReadRequiredSerializable(); - return make_unique(move(lhs), move(expr)); + return make_unique(std::move(lhs), std::move(expr)); } } // namespace duckdb @@ -181400,7 +191407,7 @@ class OperatorExpression : public ParsedExpression { public: string ToString() const override; - static bool Equals(const OperatorExpression *a, const OperatorExpression *b); + static bool Equal(const OperatorExpression *a, const OperatorExpression *b); unique_ptr Copy() const override; @@ -181493,22 +191500,22 @@ OperatorExpression::OperatorExpression(ExpressionType type, unique_ptr right) : ParsedExpression(type, ExpressionClass::OPERATOR) { if (left) { - children.push_back(move(left)); + children.push_back(std::move(left)); } if (right) { - children.push_back(move(right)); + children.push_back(std::move(right)); } } OperatorExpression::OperatorExpression(ExpressionType type, vector> children) - : ParsedExpression(type, ExpressionClass::OPERATOR), children(move(children)) { + : ParsedExpression(type, ExpressionClass::OPERATOR), children(std::move(children)) { } string OperatorExpression::ToString() const { return ToString(*this); } -bool OperatorExpression::Equals(const OperatorExpression *a, const OperatorExpression *b) { +bool OperatorExpression::Equal(const OperatorExpression *a, const OperatorExpression *b) { if (a->children.size() != b->children.size()) { return false; } @@ -181526,7 +191533,7 @@ unique_ptr OperatorExpression::Copy() const { for (auto &it : children) { copy->children.push_back(it->Copy()); } - return move(copy); + return std::move(copy); } void OperatorExpression::Serialize(FieldWriter &writer) const { @@ -181536,7 +191543,7 @@ void OperatorExpression::Serialize(FieldWriter &writer) const { unique_ptr OperatorExpression::Deserialize(ExpressionType type, FieldReader &reader) { auto expression = make_unique(type); expression->children = reader.ReadRequiredSerializableList(); - return move(expression); + return std::move(expression); } } // namespace duckdb @@ -181561,10 +191568,10 @@ unique_ptr ParameterExpression::Copy() const { auto copy = make_unique(); copy->parameter_nr = parameter_nr; copy->CopyProperties(*this); - return move(copy); + return std::move(copy); } -bool ParameterExpression::Equals(const ParameterExpression *a, const ParameterExpression *b) { +bool ParameterExpression::Equal(const ParameterExpression *a, const ParameterExpression *b) { return a->parameter_nr == b->parameter_nr; } @@ -181580,7 +191587,7 @@ void ParameterExpression::Serialize(FieldWriter &writer) const { unique_ptr ParameterExpression::Deserialize(ExpressionType type, FieldReader &reader) { auto expression = make_unique(); expression->parameter_nr = reader.ReadRequired(); - return move(expression); + return std::move(expression); } } // namespace duckdb @@ -181610,7 +191617,7 @@ class PositionalReferenceExpression : public ParsedExpression { string ToString() const override; - static bool Equals(const PositionalReferenceExpression *a, const PositionalReferenceExpression *b); + static bool Equal(const PositionalReferenceExpression *a, const PositionalReferenceExpression *b); unique_ptr Copy() const override; hash_t Hash() const override; @@ -181635,15 +191642,15 @@ string PositionalReferenceExpression::ToString() const { return "#" + to_string(index); } -bool PositionalReferenceExpression::Equals(const PositionalReferenceExpression *a, - const PositionalReferenceExpression *b) { +bool PositionalReferenceExpression::Equal(const PositionalReferenceExpression *a, + const PositionalReferenceExpression *b) { return a->index == b->index; } unique_ptr PositionalReferenceExpression::Copy() const { auto copy = make_unique(index); copy->CopyProperties(*this); - return move(copy); + return std::move(copy); } hash_t PositionalReferenceExpression::Hash() const { @@ -181657,7 +191664,7 @@ void PositionalReferenceExpression::Serialize(FieldWriter &writer) const { unique_ptr PositionalReferenceExpression::Deserialize(ExpressionType type, FieldReader &reader) { auto expression = make_unique(reader.ReadRequired()); - return move(expression); + return std::move(expression); } } // namespace duckdb @@ -181669,7 +191676,7 @@ unique_ptr PositionalReferenceExpression::Deserialize(Expressi namespace duckdb { StarExpression::StarExpression(string relation_name_p) - : ParsedExpression(ExpressionType::STAR, ExpressionClass::STAR), relation_name(move(relation_name_p)) { + : ParsedExpression(ExpressionType::STAR, ExpressionClass::STAR), relation_name(std::move(relation_name_p)) { } string StarExpression::ToString() const { @@ -181714,7 +191721,7 @@ string StarExpression::ToString() const { return result; } -bool StarExpression::Equals(const StarExpression *a, const StarExpression *b) { +bool StarExpression::Equal(const StarExpression *a, const StarExpression *b) { if (a->relation_name != b->relation_name || a->exclude_list != b->exclude_list) { return false; } @@ -181772,11 +191779,11 @@ unique_ptr StarExpression::Deserialize(ExpressionType type, Fi for (idx_t i = 0; i < replace_count; i++) { auto name = source.Read(); auto expr = ParsedExpression::Deserialize(source); - result->replace_list.insert(make_pair(name, move(expr))); + result->replace_list.insert(make_pair(name, std::move(expr))); } result->columns = reader.ReadField(false); result->regex = reader.ReadField(string()); - return move(result); + return std::move(result); } unique_ptr StarExpression::Copy() const { @@ -181788,7 +191795,7 @@ unique_ptr StarExpression::Copy() const { copy->columns = columns; copy->regex = regex; copy->CopyProperties(*this); - return move(copy); + return std::move(copy); } } // namespace duckdb @@ -181820,7 +191827,7 @@ string SubqueryExpression::ToString() const { } } -bool SubqueryExpression::Equals(const SubqueryExpression *a, const SubqueryExpression *b) { +bool SubqueryExpression::Equal(const SubqueryExpression *a, const SubqueryExpression *b) { if (!a->subquery || !b->subquery) { return false; } @@ -181838,7 +191845,7 @@ unique_ptr SubqueryExpression::Copy() const { copy->subquery_type = subquery_type; copy->child = child ? child->Copy() : nullptr; copy->comparison_type = comparison_type; - return move(copy); + return std::move(copy); } void SubqueryExpression::Serialize(FieldWriter &writer) const { @@ -181860,10 +191867,10 @@ unique_ptr SubqueryExpression::Deserialize(ExpressionType type auto expression = make_unique(); expression->subquery_type = subquery_type; - expression->subquery = move(subquery); + expression->subquery = std::move(subquery); expression->child = reader.ReadOptional(nullptr); expression->comparison_type = reader.ReadRequired(); - return move(expression); + return std::move(expression); } } // namespace duckdb @@ -181875,8 +191882,8 @@ unique_ptr SubqueryExpression::Deserialize(ExpressionType type namespace duckdb { -WindowExpression::WindowExpression(ExpressionType type, string schema, const string &function_name) - : ParsedExpression(type, ExpressionClass::WINDOW), schema(move(schema)), +WindowExpression::WindowExpression(ExpressionType type, string catalog_name, string schema, const string &function_name) + : ParsedExpression(type, ExpressionClass::WINDOW), catalog(std::move(catalog_name)), schema(std::move(schema)), function_name(StringUtil::Lower(function_name)), ignore_nulls(false) { switch (type) { case ExpressionType::WINDOW_AGGREGATE: @@ -181901,7 +191908,7 @@ string WindowExpression::ToString() const { return ToString(*this, schema, function_name); } -bool WindowExpression::Equals(const WindowExpression *a, const WindowExpression *b) { +bool WindowExpression::Equal(const WindowExpression *a, const WindowExpression *b) { // check if the child expressions are equivalent if (b->children.size() != a->children.size()) { return false; @@ -181917,7 +191924,7 @@ bool WindowExpression::Equals(const WindowExpression *a, const WindowExpression if (a->start != b->start || a->end != b->end) { return false; } - // check if the framing expressions are equivalent + // check if the framing expressions are equivalentbind_ if (!BaseExpression::Equals(a->start_expr.get(), b->start_expr.get()) || !BaseExpression::Equals(a->end_expr.get(), b->end_expr.get()) || !BaseExpression::Equals(a->offset_expr.get(), b->offset_expr.get()) || @@ -181955,7 +191962,7 @@ bool WindowExpression::Equals(const WindowExpression *a, const WindowExpression } unique_ptr WindowExpression::Copy() const { - auto new_window = make_unique(type, schema, function_name); + auto new_window = make_unique(type, catalog, schema, function_name); new_window->CopyProperties(*this); for (auto &child : children) { @@ -181980,7 +191987,7 @@ unique_ptr WindowExpression::Copy() const { new_window->default_expr = default_expr ? default_expr->Copy() : nullptr; new_window->ignore_nulls = ignore_nulls; - return move(new_window); + return std::move(new_window); } void WindowExpression::Serialize(FieldWriter &writer) const { @@ -182005,12 +192012,13 @@ void WindowExpression::Serialize(FieldWriter &writer) const { writer.WriteOptional(default_expr); writer.WriteField(ignore_nulls); writer.WriteOptional(filter_expr); + writer.WriteString(catalog); } unique_ptr WindowExpression::Deserialize(ExpressionType type, FieldReader &reader) { auto function_name = reader.ReadRequired(); auto schema = reader.ReadRequired(); - auto expr = make_unique(type, schema, function_name); + auto expr = make_unique(type, INVALID_CATALOG, std::move(schema), function_name); expr->children = reader.ReadRequiredSerializableList(); expr->partitions = reader.ReadRequiredSerializableList(); @@ -182028,7 +192036,8 @@ unique_ptr WindowExpression::Deserialize(ExpressionType type, expr->default_expr = reader.ReadOptional(nullptr); expr->ignore_nulls = reader.ReadRequired(); expr->filter_expr = reader.ReadOptional(nullptr); - return move(expr); + expr->catalog = reader.ReadField(INVALID_CATALOG); + return std::move(expr); } } // namespace duckdb @@ -182153,8 +192162,10 @@ namespace duckdb { //===--------------------------------------------------------------------===// // AlterFunctionInfo //===--------------------------------------------------------------------===// -AlterFunctionInfo::AlterFunctionInfo(AlterFunctionType type, string schema_p, string table_p, bool if_exists) - : AlterInfo(AlterType::ALTER_FUNCTION, move(move(schema_p)), move(table_p), if_exists), alter_function_type(type) { +AlterFunctionInfo::AlterFunctionInfo(AlterFunctionType type, AlterEntryData data) + : AlterInfo(AlterType::ALTER_FUNCTION, std::move(data.catalog), std::move(data.schema), std::move(data.name), + data.if_exists), + alter_function_type(type) { } AlterFunctionInfo::~AlterFunctionInfo() { } @@ -182165,6 +192176,7 @@ CatalogType AlterFunctionInfo::GetCatalogType() const { void AlterFunctionInfo::Serialize(FieldWriter &writer) const { writer.WriteField(alter_function_type); + writer.WriteString(catalog); writer.WriteString(schema); writer.WriteString(name); writer.WriteField(if_exists); @@ -182182,16 +192194,16 @@ unique_ptr AlterFunctionInfo::Deserialize(FieldReader &reader) { //===--------------------------------------------------------------------===// // AddFunctionOverloadInfo //===--------------------------------------------------------------------===// -AddFunctionOverloadInfo::AddFunctionOverloadInfo(string schema_p, string name_p, bool if_exists_p, - ScalarFunctionSet new_overloads_p) - : AlterFunctionInfo(AlterFunctionType::ADD_FUNCTION_OVERLOADS, move(schema_p), move(name_p), if_exists_p), - new_overloads(move(new_overloads_p)) { +AddFunctionOverloadInfo::AddFunctionOverloadInfo(AlterEntryData data, ScalarFunctionSet new_overloads_p) + : AlterFunctionInfo(AlterFunctionType::ADD_FUNCTION_OVERLOADS, std::move(data)), + new_overloads(std::move(new_overloads_p)) { + this->allow_internal = true; } AddFunctionOverloadInfo::~AddFunctionOverloadInfo() { } unique_ptr AddFunctionOverloadInfo::Copy() const { - return make_unique_base(schema, name, if_exists, new_overloads); + return make_unique_base(GetAlterEntryData(), new_overloads); } } // namespace duckdb @@ -182203,8 +192215,9 @@ unique_ptr AddFunctionOverloadInfo::Copy() const { namespace duckdb { -AlterInfo::AlterInfo(AlterType type, string schema_p, string name_p, bool if_exists) - : type(type), if_exists(if_exists), schema(move(schema_p)), name(move(name_p)) { +AlterInfo::AlterInfo(AlterType type, string catalog_p, string schema_p, string name_p, bool if_exists) + : type(type), if_exists(if_exists), catalog(std::move(catalog_p)), schema(std::move(schema_p)), + name(std::move(name_p)), allow_internal(false) { } AlterInfo::~AlterInfo() { @@ -182240,6 +192253,15 @@ unique_ptr AlterInfo::Deserialize(Deserializer &source) { return result; } +AlterEntryData AlterInfo::GetAlterEntryData() const { + AlterEntryData data; + data.catalog = catalog; + data.schema = schema; + data.name = name; + data.if_exists = if_exists; + return data; +} + } // namespace duckdb @@ -182251,10 +192273,13 @@ namespace duckdb { //===--------------------------------------------------------------------===// // ChangeOwnershipInfo //===--------------------------------------------------------------------===// -ChangeOwnershipInfo::ChangeOwnershipInfo(CatalogType entry_catalog_type, string entry_schema_p, string entry_name_p, - string owner_schema_p, string owner_name_p, bool if_exists) - : AlterInfo(AlterType::CHANGE_OWNERSHIP, move(entry_schema_p), move(entry_name_p), if_exists), - entry_catalog_type(entry_catalog_type), owner_schema(move(owner_schema_p)), owner_name(move(owner_name_p)) { +ChangeOwnershipInfo::ChangeOwnershipInfo(CatalogType entry_catalog_type, string entry_catalog_p, string entry_schema_p, + string entry_name_p, string owner_schema_p, string owner_name_p, + bool if_exists) + : AlterInfo(AlterType::CHANGE_OWNERSHIP, std::move(entry_catalog_p), std::move(entry_schema_p), + std::move(entry_name_p), if_exists), + entry_catalog_type(entry_catalog_type), owner_schema(std::move(owner_schema_p)), + owner_name(std::move(owner_name_p)) { } CatalogType ChangeOwnershipInfo::GetCatalogType() const { @@ -182262,8 +192287,8 @@ CatalogType ChangeOwnershipInfo::GetCatalogType() const { } unique_ptr ChangeOwnershipInfo::Copy() const { - return make_unique_base(entry_catalog_type, schema, name, owner_schema, owner_name, - if_exists); + return make_unique_base(entry_catalog_type, catalog, schema, name, owner_schema, + owner_name, if_exists); } void ChangeOwnershipInfo::Serialize(FieldWriter &writer) const { @@ -182273,8 +192298,10 @@ void ChangeOwnershipInfo::Serialize(FieldWriter &writer) const { //===--------------------------------------------------------------------===// // AlterTableInfo //===--------------------------------------------------------------------===// -AlterTableInfo::AlterTableInfo(AlterTableType type, string schema_p, string table_p, bool if_exists) - : AlterInfo(AlterType::ALTER_TABLE, move(move(schema_p)), move(table_p), if_exists), alter_table_type(type) { +AlterTableInfo::AlterTableInfo(AlterTableType type, AlterEntryData data) + : AlterInfo(AlterType::ALTER_TABLE, std::move(data.catalog), std::move(data.schema), std::move(data.name), + data.if_exists), + alter_table_type(type) { } AlterTableInfo::~AlterTableInfo() { } @@ -182285,6 +192312,7 @@ CatalogType AlterTableInfo::GetCatalogType() const { void AlterTableInfo::Serialize(FieldWriter &writer) const { writer.WriteField(alter_table_type); + writer.WriteString(catalog); writer.WriteString(schema); writer.WriteString(name); writer.WriteField(if_exists); @@ -182293,30 +192321,32 @@ void AlterTableInfo::Serialize(FieldWriter &writer) const { unique_ptr AlterTableInfo::Deserialize(FieldReader &reader) { auto type = reader.ReadRequired(); - auto schema = reader.ReadRequired(); - auto table = reader.ReadRequired(); - auto if_exists = reader.ReadRequired(); + AlterEntryData data; + data.catalog = reader.ReadRequired(); + data.schema = reader.ReadRequired(); + data.name = reader.ReadRequired(); + data.if_exists = reader.ReadRequired(); unique_ptr info; switch (type) { case AlterTableType::RENAME_COLUMN: - return RenameColumnInfo::Deserialize(reader, schema, table, if_exists); + return RenameColumnInfo::Deserialize(reader, std::move(data)); case AlterTableType::RENAME_TABLE: - return RenameTableInfo::Deserialize(reader, schema, table, if_exists); + return RenameTableInfo::Deserialize(reader, std::move(data)); case AlterTableType::ADD_COLUMN: - return AddColumnInfo::Deserialize(reader, schema, table, if_exists); + return AddColumnInfo::Deserialize(reader, std::move(data)); case AlterTableType::REMOVE_COLUMN: - return RemoveColumnInfo::Deserialize(reader, schema, table, if_exists); + return RemoveColumnInfo::Deserialize(reader, std::move(data)); case AlterTableType::ALTER_COLUMN_TYPE: - return ChangeColumnTypeInfo::Deserialize(reader, schema, table, if_exists); + return ChangeColumnTypeInfo::Deserialize(reader, std::move(data)); case AlterTableType::SET_DEFAULT: - return SetDefaultInfo::Deserialize(reader, schema, table, if_exists); + return SetDefaultInfo::Deserialize(reader, std::move(data)); case AlterTableType::FOREIGN_KEY_CONSTRAINT: - return AlterForeignKeyInfo::Deserialize(reader, schema, table, if_exists); + return AlterForeignKeyInfo::Deserialize(reader, std::move(data)); case AlterTableType::SET_NOT_NULL: - return SetNotNullInfo::Deserialize(reader, schema, table, if_exists); + return SetNotNullInfo::Deserialize(reader, std::move(data)); case AlterTableType::DROP_NOT_NULL: - return DropNotNullInfo::Deserialize(reader, schema, table, if_exists); + return DropNotNullInfo::Deserialize(reader, std::move(data)); default: throw SerializationException("Unknown alter table type for deserialization!"); } @@ -182325,16 +192355,15 @@ unique_ptr AlterTableInfo::Deserialize(FieldReader &reader) { //===--------------------------------------------------------------------===// // RenameColumnInfo //===--------------------------------------------------------------------===// -RenameColumnInfo::RenameColumnInfo(string schema_p, string table_p, bool if_exists_p, string old_name_p, - string new_name_p) - : AlterTableInfo(AlterTableType::RENAME_COLUMN, move(schema_p), move(table_p), if_exists_p), - old_name(move(old_name_p)), new_name(move(new_name_p)) { +RenameColumnInfo::RenameColumnInfo(AlterEntryData data, string old_name_p, string new_name_p) + : AlterTableInfo(AlterTableType::RENAME_COLUMN, std::move(data)), old_name(std::move(old_name_p)), + new_name(std::move(new_name_p)) { } RenameColumnInfo::~RenameColumnInfo() { } unique_ptr RenameColumnInfo::Copy() const { - return make_unique_base(schema, name, if_exists, old_name, new_name); + return make_unique_base(GetAlterEntryData(), old_name, new_name); } void RenameColumnInfo::SerializeAlterTable(FieldWriter &writer) const { @@ -182342,49 +192371,47 @@ void RenameColumnInfo::SerializeAlterTable(FieldWriter &writer) const { writer.WriteString(new_name); } -unique_ptr RenameColumnInfo::Deserialize(FieldReader &reader, string schema, string table, bool if_exists) { +unique_ptr RenameColumnInfo::Deserialize(FieldReader &reader, AlterEntryData data) { auto old_name = reader.ReadRequired(); auto new_name = reader.ReadRequired(); - return make_unique(move(schema), move(table), if_exists, old_name, new_name); + return make_unique(std::move(data), old_name, new_name); } //===--------------------------------------------------------------------===// // RenameTableInfo //===--------------------------------------------------------------------===// -RenameTableInfo::RenameTableInfo(string schema_p, string table_p, bool if_exists, string new_name_p) - : AlterTableInfo(AlterTableType::RENAME_TABLE, move(schema_p), move(table_p), if_exists), - new_table_name(move(new_name_p)) { +RenameTableInfo::RenameTableInfo(AlterEntryData data, string new_name_p) + : AlterTableInfo(AlterTableType::RENAME_TABLE, std::move(data)), new_table_name(std::move(new_name_p)) { } RenameTableInfo::~RenameTableInfo() { } unique_ptr RenameTableInfo::Copy() const { - return make_unique_base(schema, name, if_exists, new_table_name); + return make_unique_base(GetAlterEntryData(), new_table_name); } void RenameTableInfo::SerializeAlterTable(FieldWriter &writer) const { writer.WriteString(new_table_name); } -unique_ptr RenameTableInfo::Deserialize(FieldReader &reader, string schema, string table, bool if_exists) { +unique_ptr RenameTableInfo::Deserialize(FieldReader &reader, AlterEntryData data) { auto new_name = reader.ReadRequired(); - return make_unique(move(schema), move(table), if_exists, new_name); + return make_unique(std::move(data), new_name); } //===--------------------------------------------------------------------===// // AddColumnInfo //===--------------------------------------------------------------------===// -AddColumnInfo::AddColumnInfo(string schema_p, string table_p, bool if_exists_p, ColumnDefinition new_column, - bool if_column_not_exists) - : AlterTableInfo(AlterTableType::ADD_COLUMN, move(schema_p), move(table_p), if_exists_p), - new_column(move(new_column)), if_column_not_exists(if_column_not_exists) { +AddColumnInfo::AddColumnInfo(AlterEntryData data, ColumnDefinition new_column, bool if_column_not_exists) + : AlterTableInfo(AlterTableType::ADD_COLUMN, std::move(data)), new_column(std::move(new_column)), + if_column_not_exists(if_column_not_exists) { } AddColumnInfo::~AddColumnInfo() { } unique_ptr AddColumnInfo::Copy() const { - return make_unique_base(schema, name, if_exists, new_column.Copy(), if_column_not_exists); + return make_unique_base(GetAlterEntryData(), new_column.Copy(), if_column_not_exists); } void AddColumnInfo::SerializeAlterTable(FieldWriter &writer) const { @@ -182392,25 +192419,24 @@ void AddColumnInfo::SerializeAlterTable(FieldWriter &writer) const { writer.WriteField(if_column_not_exists); } -unique_ptr AddColumnInfo::Deserialize(FieldReader &reader, string schema, string table, bool if_exists) { +unique_ptr AddColumnInfo::Deserialize(FieldReader &reader, AlterEntryData data) { auto new_column = reader.ReadRequiredSerializable(); auto if_column_not_exists = reader.ReadRequired(); - return make_unique(move(schema), move(table), if_exists, move(new_column), if_column_not_exists); + return make_unique(std::move(data), std::move(new_column), if_column_not_exists); } //===--------------------------------------------------------------------===// // RemoveColumnInfo //===--------------------------------------------------------------------===// -RemoveColumnInfo::RemoveColumnInfo(string schema, string table, bool if_exists, string removed_column, - bool if_column_exists, bool cascade) - : AlterTableInfo(AlterTableType::REMOVE_COLUMN, move(schema), move(table), if_exists), - removed_column(move(removed_column)), if_column_exists(if_column_exists), cascade(cascade) { +RemoveColumnInfo::RemoveColumnInfo(AlterEntryData data, string removed_column, bool if_column_exists, bool cascade) + : AlterTableInfo(AlterTableType::REMOVE_COLUMN, std::move(data)), removed_column(std::move(removed_column)), + if_column_exists(if_column_exists), cascade(cascade) { } RemoveColumnInfo::~RemoveColumnInfo() { } unique_ptr RemoveColumnInfo::Copy() const { - return make_unique_base(schema, name, if_exists, removed_column, if_column_exists, + return make_unique_base(GetAlterEntryData(), removed_column, if_column_exists, cascade); } @@ -182420,26 +192446,26 @@ void RemoveColumnInfo::SerializeAlterTable(FieldWriter &writer) const { writer.WriteField(cascade); } -unique_ptr RemoveColumnInfo::Deserialize(FieldReader &reader, string schema, string table, bool if_exists) { +unique_ptr RemoveColumnInfo::Deserialize(FieldReader &reader, AlterEntryData data) { auto new_name = reader.ReadRequired(); auto if_column_exists = reader.ReadRequired(); auto cascade = reader.ReadRequired(); - return make_unique(move(schema), move(table), if_exists, new_name, if_column_exists, cascade); + return make_unique(std::move(data), std::move(new_name), if_column_exists, cascade); } //===--------------------------------------------------------------------===// // ChangeColumnTypeInfo //===--------------------------------------------------------------------===// -ChangeColumnTypeInfo::ChangeColumnTypeInfo(string schema_p, string table_p, bool if_exists_p, string column_name, - LogicalType target_type, unique_ptr expression) - : AlterTableInfo(AlterTableType::ALTER_COLUMN_TYPE, move(schema_p), move(table_p), if_exists_p), - column_name(move(column_name)), target_type(move(target_type)), expression(move(expression)) { +ChangeColumnTypeInfo::ChangeColumnTypeInfo(AlterEntryData data, string column_name, LogicalType target_type, + unique_ptr expression) + : AlterTableInfo(AlterTableType::ALTER_COLUMN_TYPE, std::move(data)), column_name(std::move(column_name)), + target_type(std::move(target_type)), expression(std::move(expression)) { } ChangeColumnTypeInfo::~ChangeColumnTypeInfo() { } unique_ptr ChangeColumnTypeInfo::Copy() const { - return make_unique_base(schema, name, if_exists, column_name, target_type, + return make_unique_base(GetAlterEntryData(), column_name, target_type, expression->Copy()); } @@ -182449,28 +192475,26 @@ void ChangeColumnTypeInfo::SerializeAlterTable(FieldWriter &writer) const { writer.WriteOptional(expression); } -unique_ptr ChangeColumnTypeInfo::Deserialize(FieldReader &reader, string schema, string table, - bool if_exists) { +unique_ptr ChangeColumnTypeInfo::Deserialize(FieldReader &reader, AlterEntryData data) { auto column_name = reader.ReadRequired(); auto target_type = reader.ReadRequiredSerializable(); auto expression = reader.ReadOptional(nullptr); - return make_unique(move(schema), move(table), if_exists, move(column_name), move(target_type), - move(expression)); + return make_unique(std::move(data), std::move(column_name), std::move(target_type), + std::move(expression)); } //===--------------------------------------------------------------------===// // SetDefaultInfo //===--------------------------------------------------------------------===// -SetDefaultInfo::SetDefaultInfo(string schema_p, string table_p, bool if_exists_p, string column_name_p, - unique_ptr new_default) - : AlterTableInfo(AlterTableType::SET_DEFAULT, move(schema_p), move(table_p), if_exists_p), - column_name(move(column_name_p)), expression(move(new_default)) { +SetDefaultInfo::SetDefaultInfo(AlterEntryData data, string column_name_p, unique_ptr new_default) + : AlterTableInfo(AlterTableType::SET_DEFAULT, std::move(data)), column_name(std::move(column_name_p)), + expression(std::move(new_default)) { } SetDefaultInfo::~SetDefaultInfo() { } unique_ptr SetDefaultInfo::Copy() const { - return make_unique_base(schema, name, if_exists, column_name, + return make_unique_base(GetAlterEntryData(), column_name, expression ? expression->Copy() : nullptr); } @@ -182479,74 +192503,71 @@ void SetDefaultInfo::SerializeAlterTable(FieldWriter &writer) const { writer.WriteOptional(expression); } -unique_ptr SetDefaultInfo::Deserialize(FieldReader &reader, string schema, string table, bool if_exists) { +unique_ptr SetDefaultInfo::Deserialize(FieldReader &reader, AlterEntryData data) { auto column_name = reader.ReadRequired(); auto new_default = reader.ReadOptional(nullptr); - return make_unique(move(schema), move(table), if_exists, move(column_name), move(new_default)); + return make_unique(std::move(data), std::move(column_name), std::move(new_default)); } //===--------------------------------------------------------------------===// // SetNotNullInfo //===--------------------------------------------------------------------===// -SetNotNullInfo::SetNotNullInfo(string schema_p, string table_p, bool if_exists_p, string column_name_p) - : AlterTableInfo(AlterTableType::SET_NOT_NULL, move(schema_p), move(table_p), if_exists_p), - column_name(move(column_name_p)) { +SetNotNullInfo::SetNotNullInfo(AlterEntryData data, string column_name_p) + : AlterTableInfo(AlterTableType::SET_NOT_NULL, std::move(data)), column_name(std::move(column_name_p)) { } SetNotNullInfo::~SetNotNullInfo() { } unique_ptr SetNotNullInfo::Copy() const { - return make_unique_base(schema, name, if_exists, column_name); + return make_unique_base(GetAlterEntryData(), column_name); } void SetNotNullInfo::SerializeAlterTable(FieldWriter &writer) const { writer.WriteString(column_name); } -unique_ptr SetNotNullInfo::Deserialize(FieldReader &reader, string schema, string table, bool if_exists) { +unique_ptr SetNotNullInfo::Deserialize(FieldReader &reader, AlterEntryData data) { auto column_name = reader.ReadRequired(); - return make_unique(move(schema), move(table), if_exists, move(column_name)); + return make_unique(std::move(data), std::move(column_name)); } //===--------------------------------------------------------------------===// // DropNotNullInfo //===--------------------------------------------------------------------===// -DropNotNullInfo::DropNotNullInfo(string schema_p, string table_p, bool if_exists_p, string column_name_p) - : AlterTableInfo(AlterTableType::DROP_NOT_NULL, move(schema_p), move(table_p), if_exists_p), - column_name(move(column_name_p)) { +DropNotNullInfo::DropNotNullInfo(AlterEntryData data, string column_name_p) + : AlterTableInfo(AlterTableType::DROP_NOT_NULL, std::move(data)), column_name(std::move(column_name_p)) { } DropNotNullInfo::~DropNotNullInfo() { } unique_ptr DropNotNullInfo::Copy() const { - return make_unique_base(schema, name, if_exists, column_name); + return make_unique_base(GetAlterEntryData(), column_name); } void DropNotNullInfo::SerializeAlterTable(FieldWriter &writer) const { writer.WriteString(column_name); } -unique_ptr DropNotNullInfo::Deserialize(FieldReader &reader, string schema, string table, bool if_exists) { +unique_ptr DropNotNullInfo::Deserialize(FieldReader &reader, AlterEntryData data) { auto column_name = reader.ReadRequired(); - return make_unique(move(schema), move(table), if_exists, move(column_name)); + return make_unique(std::move(data), std::move(column_name)); } //===--------------------------------------------------------------------===// // AlterForeignKeyInfo //===--------------------------------------------------------------------===// -AlterForeignKeyInfo::AlterForeignKeyInfo(string schema_p, string table_p, bool if_exists_p, string fk_table, - vector pk_columns, vector fk_columns, - vector pk_keys, vector fk_keys, - AlterForeignKeyType type_p) - : AlterTableInfo(AlterTableType::FOREIGN_KEY_CONSTRAINT, move(schema_p), move(table_p), if_exists_p), - fk_table(move(fk_table)), pk_columns(move(pk_columns)), fk_columns(move(fk_columns)), pk_keys(move(pk_keys)), - fk_keys(move(fk_keys)), type(type_p) { +AlterForeignKeyInfo::AlterForeignKeyInfo(AlterEntryData data, string fk_table, vector pk_columns, + vector fk_columns, vector pk_keys, + vector fk_keys, AlterForeignKeyType type_p) + : AlterTableInfo(AlterTableType::FOREIGN_KEY_CONSTRAINT, std::move(data)), fk_table(std::move(fk_table)), + pk_columns(std::move(pk_columns)), fk_columns(std::move(fk_columns)), pk_keys(std::move(pk_keys)), + fk_keys(std::move(fk_keys)), type(type_p) { } AlterForeignKeyInfo::~AlterForeignKeyInfo() { } unique_ptr AlterForeignKeyInfo::Copy() const { - return make_unique_base(schema, name, if_exists, fk_table, pk_columns, fk_columns, + return make_unique_base(GetAlterEntryData(), fk_table, pk_columns, fk_columns, pk_keys, fk_keys, type); } @@ -182559,23 +192580,24 @@ void AlterForeignKeyInfo::SerializeAlterTable(FieldWriter &writer) const { writer.WriteField(type); } -unique_ptr AlterForeignKeyInfo::Deserialize(FieldReader &reader, string schema, string table, - bool if_exists) { +unique_ptr AlterForeignKeyInfo::Deserialize(FieldReader &reader, AlterEntryData data) { auto fk_table = reader.ReadRequired(); auto pk_columns = reader.ReadRequiredList(); auto fk_columns = reader.ReadRequiredList(); auto pk_keys = reader.ReadRequiredIndexList(); auto fk_keys = reader.ReadRequiredIndexList(); auto type = reader.ReadRequired(); - return make_unique(move(schema), move(table), if_exists, move(fk_table), move(pk_columns), - move(fk_columns), move(pk_keys), move(fk_keys), type); + return make_unique(std::move(data), std::move(fk_table), std::move(pk_columns), + std::move(fk_columns), std::move(pk_keys), std::move(fk_keys), type); } //===--------------------------------------------------------------------===// // Alter View //===--------------------------------------------------------------------===// -AlterViewInfo::AlterViewInfo(AlterViewType type, string schema_p, string view_p, bool if_exists_p) - : AlterInfo(AlterType::ALTER_VIEW, move(schema_p), move(view_p), if_exists_p), alter_view_type(type) { +AlterViewInfo::AlterViewInfo(AlterViewType type, AlterEntryData data) + : AlterInfo(AlterType::ALTER_VIEW, std::move(data.catalog), std::move(data.schema), std::move(data.name), + data.if_exists), + alter_view_type(type) { } AlterViewInfo::~AlterViewInfo() { } @@ -182586,6 +192608,7 @@ CatalogType AlterViewInfo::GetCatalogType() const { void AlterViewInfo::Serialize(FieldWriter &writer) const { writer.WriteField(alter_view_type); + writer.WriteString(catalog); writer.WriteString(schema); writer.WriteString(name); writer.WriteField(if_exists); @@ -182594,13 +192617,15 @@ void AlterViewInfo::Serialize(FieldWriter &writer) const { unique_ptr AlterViewInfo::Deserialize(FieldReader &reader) { auto type = reader.ReadRequired(); - auto schema = reader.ReadRequired(); - auto view = reader.ReadRequired(); - auto if_exists = reader.ReadRequired(); + AlterEntryData data; + data.catalog = reader.ReadRequired(); + data.schema = reader.ReadRequired(); + data.name = reader.ReadRequired(); + data.if_exists = reader.ReadRequired(); unique_ptr info; switch (type) { case AlterViewType::RENAME_VIEW: - return RenameViewInfo::Deserialize(reader, schema, view, if_exists); + return RenameViewInfo::Deserialize(reader, std::move(data)); default: throw SerializationException("Unknown alter view type for deserialization!"); } @@ -182609,25 +192634,95 @@ unique_ptr AlterViewInfo::Deserialize(FieldReader &reader) { //===--------------------------------------------------------------------===// // RenameViewInfo //===--------------------------------------------------------------------===// -RenameViewInfo::RenameViewInfo(string schema_p, string view_p, bool if_exists_p, string new_name_p) - : AlterViewInfo(AlterViewType::RENAME_VIEW, move(schema_p), move(view_p), if_exists_p), - new_view_name(move(new_name_p)) { +RenameViewInfo::RenameViewInfo(AlterEntryData data, string new_name_p) + : AlterViewInfo(AlterViewType::RENAME_VIEW, std::move(data)), new_view_name(std::move(new_name_p)) { } RenameViewInfo::~RenameViewInfo() { } unique_ptr RenameViewInfo::Copy() const { - return make_unique_base(schema, name, if_exists, new_view_name); + return make_unique_base(GetAlterEntryData(), new_view_name); } void RenameViewInfo::SerializeAlterView(FieldWriter &writer) const { writer.WriteString(new_view_name); } -unique_ptr RenameViewInfo::Deserialize(FieldReader &reader, string schema, string view, bool if_exists) { +unique_ptr RenameViewInfo::Deserialize(FieldReader &reader, AlterEntryData data) { auto new_name = reader.ReadRequired(); - return make_unique(move(schema), move(view), if_exists, new_name); + return make_unique(std::move(data), new_name); +} +} // namespace duckdb + + +namespace duckdb { + +CreateAggregateFunctionInfo::CreateAggregateFunctionInfo(AggregateFunction function) + : CreateFunctionInfo(CatalogType::AGGREGATE_FUNCTION_ENTRY), functions(function.name) { + name = function.name; + functions.AddFunction(std::move(function)); + internal = true; +} + +CreateAggregateFunctionInfo::CreateAggregateFunctionInfo(AggregateFunctionSet set) + : CreateFunctionInfo(CatalogType::AGGREGATE_FUNCTION_ENTRY), functions(std::move(set)) { + name = functions.name; + for (auto &func : functions.functions) { + func.name = functions.name; + } + internal = true; } + +unique_ptr CreateAggregateFunctionInfo::Copy() const { + auto result = make_unique(functions); + CopyProperties(*result); + return std::move(result); +} + +} // namespace duckdb + + +namespace duckdb { + +CreateCollationInfo::CreateCollationInfo(string name_p, ScalarFunction function_p, bool combinable_p, + bool not_required_for_equality_p) + : CreateInfo(CatalogType::COLLATION_ENTRY), function(std::move(function_p)), combinable(combinable_p), + not_required_for_equality(not_required_for_equality_p) { + this->name = std::move(name_p); + internal = true; +} + +void CreateCollationInfo::SerializeInternal(Serializer &) const { + throw NotImplementedException("Cannot serialize '%s'", CatalogTypeToString(type)); +} + +unique_ptr CreateCollationInfo::Copy() const { + auto result = make_unique(name, function, combinable, not_required_for_equality); + CopyProperties(*result); + return std::move(result); +} + +} // namespace duckdb + + +namespace duckdb { + +CreateCopyFunctionInfo::CreateCopyFunctionInfo(CopyFunction function_p) + : CreateInfo(CatalogType::COPY_FUNCTION_ENTRY), function(std::move(function_p)) { + this->name = function.name; + internal = true; +} + +void CreateCopyFunctionInfo::SerializeInternal(Serializer &) const { + throw NotImplementedException("Cannot serialize '%s'", CatalogTypeToString(type)); +} + +unique_ptr CreateCopyFunctionInfo::Copy() const { + auto result = make_unique(function); + CopyProperties(*result); + return std::move(result); +} + } // namespace duckdb @@ -182651,7 +192746,7 @@ unique_ptr CreateIndexInfo::Copy() const { result->scan_types = scan_types; result->names = names; result->column_ids = column_ids; - return move(result); + return std::move(result); } void CreateIndexInfo::SerializeInternal(Serializer &serializer) const { @@ -182698,10 +192793,62 @@ unique_ptr CreateIndexInfo::Deserialize(Deserializer &deseriali +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/parsed_data/create_database_info.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +struct CreateDatabaseInfo : public CreateInfo { + CreateDatabaseInfo() : CreateInfo(CatalogType::DATABASE_ENTRY) { + } + + //! Extension name which creates databases + string extension_name; + + //! Name of the database + string name; + + //! Source path of the database if it's created from another database + string path; + +public: + unique_ptr Copy() const override { + auto result = make_unique(); + CopyProperties(*result); + result->extension_name = extension_name; + result->name = name; + result->path = path; + return unique_ptr(result.release()); + } + + static unique_ptr Deserialize(Deserializer &deserializer) { + auto result = make_unique(); + result->DeserializeBase(deserializer); + return result; + } + +protected: + void SerializeInternal(Serializer &) const override { + throw NotImplementedException("Cannot serialize '%s'", CatalogTypeToString(type)); + } +}; + +} // namespace duckdb + namespace duckdb { void CreateInfo::DeserializeBase(Deserializer &deserializer) { + this->catalog = deserializer.Read(); this->schema = deserializer.Read(); this->on_conflict = deserializer.Read(); this->temporary = deserializer.Read(); @@ -182711,6 +192858,7 @@ void CreateInfo::DeserializeBase(Deserializer &deserializer) { void CreateInfo::Serialize(Serializer &serializer) const { serializer.Write(type); + serializer.WriteString(catalog); serializer.WriteString(schema); serializer.Write(on_conflict); serializer.Write(temporary); @@ -182730,6 +192878,8 @@ unique_ptr CreateInfo::Deserialize(Deserializer &deserializer) { return CreateSchemaInfo::Deserialize(deserializer); case CatalogType::VIEW_ENTRY: return CreateViewInfo::Deserialize(deserializer); + case CatalogType::DATABASE_ENTRY: + return CreateDatabaseInfo::Deserialize(deserializer); default: throw NotImplementedException("Cannot deserialize '%s'", CatalogTypeToString(type)); } @@ -182741,6 +192891,7 @@ unique_ptr CreateInfo::Deserialize(Deserializer &source, PlanDeseria void CreateInfo::CopyProperties(CreateInfo &other) const { other.type = type; + other.catalog = catalog; other.schema = schema; other.on_conflict = on_conflict; other.temporary = temporary; @@ -182755,44 +192906,104 @@ unique_ptr CreateInfo::GetAlterInfo() const { } // namespace duckdb +namespace duckdb { + +CreatePragmaFunctionInfo::CreatePragmaFunctionInfo(PragmaFunction function) + : CreateFunctionInfo(CatalogType::PRAGMA_FUNCTION_ENTRY), functions(function.name) { + name = function.name; + functions.AddFunction(std::move(function)); + internal = true; +} +CreatePragmaFunctionInfo::CreatePragmaFunctionInfo(string name, PragmaFunctionSet functions_p) + : CreateFunctionInfo(CatalogType::PRAGMA_FUNCTION_ENTRY), functions(std::move(functions_p)) { + this->name = std::move(name); + internal = true; +} + +unique_ptr CreatePragmaFunctionInfo::Copy() const { + auto result = make_unique(functions.name, functions); + CopyProperties(*result); + return std::move(result); +} + +} // namespace duckdb + + namespace duckdb { CreateScalarFunctionInfo::CreateScalarFunctionInfo(ScalarFunction function) : CreateFunctionInfo(CatalogType::SCALAR_FUNCTION_ENTRY), functions(function.name) { name = function.name; - functions.AddFunction(move(function)); + functions.AddFunction(std::move(function)); + internal = true; } CreateScalarFunctionInfo::CreateScalarFunctionInfo(ScalarFunctionSet set) - : CreateFunctionInfo(CatalogType::SCALAR_FUNCTION_ENTRY), functions(move(set)) { + : CreateFunctionInfo(CatalogType::SCALAR_FUNCTION_ENTRY), functions(std::move(set)) { name = functions.name; for (auto &func : functions.functions) { func.name = functions.name; } + internal = true; } unique_ptr CreateScalarFunctionInfo::Copy() const { ScalarFunctionSet set(name); set.functions = functions.functions; - auto result = make_unique(move(set)); + auto result = make_unique(std::move(set)); CopyProperties(*result); - return move(result); + return std::move(result); } unique_ptr CreateScalarFunctionInfo::GetAlterInfo() const { - return make_unique_base(schema, name, true, functions); + return make_unique_base(AlterEntryData(catalog, schema, name, true), functions); +} + +} // namespace duckdb + + +namespace duckdb { + +CreateTableFunctionInfo::CreateTableFunctionInfo(TableFunction function) + : CreateFunctionInfo(CatalogType::TABLE_FUNCTION_ENTRY), functions(function.name) { + name = function.name; + functions.AddFunction(std::move(function)); + internal = true; +} +CreateTableFunctionInfo::CreateTableFunctionInfo(TableFunctionSet set) + : CreateFunctionInfo(CatalogType::TABLE_FUNCTION_ENTRY), functions(std::move(set)) { + name = functions.name; + for (auto &func : functions.functions) { + func.name = functions.name; + } + internal = true; +} + +unique_ptr CreateTableFunctionInfo::Copy() const { + TableFunctionSet set(name); + set.functions = functions.functions; + auto result = make_unique(std::move(set)); + CopyProperties(*result); + return std::move(result); } } // namespace duckdb + + + namespace duckdb { CreateTableInfo::CreateTableInfo() : CreateInfo(CatalogType::TABLE_ENTRY, INVALID_SCHEMA) { } -CreateTableInfo::CreateTableInfo(string schema_p, string name_p) - : CreateInfo(CatalogType::TABLE_ENTRY, move(schema_p)), table(move(name_p)) { +CreateTableInfo::CreateTableInfo(string catalog_p, string schema_p, string name_p) + : CreateInfo(CatalogType::TABLE_ENTRY, std::move(schema_p), std::move(catalog_p)), table(std::move(name_p)) { +} + +CreateTableInfo::CreateTableInfo(SchemaCatalogEntry *schema, string name_p) + : CreateTableInfo(schema->catalog->GetName(), schema->name, std::move(name_p)) { } void CreateTableInfo::SerializeInternal(Serializer &serializer) const { @@ -182819,7 +193030,7 @@ unique_ptr CreateTableInfo::Deserialize(Deserializer &deseriali } unique_ptr CreateTableInfo::Copy() const { - auto result = make_unique(schema, table); + auto result = make_unique(catalog, schema, table); CopyProperties(*result); result->columns = columns.Copy(); for (auto &constraint : constraints) { @@ -182828,7 +193039,109 @@ unique_ptr CreateTableInfo::Copy() const { if (query) { result->query = unique_ptr_cast(query->Copy()); } - return move(result); + return std::move(result); +} + +} // namespace duckdb + + + + + + + + +namespace duckdb { + +CreateViewInfo::CreateViewInfo() : CreateInfo(CatalogType::VIEW_ENTRY, INVALID_SCHEMA) { +} +CreateViewInfo::CreateViewInfo(string catalog_p, string schema_p, string view_name_p) + : CreateInfo(CatalogType::VIEW_ENTRY, std::move(schema_p), std::move(catalog_p)), + view_name(std::move(view_name_p)) { +} + +CreateViewInfo::CreateViewInfo(SchemaCatalogEntry *schema, string view_name) + : CreateViewInfo(schema->catalog->GetName(), schema->name, std::move(view_name)) { +} + +unique_ptr CreateViewInfo::Copy() const { + auto result = make_unique(catalog, schema, view_name); + CopyProperties(*result); + result->aliases = aliases; + result->types = types; + result->query = unique_ptr_cast(query->Copy()); + return std::move(result); +} + +unique_ptr CreateViewInfo::Deserialize(Deserializer &deserializer) { + auto result = make_unique(); + result->DeserializeBase(deserializer); + + FieldReader reader(deserializer); + result->view_name = reader.ReadRequired(); + result->aliases = reader.ReadRequiredList(); + result->types = reader.ReadRequiredSerializableList(); + result->query = reader.ReadOptional(nullptr); + reader.Finalize(); + + return result; +} + +void CreateViewInfo::SerializeInternal(Serializer &serializer) const { + FieldWriter writer(serializer); + writer.WriteString(view_name); + writer.WriteList(aliases); + writer.WriteRegularSerializableList(types); + writer.WriteOptional(query); + writer.Finalize(); +} + +unique_ptr CreateViewInfo::FromSelect(ClientContext &context, unique_ptr info) { + D_ASSERT(info); + D_ASSERT(!info->view_name.empty()); + D_ASSERT(!info->sql.empty()); + D_ASSERT(!info->query); + + Parser parser; + parser.ParseQuery(info->sql); + if (parser.statements.size() != 1 || parser.statements[0]->type != StatementType::SELECT_STATEMENT) { + throw BinderException( + "Failed to create view from SQL string - \"%s\" - statement did not contain a single SELECT statement", + info->sql); + } + D_ASSERT(parser.statements.size() == 1 && parser.statements[0]->type == StatementType::SELECT_STATEMENT); + info->query = unique_ptr_cast(std::move(parser.statements[0])); + + auto binder = Binder::CreateBinder(context); + binder->BindCreateViewInfo(*info); + + return info; +} + +unique_ptr CreateViewInfo::FromCreateView(ClientContext &context, const string &sql) { + D_ASSERT(!sql.empty()); + + // parse the SQL statement + Parser parser; + parser.ParseQuery(sql); + + if (parser.statements.size() != 1 || parser.statements[0]->type != StatementType::CREATE_STATEMENT) { + throw BinderException( + "Failed to create view from SQL string - \"%s\" - statement did not contain a single CREATE VIEW statement", + sql); + } + auto &create_statement = (CreateStatement &)*parser.statements[0]; + if (create_statement.info->type != CatalogType::VIEW_ENTRY) { + throw BinderException( + "Failed to create view from SQL string - \"%s\" - view did not contain a CREATE VIEW statement", sql); + } + + auto result = unique_ptr_cast(std::move(create_statement.info)); + + auto binder = Binder::CreateBinder(context); + binder->BindCreateViewInfo(*result); + + return result; } } // namespace duckdb @@ -182968,40 +193281,40 @@ bool ParsedExpression::Equals(const BaseExpression *other) const { } switch (expression_class) { case ExpressionClass::BETWEEN: - return BetweenExpression::Equals((BetweenExpression *)this, (BetweenExpression *)other); + return BetweenExpression::Equal((BetweenExpression *)this, (BetweenExpression *)other); case ExpressionClass::CASE: - return CaseExpression::Equals((CaseExpression *)this, (CaseExpression *)other); + return CaseExpression::Equal((CaseExpression *)this, (CaseExpression *)other); case ExpressionClass::CAST: - return CastExpression::Equals((CastExpression *)this, (CastExpression *)other); + return CastExpression::Equal((CastExpression *)this, (CastExpression *)other); case ExpressionClass::COLLATE: - return CollateExpression::Equals((CollateExpression *)this, (CollateExpression *)other); + return CollateExpression::Equal((CollateExpression *)this, (CollateExpression *)other); case ExpressionClass::COLUMN_REF: - return ColumnRefExpression::Equals((ColumnRefExpression *)this, (ColumnRefExpression *)other); + return ColumnRefExpression::Equal((ColumnRefExpression *)this, (ColumnRefExpression *)other); case ExpressionClass::COMPARISON: - return ComparisonExpression::Equals((ComparisonExpression *)this, (ComparisonExpression *)other); + return ComparisonExpression::Equal((ComparisonExpression *)this, (ComparisonExpression *)other); case ExpressionClass::CONJUNCTION: - return ConjunctionExpression::Equals((ConjunctionExpression *)this, (ConjunctionExpression *)other); + return ConjunctionExpression::Equal((ConjunctionExpression *)this, (ConjunctionExpression *)other); case ExpressionClass::CONSTANT: - return ConstantExpression::Equals((ConstantExpression *)this, (ConstantExpression *)other); + return ConstantExpression::Equal((ConstantExpression *)this, (ConstantExpression *)other); case ExpressionClass::DEFAULT: return true; case ExpressionClass::FUNCTION: - return FunctionExpression::Equals((FunctionExpression *)this, (FunctionExpression *)other); + return FunctionExpression::Equal((FunctionExpression *)this, (FunctionExpression *)other); case ExpressionClass::LAMBDA: - return LambdaExpression::Equals((LambdaExpression *)this, (LambdaExpression *)other); + return LambdaExpression::Equal((LambdaExpression *)this, (LambdaExpression *)other); case ExpressionClass::OPERATOR: - return OperatorExpression::Equals((OperatorExpression *)this, (OperatorExpression *)other); + return OperatorExpression::Equal((OperatorExpression *)this, (OperatorExpression *)other); case ExpressionClass::PARAMETER: - return ParameterExpression::Equals((ParameterExpression *)this, (ParameterExpression *)other); + return ParameterExpression::Equal((ParameterExpression *)this, (ParameterExpression *)other); case ExpressionClass::POSITIONAL_REFERENCE: - return PositionalReferenceExpression::Equals((PositionalReferenceExpression *)this, - (PositionalReferenceExpression *)other); + return PositionalReferenceExpression::Equal((PositionalReferenceExpression *)this, + (PositionalReferenceExpression *)other); case ExpressionClass::STAR: - return StarExpression::Equals((StarExpression *)this, (StarExpression *)other); + return StarExpression::Equal((StarExpression *)this, (StarExpression *)other); case ExpressionClass::SUBQUERY: - return SubqueryExpression::Equals((SubqueryExpression *)this, (SubqueryExpression *)other); + return SubqueryExpression::Equal((SubqueryExpression *)this, (SubqueryExpression *)other); case ExpressionClass::WINDOW: - return WindowExpression::Equals((WindowExpression *)this, (WindowExpression *)other); + return WindowExpression::Equal((WindowExpression *)this, (WindowExpression *)other); default: throw SerializationException("Unsupported type for expression comparison!"); } @@ -183148,7 +193461,6 @@ class RecursiveCTENode : public QueryNode { - //===----------------------------------------------------------------------===// // DuckDB // @@ -183375,12 +193687,6 @@ void ParsedExpressionIterator::EnumerateQueryNodeModifiers( void ParsedExpressionIterator::EnumerateTableRefChildren( TableRef &ref, const std::function &child)> &callback) { switch (ref.type) { - case TableReferenceType::CROSS_PRODUCT: { - auto &cp_ref = (CrossProductRef &)ref; - EnumerateTableRefChildren(*cp_ref.left, callback); - EnumerateTableRefChildren(*cp_ref.right, callback); - break; - } case TableReferenceType::EXPRESSION_LIST: { auto &el_ref = (ExpressionListRef &)ref; for (idx_t i = 0; i < el_ref.values.size(); i++) { @@ -183413,7 +193719,8 @@ void ParsedExpressionIterator::EnumerateTableRefChildren( case TableReferenceType::EMPTY: // these TableRefs do not need to be unfolded break; - default: + case TableReferenceType::INVALID: + case TableReferenceType::CTE: throw NotImplementedException("TableRef type not implemented for traversal"); } } @@ -183492,6 +193799,7 @@ void ParsedExpressionIterator::EnumerateQueryNodeChildren( + // LICENSE_CHANGE_BEGIN // The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #14 // See the end of this file for a list @@ -184365,6 +194673,9 @@ typedef enum PGNodeTag { T_PGPragmaStmt, T_PGExportStmt, T_PGImportStmt, + T_PGAttachStmt, + T_PGCreateDatabaseStmt, + T_PGUseStmt, /* * TAGS FOR PARSE TREE NODES (parsenodes.h) @@ -184606,7 +194917,12 @@ typedef enum PGJoinType { * by the executor (nor, indeed, by most of the planner). */ PG_JOIN_UNIQUE_OUTER, /* LHS path must be made unique */ - PG_JOIN_UNIQUE_INNER /* RHS path must be made unique */ + PG_JOIN_UNIQUE_INNER, /* RHS path must be made unique */ + + /* + * Positional joins are essentially parallel table scans. + */ + PG_JOIN_POSITION /* Two tables of the same length */ /* * We might need additional join types someday. @@ -184702,6 +195018,18 @@ typedef enum PGOnConflictAction { PG_ONCONFLICT_UPDATE /* ON CONFLICT ... DO UPDATE */ } PGOnConflictAction; +/* + * PGOnConflictActionAlias - + * "INSERT OR [REPLACE|IGNORE]" aliases for OnConflictAction + * + * This is needed in both parsenodes.h and plannodes.h, so put it here... + */ +typedef enum PGOnConflictActionAlias { + PG_ONCONFLICT_ALIAS_NONE, /* No "OR [IGNORE|REPLACE]" clause */ + PG_ONCONFLICT_ALIAS_REPLACE, /* INSERT OR REPLACE */ + PG_ONCONFLICT_ALIAS_IGNORE /* INSERT OR IGNORE */ +} PGOnConflictActionAlias; + } @@ -186640,6 +196968,7 @@ typedef struct PGParamRef { PGNodeTag type; int number; /* the number of the parameter */ int location; /* token location, or -1 if unknown */ + char *name; /* optional name of the parameter */ } PGParamRef; /* @@ -187564,6 +197893,7 @@ typedef struct PGInsertStmt { PGRangeVar *relation; /* relation to insert into */ PGList *cols; /* optional: names of the target columns */ PGNode *selectStmt; /* the source SELECT/VALUES, or NULL */ + PGOnConflictActionAlias onConflictAlias; /* the (optional) shorthand provided for the onConflictClause */ PGOnConflictClause *onConflictClause; /* ON CONFLICT clause */ PGList *returningList; /* list of expressions to return */ PGWithClause *withClause; /* WITH clause */ @@ -187762,6 +198092,7 @@ typedef enum PGObjectType { */ typedef struct PGCreateSchemaStmt { PGNodeTag type; + char *catalogname; /* the name of the catalog in which to create the schema */ char *schemaname; /* the name of the schema to create */ PGList *schemaElts; /* schema components (list of parsenodes) */ PGOnCreateConflict onconflict; /* what to do on create conflict */ @@ -188331,6 +198662,7 @@ typedef struct PGCreateTableAsStmt { typedef struct PGCheckPointStmt { PGNodeTag type; bool force; + char *name; } PGCheckPointStmt; /* ---------------------- @@ -188399,6 +198731,7 @@ typedef struct PGCallStmt { typedef struct PGExportStmt { PGNodeTag type; + char *database; /* database name */ char *filename; /* filename */ PGList *options; /* PGList of PGDefElem nodes */ } PGExportStmt; @@ -188482,13 +198815,47 @@ typedef struct PGCreateTypeStmt { PGNodeTag type; PGNewTypeKind kind; - PGList *typeName; /* qualified name (list of Value strings) */ + PGRangeVar *typeName; /* qualified name (list of Value strings) */ PGList *vals; /* enum values (list of Value strings) */ PGTypeName *ofType; /* original type of alias name */ PGNode *query; } PGCreateTypeStmt; +/* ---------------------- + * Attach Statement + * ---------------------- + */ +typedef struct PGAttachStmt +{ + PGNodeTag type; + char *path; /* The file path of the to-be-attached database */ + char *name; /* The name of the attached database */ + PGList *options; /* PGList of PGDefElem nodes */ + PGNode *query; +} PGAttachStmt; + +/* ---------------------- + * CREATE DATABASE Statement + * ---------------------- + */ +typedef struct PGCreateDatabaseStmt +{ + PGNodeTag type; + PGRangeVar *name; /* The name of the created database */ + char *extension; /* The name of the extension which will create the database */ + char *path; /* The file path of the to-be-created database */ +} PGCreateDatabaseStmt; + +/* ---------------------- + * Use Statement + * ---------------------- + */ + +typedef struct PGUseStmt { + PGNodeTag type; + PGRangeVar *name; /* variable to be set */ +} PGUseStmt; @@ -188506,6 +198873,8 @@ struct OrderByNode; struct CopyInfo; struct CommonTableExpressionInfo; struct GroupingExpressionMap; +class OnConflictInfo; +class UpdateSetInfo; //! The transformer class is responsible for transforming the internal Postgres //! parser representation into the DuckDB representation @@ -188529,6 +198898,8 @@ class Transformer { idx_t max_expression_depth; //! The current prepared statement parameter index idx_t prepared_statement_parameter_index = 0; + //! Map from named parameter to parameter index; + case_insensitive_map_t named_param_map; //! Holds window expressions defined by name. We need those when transforming the expressions referring to them. unordered_map window_clauses; @@ -188539,6 +198910,29 @@ class Transformer { this->prepared_statement_parameter_index = new_count; } } + void SetNamedParam(const string &name, int32_t index) { + if (parent) { + parent->SetNamedParam(name, index); + } else { + D_ASSERT(!named_param_map.count(name)); + this->named_param_map[name] = index; + } + } + bool GetNamedParam(const string &name, int32_t &index) { + if (parent) { + return parent->GetNamedParam(name, index); + } else { + auto entry = named_param_map.find(name); + if (entry == named_param_map.end()) { + return false; + } + index = entry->second; + return true; + } + } + bool HasNamedParameters() const { + return parent ? parent->HasNamedParameters() : !named_param_map.empty(); + } private: //! Transforms a Postgres statement into a single SQL statement @@ -188570,12 +198964,21 @@ class Transformer { unique_ptr TransformCreateFunction(duckdb_libpgquery::PGNode *node); //! Transform a Postgres duckdb_libpgquery::T_PGCreateTypeStmt node into CreateStatement unique_ptr TransformCreateType(duckdb_libpgquery::PGNode *node); + //! Transform a Postgres duckdb_libpgquery::T_PGCreateDatabaseStmt node into a CreateStatement + unique_ptr TransformCreateDatabase(duckdb_libpgquery::PGNode *node); //! Transform a Postgres duckdb_libpgquery::T_PGAlterSeqStmt node into CreateStatement unique_ptr TransformAlterSequence(duckdb_libpgquery::PGNode *node); //! Transform a Postgres duckdb_libpgquery::T_PGDropStmt node into a Drop[Table,Schema]Statement unique_ptr TransformDrop(duckdb_libpgquery::PGNode *node); //! Transform a Postgres duckdb_libpgquery::T_PGInsertStmt node into a InsertStatement unique_ptr TransformInsert(duckdb_libpgquery::PGNode *node); + + //! Transform a Postgres duckdb_libpgquery::T_PGOnConflictClause node into a OnConflictInfo + unique_ptr TransformOnConflictClause(duckdb_libpgquery::PGOnConflictClause *node, + const string &relname); + //! Transform a ON CONFLICT shorthand into a OnConflictInfo + unique_ptr DummyOnConflictClause(duckdb_libpgquery::PGOnConflictActionAlias type, + const string &relname); //! Transform a Postgres duckdb_libpgquery::T_PGCopyStmt node into a CopyStatement unique_ptr TransformCopy(duckdb_libpgquery::PGNode *node); void TransformCopyOptions(CopyInfo &info, duckdb_libpgquery::PGList *options); @@ -188595,12 +198998,21 @@ class Transformer { unique_ptr TransformVacuum(duckdb_libpgquery::PGNode *node); unique_ptr TransformShow(duckdb_libpgquery::PGNode *node); unique_ptr TransformShowSelect(duckdb_libpgquery::PGNode *node); + unique_ptr TransformAttach(duckdb_libpgquery::PGNode *node); + unique_ptr TransformUse(duckdb_libpgquery::PGNode *node); unique_ptr TransformPrepare(duckdb_libpgquery::PGNode *node); unique_ptr TransformExecute(duckdb_libpgquery::PGNode *node); unique_ptr TransformCall(duckdb_libpgquery::PGNode *node); unique_ptr TransformDeallocate(duckdb_libpgquery::PGNode *node); + + //===--------------------------------------------------------------------===// + // SetStatement Transform + //===--------------------------------------------------------------------===// unique_ptr TransformSet(duckdb_libpgquery::PGNode *node); + unique_ptr TransformSetVariable(duckdb_libpgquery::PGVariableSetStmt *stmt); + unique_ptr TransformResetVariable(duckdb_libpgquery::PGVariableSetStmt *stmt); + unique_ptr TransformCheckpoint(duckdb_libpgquery::PGNode *node); unique_ptr TransformLoad(duckdb_libpgquery::PGNode *node); @@ -188661,6 +199073,18 @@ class Transformer { unique_ptr TransformConstraint(duckdb_libpgquery::PGListCell *cell, ColumnDefinition &column, idx_t index); + //===--------------------------------------------------------------------===// + // Update transform + //===--------------------------------------------------------------------===// + unique_ptr TransformUpdateSetInfo(duckdb_libpgquery::PGList *target_list, + duckdb_libpgquery::PGNode *where_clause); + + //===--------------------------------------------------------------------===// + // Index transform + //===--------------------------------------------------------------------===// + vector> TransformIndexParameters(duckdb_libpgquery::PGList *list, + const string &relation_name); + //===--------------------------------------------------------------------===// // Collation transform //===--------------------------------------------------------------------===// @@ -188934,41 +199358,158 @@ namespace duckdb { Parser::Parser(ParserOptions options_p) : options(options_p) { } +struct UnicodeSpace { + UnicodeSpace(idx_t pos, idx_t bytes) : pos(pos), bytes(bytes) { + } + + idx_t pos; + idx_t bytes; +}; + +static bool ReplaceUnicodeSpaces(const string &query, string &new_query, vector &unicode_spaces) { + if (unicode_spaces.empty()) { + // no unicode spaces found + return false; + } + idx_t prev = 0; + for (auto &usp : unicode_spaces) { + new_query += query.substr(prev, usp.pos - prev); + new_query += " "; + prev = usp.pos + usp.bytes; + } + new_query += query.substr(prev, query.size() - prev); + return true; +} + +// This function strips unicode space characters from the query and replaces them with regular spaces +// It returns true if any unicode space characters were found and stripped +// See here for a list of unicode space characters - https://jkorpela.fi/chars/spaces.html +static bool StripUnicodeSpaces(const string &query_str, string &new_query) { + const idx_t NBSP_LEN = 2; + const idx_t USP_LEN = 3; + idx_t pos = 0; + unsigned char quote; + vector unicode_spaces; + auto query = (unsigned char *)query_str.c_str(); + auto qsize = query_str.size(); + +regular: + for (; pos + 2 < qsize; pos++) { + if (query[pos] == 0xC2) { + if (query[pos + 1] == 0xA0) { + // U+00A0 - C2A0 + unicode_spaces.emplace_back(pos, NBSP_LEN); + } + } + if (query[pos] == 0xE2) { + if (query[pos + 1] == 0x80) { + if (query[pos + 2] >= 0x80 && query[pos + 2] <= 0x8B) { + // U+2000 to U+200B + // E28080 - E2808B + unicode_spaces.emplace_back(pos, USP_LEN); + } else if (query[pos + 2] == 0xAF) { + // U+202F - E280AF + unicode_spaces.emplace_back(pos, USP_LEN); + } + } else if (query[pos + 1] == 0x81) { + if (query[pos + 2] == 0x9F) { + // U+205F - E2819f + unicode_spaces.emplace_back(pos, USP_LEN); + } else if (query[pos + 2] == 0xA0) { + // U+2060 - E281A0 + unicode_spaces.emplace_back(pos, USP_LEN); + } + } + } else if (query[pos] == 0xE3) { + if (query[pos + 1] == 0x80 && query[pos + 2] == 0x80) { + // U+3000 - E38080 + unicode_spaces.emplace_back(pos, USP_LEN); + } + } else if (query[pos] == 0xEF) { + if (query[pos + 1] == 0xBB && query[pos + 2] == 0xBF) { + // U+FEFF - EFBBBF + unicode_spaces.emplace_back(pos, USP_LEN); + } + } else if (query[pos] == '"' || query[pos] == '\'') { + quote = query[pos]; + pos++; + goto in_quotes; + } else if (query[pos] == '-' && query[pos + 1] == '-') { + goto in_comment; + } + } + goto end; +in_quotes: + for (; pos + 1 < qsize; pos++) { + if (query[pos] == quote) { + if (query[pos + 1] == quote) { + // escaped quote + pos++; + continue; + } + pos++; + goto regular; + } + } + goto end; +in_comment: + for (; pos < qsize; pos++) { + if (query[pos] == '\n' || query[pos] == '\r') { + goto regular; + } + } + goto end; +end: + return ReplaceUnicodeSpaces(query_str, new_query, unicode_spaces); +} + void Parser::ParseQuery(const string &query) { Transformer transformer(options.max_expression_depth); + string parser_error; + { + // check if there are any unicode spaces in the string + string new_query; + if (StripUnicodeSpaces(query, new_query)) { + // there are - strip the unicode spaces and re-run the query + ParseQuery(new_query); + return; + } + } { PostgresParser::SetPreserveIdentifierCase(options.preserve_identifier_case); PostgresParser parser; parser.Parse(query); + if (parser.success) { + if (!parser.parse_tree) { + // empty statement + return; + } - if (!parser.success) { - if (options.extensions) { - for (auto &ext : *options.extensions) { - D_ASSERT(ext.parse_function); - auto result = ext.parse_function(ext.parser_info.get(), query); - if (result.type == ParserExtensionResultType::PARSE_SUCCESSFUL) { - auto statement = make_unique(ext, move(result.parse_data)); - statement->stmt_length = query.size(); - statement->stmt_location = 0; - statements.push_back(move(statement)); - return; - } - if (result.type == ParserExtensionResultType::DISPLAY_EXTENSION_ERROR) { - throw ParserException(result.error); - } + // if it succeeded, we transform the Postgres parse tree into a list of + // SQLStatements + transformer.TransformParseTree(parser.parse_tree, statements); + } else { + parser_error = QueryErrorContext::Format(query, parser.error_message, parser.error_location - 1); + } + } + if (!parser_error.empty()) { + if (options.extensions) { + for (auto &ext : *options.extensions) { + D_ASSERT(ext.parse_function); + auto result = ext.parse_function(ext.parser_info.get(), query); + if (result.type == ParserExtensionResultType::PARSE_SUCCESSFUL) { + auto statement = make_unique(ext, std::move(result.parse_data)); + statement->stmt_length = query.size(); + statement->stmt_location = 0; + statements.push_back(std::move(statement)); + return; + } + if (result.type == ParserExtensionResultType::DISPLAY_EXTENSION_ERROR) { + throw ParserException(result.error); } } - throw ParserException(QueryErrorContext::Format(query, parser.error_message, parser.error_location - 1)); } - - if (!parser.parse_tree) { - // empty statement - return; - } - - // if it succeeded, we transform the Postgres parse tree into a list of - // SQLStatements - transformer.TransformParseTree(parser.parse_tree, statements); + throw ParserException(parser_error); } if (!statements.empty()) { auto &last_statement = statements.back(); @@ -189064,7 +199605,7 @@ vector> Parser::ParseExpressionList(const string &s throw ParserException("Expected a single SELECT node"); } auto &select_node = (SelectNode &)*select.node; - return move(select_node.select_list); + return std::move(select_node.select_list); } vector Parser::ParseOrderList(const string &select_list, ParserOptions options) { @@ -189087,7 +199628,7 @@ vector Parser::ParseOrderList(const string &select_list, ParserOpti throw ParserException("Expected a single ORDER clause"); } auto &order = (OrderModifier &)*select_node.modifiers[0]; - return move(order.orders); + return std::move(order.orders); } void Parser::ParseUpdateList(const string &update_list, vector &update_columns, @@ -189102,8 +199643,8 @@ void Parser::ParseUpdateList(const string &update_list, vector &update_c throw ParserException("Expected a single UPDATE statement"); } auto &update = (UpdateStatement &)*parser.statements[0]; - update_columns = move(update.columns); - expressions = move(update.expressions); + update_columns = std::move(update.set_info->columns); + expressions = std::move(update.set_info->expressions); } vector>> Parser::ParseValuesList(const string &value_list, ParserOptions options) { @@ -189125,7 +199666,7 @@ vector>> Parser::ParseValuesList(const strin throw ParserException("Expected a single VALUES statement"); } auto &values_list = (ExpressionListRef &)*select_node.from_table; - return move(values_list.values); + return std::move(values_list.values); } ColumnList Parser::ParseColumnList(const string &column_list, ParserOptions options) { @@ -189140,7 +199681,7 @@ ColumnList Parser::ParseColumnList(const string &column_list, ParserOptions opti throw InternalException("Expected a single CREATE TABLE statement"); } auto &info = ((CreateTableInfo &)*create.info); - return move(info.columns); + return std::move(info.columns); } } // namespace duckdb @@ -189310,7 +199851,7 @@ unique_ptr RecursiveCTENode::Copy() const { result->right = right->Copy(); result->aliases = aliases; this->CopyProperties(*result); - return move(result); + return std::move(result); } void RecursiveCTENode::Serialize(FieldWriter &writer) const { @@ -189328,7 +199869,7 @@ unique_ptr RecursiveCTENode::Deserialize(FieldReader &reader) { result->left = reader.ReadRequiredSerializable(); result->right = reader.ReadRequiredSerializable(); result->aliases = reader.ReadRequiredList(); - return move(result); + return std::move(result); } } // namespace duckdb @@ -189504,7 +200045,7 @@ unique_ptr SelectNode::Copy() const { result->qualify = qualify ? qualify->Copy() : nullptr; result->sample = sample ? sample->Copy() : nullptr; this->CopyProperties(*result); - return move(result); + return std::move(result); } void SelectNode::Serialize(FieldWriter &writer) const { @@ -189548,7 +200089,7 @@ unique_ptr SelectNode::Deserialize(FieldReader &reader) { result->having = reader.ReadOptional(nullptr); result->sample = reader.ReadOptional(nullptr); result->qualify = reader.ReadOptional(nullptr); - return move(result); + return std::move(result); } } // namespace duckdb @@ -189618,7 +200159,7 @@ unique_ptr SetOperationNode::Copy() const { result->left = left->Copy(); result->right = right->Copy(); this->CopyProperties(*result); - return move(result); + return std::move(result); } void SetOperationNode::Serialize(FieldWriter &writer) const { @@ -189632,7 +200173,7 @@ unique_ptr SetOperationNode::Deserialize(FieldReader &reader) { result->setop_type = reader.ReadRequired(); result->left = reader.ReadRequiredSerializable(); result->right = reader.ReadRequiredSerializable(); - return move(result); + return std::move(result); } } // namespace duckdb @@ -189657,7 +200198,7 @@ CommonTableExpressionMap CommonTableExpressionMap::Copy() const { kv_info->aliases.push_back(al); } kv_info->query = unique_ptr_cast(kv.second->query->Copy()); - res.map[kv.first] = move(kv_info); + res.map[kv.first] = std::move(kv_info); } return res; } @@ -189784,7 +200325,7 @@ void QueryNode::CopyProperties(QueryNode &other) const { kv_info->aliases.push_back(al); } kv_info->query = unique_ptr_cast(kv.second->query->Copy()); - other.cte_map.map[kv.first] = move(kv_info); + other.cte_map.map[kv.first] = std::move(kv_info); } } @@ -189818,7 +200359,7 @@ unique_ptr QueryNode::Deserialize(Deserializer &main_source) { auto info = make_unique(); source.ReadStringVector(info->aliases); info->query = SelectStatement::Deserialize(source); - new_map[name] = move(info); + new_map[name] = std::move(info); } unique_ptr result; switch (type) { @@ -189834,8 +200375,8 @@ unique_ptr QueryNode::Deserialize(Deserializer &main_source) { default: throw SerializationException("Could not deserialize Query Node: unknown type!"); } - result->modifiers = move(modifiers); - result->cte_map.map = move(new_map); + result->modifiers = std::move(modifiers); + result->cte_map.map = std::move(new_map); reader.Finalize(); return result; } @@ -189928,7 +200469,7 @@ unique_ptr LimitModifier::Copy() const { if (offset) { copy->offset = offset->Copy(); } - return move(copy); + return std::move(copy); } void LimitModifier::Serialize(FieldWriter &writer) const { @@ -189940,7 +200481,7 @@ unique_ptr LimitModifier::Deserialize(FieldReader &reader) { auto mod = make_unique(); mod->limit = reader.ReadOptional(nullptr); mod->offset = reader.ReadOptional(nullptr); - return move(mod); + return std::move(mod); } bool DistinctModifier::Equals(const ResultModifier *other_p) const { @@ -189959,7 +200500,7 @@ unique_ptr DistinctModifier::Copy() const { for (auto &expr : distinct_on_targets) { copy->distinct_on_targets.push_back(expr->Copy()); } - return move(copy); + return std::move(copy); } void DistinctModifier::Serialize(FieldWriter &writer) const { @@ -189969,7 +200510,7 @@ void DistinctModifier::Serialize(FieldWriter &writer) const { unique_ptr DistinctModifier::Deserialize(FieldReader &reader) { auto mod = make_unique(); mod->distinct_on_targets = reader.ReadRequiredSerializableList(); - return move(mod); + return std::move(mod); } bool OrderModifier::Equals(const ResultModifier *other_p) const { @@ -189996,7 +200537,7 @@ unique_ptr OrderModifier::Copy() const { for (auto &order : orders) { copy->orders.emplace_back(order.type, order.null_order, order.expression->Copy()); } - return move(copy); + return std::move(copy); } string OrderByNode::ToString() const { @@ -190039,7 +200580,7 @@ OrderByNode OrderByNode::Deserialize(Deserializer &source) { auto null_order = reader.ReadRequired(); auto expression = reader.ReadRequiredSerializable(); reader.Finalize(); - return OrderByNode(type, null_order, move(expression)); + return OrderByNode(type, null_order, std::move(expression)); } void OrderModifier::Serialize(FieldWriter &writer) const { @@ -190049,7 +200590,7 @@ void OrderModifier::Serialize(FieldWriter &writer) const { unique_ptr OrderModifier::Deserialize(FieldReader &reader) { auto mod = make_unique(); mod->orders = reader.ReadRequiredSerializableList(); - return move(mod); + return std::move(mod); } bool LimitPercentModifier::Equals(const ResultModifier *other_p) const { @@ -190074,7 +200615,7 @@ unique_ptr LimitPercentModifier::Copy() const { if (offset) { copy->offset = offset->Copy(); } - return move(copy); + return std::move(copy); } void LimitPercentModifier::Serialize(FieldWriter &writer) const { @@ -190086,7 +200627,7 @@ unique_ptr LimitPercentModifier::Deserialize(FieldReader &reader auto mod = make_unique(); mod->limit = reader.ReadOptional(nullptr); mod->offset = reader.ReadOptional(nullptr); - return move(mod); + return std::move(mod); } } // namespace duckdb @@ -190134,6 +200675,50 @@ unique_ptr AlterStatement::Copy() const { return unique_ptr(new AlterStatement(*this)); } +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/statement/attach_statement.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +class AttachStatement : public SQLStatement { +public: + AttachStatement(); + + unique_ptr info; + +protected: + AttachStatement(const AttachStatement &other); + +public: + unique_ptr Copy() const override; +}; + +} // namespace duckdb + + +namespace duckdb { + +AttachStatement::AttachStatement() : SQLStatement(StatementType::ATTACH_STATEMENT) { +} + +AttachStatement::AttachStatement(const AttachStatement &other) : SQLStatement(other), info(other.info->Copy()) { +} + +unique_ptr AttachStatement::Copy() const { + return unique_ptr(new AttachStatement(*this)); +} + } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB @@ -190192,6 +200777,108 @@ CopyStatement::CopyStatement(const CopyStatement &other) : SQLStatement(other), } } +string ConvertOptionValueToString(const Value &val) { + auto type = val.type().id(); + switch (type) { + case LogicalTypeId::VARCHAR: + return KeywordHelper::WriteOptionallyQuoted(val.ToString()); + default: + return val.ToString(); + } +} + +string CopyStatement::CopyOptionsToString(const string &format, + const case_insensitive_map_t> &options) const { + if (format.empty() && options.empty()) { + return string(); + } + string result; + + result += " ("; + if (!format.empty()) { + result += " FORMAT "; + result += format; + } + for (auto it = options.begin(); it != options.end(); it++) { + if (!format.empty() || it != options.begin()) { + result += ", "; + } + auto &name = it->first; + auto &values = it->second; + + result += name + " "; + if (values.empty()) { + // Options like HEADER don't need an explicit value + // just providing the name already sets it to true + } else if (values.size() == 1) { + result += ConvertOptionValueToString(values[0]); + } else { + result += "( "; + for (idx_t i = 0; i < values.size(); i++) { + auto &value = values[i]; + if (i) { + result += ", "; + } + result += KeywordHelper::WriteOptionallyQuoted(value.ToString()); + } + result += " )"; + } + } + result += " )"; + return result; +} + +// COPY table-name (c1, c2, ..) +string TablePart(const CopyInfo &info) { + string result; + + if (!info.catalog.empty()) { + result += KeywordHelper::WriteOptionallyQuoted(info.catalog) + "."; + } + if (!info.schema.empty()) { + result += KeywordHelper::WriteOptionallyQuoted(info.schema) + "."; + } + D_ASSERT(!info.table.empty()); + result += KeywordHelper::WriteOptionallyQuoted(info.table); + + // (c1, c2, ..) + if (!info.select_list.empty()) { + result += " ("; + for (idx_t i = 0; i < info.select_list.size(); i++) { + if (i > 0) { + result += ", "; + } + result += KeywordHelper::WriteOptionallyQuoted(info.select_list[i]); + } + result += " )"; + } + return result; +} + +string CopyStatement::ToString() const { + string result; + + result += "COPY "; + if (info->is_from) { + D_ASSERT(!select_statement); + result += TablePart(*info); + result += " FROM"; + result += StringUtil::Format(" '%s'", info->file_path); + result += CopyOptionsToString(info->format, info->options); + } else { + if (select_statement) { + // COPY (select-node) TO ... + result += "(" + select_statement->ToString() + ")"; + } else { + result += TablePart(*info); + } + result += " TO "; + result += StringUtil::Format("'%s'", info->file_path); + result += CopyOptionsToString(info->format, info->options); + } + return result; +} + unique_ptr CopyStatement::Copy() const { return unique_ptr(new CopyStatement(*this)); } @@ -190303,7 +200990,7 @@ unique_ptr ExecuteStatement::Copy() const { namespace duckdb { ExplainStatement::ExplainStatement(unique_ptr stmt, ExplainType explain_type) - : SQLStatement(StatementType::EXPLAIN_STATEMENT), stmt(move(stmt)), explain_type(explain_type) { + : SQLStatement(StatementType::EXPLAIN_STATEMENT), stmt(std::move(stmt)), explain_type(explain_type) { } ExplainStatement::ExplainStatement(const ExplainStatement &other) @@ -190314,43 +201001,13 @@ unique_ptr ExplainStatement::Copy() const { return unique_ptr(new ExplainStatement(*this)); } -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/statement/export_statement.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - -namespace duckdb { - -class ExportStatement : public SQLStatement { -public: - explicit ExportStatement(unique_ptr info); - - unique_ptr info; - -protected: - ExportStatement(const ExportStatement &other); - -public: - unique_ptr Copy() const override; -}; - } // namespace duckdb namespace duckdb { ExportStatement::ExportStatement(unique_ptr info) - : SQLStatement(StatementType::EXPORT_STATEMENT), info(move(info)) { + : SQLStatement(StatementType::EXPORT_STATEMENT), info(std::move(info)) { } ExportStatement::ExportStatement(const ExportStatement &other) : SQLStatement(other), info(other.info->Copy()) { @@ -190366,7 +201023,8 @@ unique_ptr ExportStatement::Copy() const { namespace duckdb { ExtensionStatement::ExtensionStatement(ParserExtension extension_p, unique_ptr parse_data_p) - : SQLStatement(StatementType::EXTENSION_STATEMENT), extension(move(extension_p)), parse_data(move(parse_data_p)) { + : SQLStatement(StatementType::EXTENSION_STATEMENT), extension(std::move(extension_p)), + parse_data(std::move(parse_data_p)) { } unique_ptr ExtensionStatement::Copy() const { @@ -190378,26 +201036,75 @@ unique_ptr ExtensionStatement::Copy() const { + namespace duckdb { -InsertStatement::InsertStatement() : SQLStatement(StatementType::INSERT_STATEMENT), schema(DEFAULT_SCHEMA) { +OnConflictInfo::OnConflictInfo() : action_type(OnConflictAction::THROW) { +} + +OnConflictInfo::OnConflictInfo(const OnConflictInfo &other) + : action_type(other.action_type), indexed_columns(other.indexed_columns) { + if (other.set_info) { + set_info = other.set_info->Copy(); + } +} + +unique_ptr OnConflictInfo::Copy() const { + return unique_ptr(new OnConflictInfo(*this)); +} + +InsertStatement::InsertStatement() + : SQLStatement(StatementType::INSERT_STATEMENT), schema(DEFAULT_SCHEMA), catalog(INVALID_CATALOG) { } InsertStatement::InsertStatement(const InsertStatement &other) : SQLStatement(other), select_statement(unique_ptr_cast(other.select_statement->Copy())), - columns(other.columns), table(other.table), schema(other.schema) { + columns(other.columns), table(other.table), schema(other.schema), catalog(other.catalog) { cte_map = other.cte_map.Copy(); + if (other.on_conflict_info) { + on_conflict_info = other.on_conflict_info->Copy(); + } +} + +string InsertStatement::OnConflictActionToString(OnConflictAction action) { + switch (action) { + case OnConflictAction::NOTHING: + return "DO NOTHING"; + case OnConflictAction::REPLACE: + case OnConflictAction::UPDATE: + return "DO UPDATE"; + case OnConflictAction::THROW: + // Explicitly left empty, for ToString purposes + return ""; + default: { + throw NotImplementedException("type not implemented for OnConflictActionType"); + } + } } string InsertStatement::ToString() const { + bool or_replace_shorthand_set = false; string result; + result = cte_map.ToString(); - result += "INSERT INTO "; + result += "INSERT"; + if (on_conflict_info && on_conflict_info->action_type == OnConflictAction::REPLACE) { + or_replace_shorthand_set = true; + result += " OR REPLACE"; + } + result += " INTO "; + if (!catalog.empty()) { + result += KeywordHelper::WriteOptionallyQuoted(catalog) + "."; + } if (!schema.empty()) { result += KeywordHelper::WriteOptionallyQuoted(schema) + "."; } result += KeywordHelper::WriteOptionallyQuoted(table); + // Write the (optional) alias of the insert target + if (table_ref && !table_ref->alias.empty()) { + result += StringUtil::Format(" AS %s", KeywordHelper::WriteOptionallyQuoted(table_ref->alias)); + } if (!columns.empty()) { result += " ("; for (idx_t i = 0; i < columns.size(); i++) { @@ -190416,6 +201123,47 @@ string InsertStatement::ToString() const { } else { result += select_statement->ToString(); } + if (!or_replace_shorthand_set && on_conflict_info) { + auto &conflict_info = *on_conflict_info; + result += " ON CONFLICT "; + // (optional) conflict target + if (!conflict_info.indexed_columns.empty()) { + result += "("; + auto &columns = conflict_info.indexed_columns; + for (auto it = columns.begin(); it != columns.end();) { + result += StringUtil::Lower(*it); + if (++it != columns.end()) { + result += ", "; + } + } + result += " )"; + } + + // (optional) where clause + if (conflict_info.condition) { + result += " WHERE " + conflict_info.condition->ToString(); + } + result += " " + OnConflictActionToString(conflict_info.action_type); + if (conflict_info.set_info) { + D_ASSERT(conflict_info.action_type == OnConflictAction::UPDATE); + result += " SET "; + auto &set_info = *conflict_info.set_info; + D_ASSERT(set_info.columns.size() == set_info.expressions.size()); + // SET = + for (idx_t i = 0; i < set_info.columns.size(); i++) { + auto &column = set_info.columns[i]; + auto &expr = set_info.expressions[i]; + if (i) { + result += ", "; + } + result += StringUtil::Lower(column) + " = " + expr->ToString(); + } + // (optional) where clause + if (set_info.condition) { + result += " WHERE " + set_info.condition->ToString(); + } + } + } if (!returning_list.empty()) { result += " RETURNING "; for (idx_t i = 0; i < returning_list.size(); i++) { @@ -190538,7 +201286,7 @@ unique_ptr PrepareStatement::Copy() const { namespace duckdb { RelationStatement::RelationStatement(shared_ptr relation) - : SQLStatement(StatementType::RELATION_STATEMENT), relation(move(relation)) { + : SQLStatement(StatementType::RELATION_STATEMENT), relation(std::move(relation)) { } unique_ptr RelationStatement::Copy() const { @@ -190593,38 +201341,94 @@ string SelectStatement::ToString() const { +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/set_type.hpp +// +// +//===----------------------------------------------------------------------===// + + namespace duckdb { -class SetStatement : public SQLStatement { -public: - SetStatement(std::string name_p, Value value_p, SetScope scope_p); +enum class SetType : uint8_t { SET = 0, RESET = 1 }; + +} // namespace duckdb + + + +namespace duckdb { + +class SetStatement : public SQLStatement { protected: + SetStatement(std::string name_p, SetScope scope_p, SetType type_p); SetStatement(const SetStatement &other) = default; public: unique_ptr Copy() const override; +public: std::string name; - Value value; SetScope scope; + SetType set_type; }; + +class SetVariableStatement : public SetStatement { +public: + SetVariableStatement(std::string name_p, Value value_p, SetScope scope_p); + +protected: + SetVariableStatement(const SetVariableStatement &other) = default; + +public: + unique_ptr Copy() const override; + +public: + Value value; +}; + +class ResetVariableStatement : public SetStatement { +public: + ResetVariableStatement(std::string name_p, SetScope scope_p); + +protected: + ResetVariableStatement(const ResetVariableStatement &other) = default; +}; + } // namespace duckdb namespace duckdb { -SetStatement::SetStatement(std::string name_p, Value value_p, SetScope scope_p) - : SQLStatement(StatementType::SET_STATEMENT), name(move(name_p)), value(move(value_p)), scope(scope_p) { +SetStatement::SetStatement(std::string name_p, SetScope scope_p, SetType type_p) + : SQLStatement(StatementType::SET_STATEMENT), name(std::move(name_p)), scope(scope_p), set_type(type_p) { } unique_ptr SetStatement::Copy() const { return unique_ptr(new SetStatement(*this)); } +// Set Variable + +SetVariableStatement::SetVariableStatement(std::string name_p, Value value_p, SetScope scope_p) + : SetStatement(std::move(name_p), scope_p, SetType::SET), value(std::move(value_p)) { +} + +unique_ptr SetVariableStatement::Copy() const { + return unique_ptr(new SetVariableStatement(*this)); +} + +// Reset Variable + +ResetVariableStatement::ResetVariableStatement(std::string name_p, SetScope scope_p) + : SetStatement(std::move(name_p), scope_p, SetType::RESET) { +} + } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB @@ -190720,24 +201524,39 @@ unique_ptr TransactionStatement::Copy() const { namespace duckdb { -UpdateStatement::UpdateStatement() : SQLStatement(StatementType::UPDATE_STATEMENT) { +UpdateSetInfo::UpdateSetInfo() { } -UpdateStatement::UpdateStatement(const UpdateStatement &other) - : SQLStatement(other), table(other.table->Copy()), columns(other.columns) { +UpdateSetInfo::UpdateSetInfo(const UpdateSetInfo &other) : columns(other.columns) { if (other.condition) { condition = other.condition->Copy(); } - if (other.from_table) { - from_table = other.from_table->Copy(); - } for (auto &expr : other.expressions) { expressions.emplace_back(expr->Copy()); } +} + +unique_ptr UpdateSetInfo::Copy() const { + return unique_ptr(new UpdateSetInfo(*this)); +} + +UpdateStatement::UpdateStatement() : SQLStatement(StatementType::UPDATE_STATEMENT) { +} + +UpdateStatement::UpdateStatement(const UpdateStatement &other) + : SQLStatement(other), table(other.table->Copy()), set_info(other.set_info->Copy()) { + if (other.from_table) { + from_table = other.from_table->Copy(); + } cte_map = other.cte_map.Copy(); } string UpdateStatement::ToString() const { + D_ASSERT(set_info); + auto &condition = set_info->condition; + auto &columns = set_info->columns; + auto &expressions = set_info->expressions; + string result; result = cte_map.ToString(); result += "UPDATE "; @@ -190829,8 +201648,10 @@ unique_ptr VacuumStatement::Copy() const { namespace duckdb { string BaseTableRef::ToString() const { - string schema = schema_name.empty() ? "" : KeywordHelper::WriteOptionallyQuoted(schema_name) + "."; - string result = schema + KeywordHelper::WriteOptionallyQuoted(table_name); + string result; + result += catalog_name.empty() ? "" : (KeywordHelper::WriteOptionallyQuoted(catalog_name) + "."); + result += schema_name.empty() ? "" : (KeywordHelper::WriteOptionallyQuoted(schema_name) + "."); + result += KeywordHelper::WriteOptionallyQuoted(table_name); return BaseToString(result, column_name_alias); } @@ -190839,14 +201660,15 @@ bool BaseTableRef::Equals(const TableRef *other_p) const { return false; } auto other = (BaseTableRef *)other_p; - return other->schema_name == schema_name && other->table_name == table_name && - column_name_alias == other->column_name_alias; + return other->catalog_name == catalog_name && other->schema_name == schema_name && + other->table_name == table_name && column_name_alias == other->column_name_alias; } void BaseTableRef::Serialize(FieldWriter &writer) const { writer.WriteString(schema_name); writer.WriteString(table_name); writer.WriteList(column_name_alias); + writer.WriteString(catalog_name); } unique_ptr BaseTableRef::Deserialize(FieldReader &reader) { @@ -190855,63 +201677,22 @@ unique_ptr BaseTableRef::Deserialize(FieldReader &reader) { result->schema_name = reader.ReadRequired(); result->table_name = reader.ReadRequired(); result->column_name_alias = reader.ReadRequiredList(); + result->catalog_name = reader.ReadField(INVALID_CATALOG); - return move(result); + return std::move(result); } unique_ptr BaseTableRef::Copy() { auto copy = make_unique(); + copy->catalog_name = catalog_name; copy->schema_name = schema_name; copy->table_name = table_name; copy->column_name_alias = column_name_alias; CopyProperties(*copy); - return move(copy); -} -} // namespace duckdb - - - - -namespace duckdb { - -string CrossProductRef::ToString() const { - return left->ToString() + ", " + right->ToString(); + return std::move(copy); } - -bool CrossProductRef::Equals(const TableRef *other_p) const { - if (!TableRef::Equals(other_p)) { - return false; - } - auto other = (CrossProductRef *)other_p; - return left->Equals(other->left.get()) && right->Equals(other->right.get()); -} - -unique_ptr CrossProductRef::Copy() { - auto copy = make_unique(); - copy->left = left->Copy(); - copy->right = right->Copy(); - copy->alias = alias; - return move(copy); -} - -void CrossProductRef::Serialize(FieldWriter &writer) const { - writer.WriteSerializable(*left); - writer.WriteSerializable(*right); -} - -unique_ptr CrossProductRef::Deserialize(FieldReader &reader) { - auto result = make_unique(); - - result->left = reader.ReadRequiredSerializable(); - result->right = reader.ReadRequiredSerializable(); - D_ASSERT(result->left); - D_ASSERT(result->right); - - return move(result); -} - } // namespace duckdb @@ -190996,12 +201777,12 @@ unique_ptr ExpressionListRef::Copy() { for (auto &val : val_list) { new_val_list.push_back(val->Copy()); } - result->values.push_back(move(new_val_list)); + result->values.push_back(std::move(new_val_list)); } result->expected_names = expected_names; result->expected_types = expected_types; CopyProperties(*result); - return move(result); + return std::move(result); } void ExpressionListRef::Serialize(FieldWriter &writer) const { @@ -191024,9 +201805,9 @@ unique_ptr ExpressionListRef::Deserialize(FieldReader &reader) { for (idx_t i = 0; i < value_list_size; i++) { vector> value_list; source.ReadList(value_list); - result->values.push_back(move(value_list)); + result->values.push_back(std::move(value_list)); } - return move(result); + return std::move(result); } } // namespace duckdb @@ -191040,10 +201821,21 @@ namespace duckdb { string JoinRef::ToString() const { string result; result = left->ToString() + " "; - if (is_natural) { + switch (ref_type) { + case JoinRefType::REGULAR: + result += JoinTypeToString(type) + " JOIN "; + break; + case JoinRefType::NATURAL: result += "NATURAL "; + result += JoinTypeToString(type) + " JOIN "; + break; + case JoinRefType::CROSS: + result += ", "; + break; + case JoinRefType::POSITIONAL: + result += "POSITIONAL JOIN "; + break; } - result += JoinTypeToString(type) + " JOIN "; result += right->ToString(); if (condition) { D_ASSERT(using_columns.empty()); @@ -191081,17 +201873,17 @@ bool JoinRef::Equals(const TableRef *other_p) const { } unique_ptr JoinRef::Copy() { - auto copy = make_unique(); + auto copy = make_unique(ref_type); copy->left = left->Copy(); copy->right = right->Copy(); if (condition) { copy->condition = condition->Copy(); } copy->type = type; - copy->is_natural = is_natural; + copy->ref_type = ref_type; copy->alias = alias; copy->using_columns = using_columns; - return move(copy); + return std::move(copy); } void JoinRef::Serialize(FieldWriter &writer) const { @@ -191099,19 +201891,19 @@ void JoinRef::Serialize(FieldWriter &writer) const { writer.WriteSerializable(*right); writer.WriteOptional(condition); writer.WriteField(type); - writer.WriteField(is_natural); + writer.WriteField(ref_type); writer.WriteList(using_columns); } unique_ptr JoinRef::Deserialize(FieldReader &reader) { - auto result = make_unique(); + auto result = make_unique(JoinRefType::REGULAR); result->left = reader.ReadRequiredSerializable(); result->right = reader.ReadRequiredSerializable(); result->condition = reader.ReadOptional(nullptr); result->type = reader.ReadRequired(); - result->is_natural = reader.ReadRequired(); + result->ref_type = reader.ReadRequired(); result->using_columns = reader.ReadRequiredList(); - return move(result); + return std::move(result); } } // namespace duckdb @@ -191128,8 +201920,8 @@ string SubqueryRef::ToString() const { } SubqueryRef::SubqueryRef(unique_ptr subquery_p, string alias_p) - : TableRef(TableReferenceType::SUBQUERY), subquery(move(subquery_p)) { - this->alias = move(alias_p); + : TableRef(TableReferenceType::SUBQUERY), subquery(std::move(subquery_p)) { + this->alias = std::move(alias_p); } bool SubqueryRef::Equals(const TableRef *other_p) const { @@ -191144,7 +201936,7 @@ unique_ptr SubqueryRef::Copy() { auto copy = make_unique(unique_ptr_cast(subquery->Copy()), alias); copy->column_name_alias = column_name_alias; CopyProperties(*copy); - return move(copy); + return std::move(copy); } void SubqueryRef::Serialize(FieldWriter &writer) const { @@ -191154,9 +201946,9 @@ void SubqueryRef::Serialize(FieldWriter &writer) const { unique_ptr SubqueryRef::Deserialize(FieldReader &reader) { auto subquery = reader.ReadRequiredSerializable(); - auto result = make_unique(move(subquery)); + auto result = make_unique(std::move(subquery)); result->column_name_alias = reader.ReadRequiredList(); - return move(result); + return std::move(result); } } // namespace duckdb @@ -191192,7 +201984,7 @@ unique_ptr TableFunctionRef::Deserialize(FieldReader &reader) { result->function = reader.ReadRequiredSerializable(); result->alias = reader.ReadRequired(); result->column_name_alias = reader.ReadRequiredList(); - return move(result); + return std::move(result); } unique_ptr TableFunctionRef::Copy() { @@ -191202,7 +201994,7 @@ unique_ptr TableFunctionRef::Copy() { copy->column_name_alias = column_name_alias; CopyProperties(*copy); - return move(copy); + return std::move(copy); } } // namespace duckdb @@ -191217,7 +202009,7 @@ namespace duckdb { string TableRef::BaseToString(string result) const { vector column_name_alias; - return BaseToString(move(result), column_name_alias); + return BaseToString(std::move(result), column_name_alias); } string TableRef::BaseToString(string result, const vector &column_name_alias) const { @@ -191271,9 +202063,6 @@ unique_ptr TableRef::Deserialize(Deserializer &source) { case TableReferenceType::BASE_TABLE: result = BaseTableRef::Deserialize(reader); break; - case TableReferenceType::CROSS_PRODUCT: - result = CrossProductRef::Deserialize(reader); - break; case TableReferenceType::JOIN: result = JoinRef::Deserialize(reader); break; @@ -191296,7 +202085,7 @@ unique_ptr TableRef::Deserialize(Deserializer &source) { reader.Finalize(); result->alias = alias; - result->sample = move(sample); + result->sample = std::move(sample); return result; } @@ -191319,6 +202108,18 @@ void TableRef::Print() { namespace duckdb { +static void ParseSchemaTableNameFK(duckdb_libpgquery::PGRangeVar *input, ForeignKeyInfo &fk_info) { + if (input->catalogname) { + throw ParserException("FOREIGN KEY constraints cannot be defined cross-database"); + } + if (input->schemaname) { + fk_info.schema = input->schemaname; + } else { + fk_info.schema = ""; + }; + fk_info.table = input->relname; +} + unique_ptr Transformer::TransformConstraint(duckdb_libpgquery::PGListCell *cell) { auto constraint = reinterpret_cast(cell->data.ptr_value); switch (constraint->contype) { @@ -191341,12 +202142,7 @@ unique_ptr Transformer::TransformConstraint(duckdb_libpgquery::PGLis case duckdb_libpgquery::PG_CONSTR_FOREIGN: { ForeignKeyInfo fk_info; fk_info.type = ForeignKeyType::FK_TYPE_FOREIGN_KEY_TABLE; - if (constraint->pktable->schemaname) { - fk_info.schema = constraint->pktable->schemaname; - } else { - fk_info.schema = ""; - } - fk_info.table = constraint->pktable->relname; + ParseSchemaTableNameFK(constraint->pktable, fk_info); vector pk_columns, fk_columns; for (auto kc = constraint->fk_attrs->head; kc; kc = kc->next) { fk_columns.emplace_back(reinterpret_cast(kc->data.ptr_value)->val.str); @@ -191362,7 +202158,7 @@ unique_ptr Transformer::TransformConstraint(duckdb_libpgquery::PGLis if (fk_columns.empty()) { throw ParserException("The set of referencing and referenced columns for foreign keys must be not empty"); } - return make_unique(pk_columns, fk_columns, move(fk_info)); + return make_unique(pk_columns, fk_columns, std::move(fk_info)); } default: throw NotImplementedException("Constraint type not handled yet!"); @@ -191406,14 +202202,9 @@ unique_ptr Transformer::TransformConstraint(duckdb_libpgquery::PGLis case duckdb_libpgquery::PG_CONSTR_FOREIGN: { ForeignKeyInfo fk_info; fk_info.type = ForeignKeyType::FK_TYPE_FOREIGN_KEY_TABLE; - if (constraint->pktable->schemaname) { - fk_info.schema = constraint->pktable->schemaname; - } else { - fk_info.schema = ""; - } - fk_info.table = constraint->pktable->relname; - vector pk_columns, fk_columns; + ParseSchemaTableNameFK(constraint->pktable, fk_info); + vector pk_columns, fk_columns; fk_columns.emplace_back(column.Name().c_str()); if (constraint->pk_attrs) { for (auto kc = constraint->pk_attrs->head; kc; kc = kc->next) { @@ -191423,7 +202214,7 @@ unique_ptr Transformer::TransformConstraint(duckdb_libpgquery::PGLis if (pk_columns.size() != fk_columns.size()) { throw ParserException("The number of referencing and referenced columns for foreign keys must be the same"); } - return make_unique(pk_columns, fk_columns, move(fk_info)); + return make_unique(pk_columns, fk_columns, std::move(fk_info)); } default: throw NotImplementedException("Constraint not implemented!"); @@ -191457,29 +202248,29 @@ unique_ptr Transformer::TransformArrayAccess(duckdb_libpgquery // index access (either slice or extract) auto index = (duckdb_libpgquery::PGAIndices *)target; vector> children; - children.push_back(move(result)); + children.push_back(std::move(result)); if (index->is_slice) { // slice children.push_back(!index->lidx ? make_unique(Value()) : TransformExpression(index->lidx)); children.push_back(!index->uidx ? make_unique(Value()) : TransformExpression(index->uidx)); - result = make_unique(ExpressionType::ARRAY_SLICE, move(children)); + result = make_unique(ExpressionType::ARRAY_SLICE, std::move(children)); } else { // array access D_ASSERT(!index->lidx); D_ASSERT(index->uidx); children.push_back(TransformExpression(index->uidx)); - result = make_unique(ExpressionType::ARRAY_EXTRACT, move(children)); + result = make_unique(ExpressionType::ARRAY_EXTRACT, std::move(children)); } break; } case duckdb_libpgquery::T_PGString: { auto val = (duckdb_libpgquery::PGValue *)target; vector> children; - children.push_back(move(result)); + children.push_back(std::move(result)); children.push_back(TransformValue(*val)); - result = make_unique(ExpressionType::STRUCT_EXTRACT, move(children)); + result = make_unique(ExpressionType::STRUCT_EXTRACT, std::move(children)); break; } default: @@ -191506,17 +202297,19 @@ unique_ptr Transformer::TransformBoolExpr(duckdb_libpgquery::P switch (root->boolop) { case duckdb_libpgquery::PG_AND_EXPR: { if (!result) { - result = move(next); + result = std::move(next); } else { - result = make_unique(ExpressionType::CONJUNCTION_AND, move(result), move(next)); + result = make_unique(ExpressionType::CONJUNCTION_AND, std::move(result), + std::move(next)); } break; } case duckdb_libpgquery::PG_OR_EXPR: { if (!result) { - result = move(next); + result = std::move(next); } else { - result = make_unique(ExpressionType::CONJUNCTION_OR, move(result), move(next)); + result = make_unique(ExpressionType::CONJUNCTION_OR, std::move(result), + std::move(next)); } break; } @@ -191524,15 +202317,15 @@ unique_ptr Transformer::TransformBoolExpr(duckdb_libpgquery::P if (next->type == ExpressionType::COMPARE_IN) { // convert COMPARE_IN to COMPARE_NOT_IN next->type = ExpressionType::COMPARE_NOT_IN; - result = move(next); + result = std::move(next); } else if (next->type >= ExpressionType::COMPARE_EQUAL && next->type <= ExpressionType::COMPARE_GREATERTHANOREQUALTO) { // NOT on a comparison: we can negate the comparison // e.g. NOT(x > y) is equivalent to x <= y next->type = NegateComparisionExpression(next->type); - result = move(next); + result = std::move(next); } else { - result = make_unique(ExpressionType::OPERATOR_NOT, move(next)); + result = make_unique(ExpressionType::OPERATOR_NOT, std::move(next)); } break; } @@ -191562,12 +202355,12 @@ unique_ptr Transformer::TransformCase(duckdb_libpgquery::PGCas auto arg = TransformExpression(reinterpret_cast(root->arg)); if (arg) { case_check.when_expr = - make_unique(ExpressionType::COMPARE_EQUAL, move(arg), move(test_raw)); + make_unique(ExpressionType::COMPARE_EQUAL, std::move(arg), std::move(test_raw)); } else { - case_check.when_expr = move(test_raw); + case_check.when_expr = std::move(test_raw); } case_check.then_expr = TransformExpression(reinterpret_cast(w->result)); - case_node->case_checks.push_back(move(case_check)); + case_node->case_checks.push_back(std::move(case_check)); } if (root->defresult) { @@ -191575,7 +202368,7 @@ unique_ptr Transformer::TransformCase(duckdb_libpgquery::PGCas } else { case_node->else_expr = make_unique(Value(LogicalType::SQLNULL)); } - return move(case_node); + return std::move(case_node); } } // namespace duckdb @@ -191606,7 +202399,7 @@ unique_ptr Transformer::TransformTypeCast(duckdb_libpgquery::P bool try_cast = root->tryCast; // now create a cast operation - return make_unique(target_type, move(expression), try_cast); + return make_unique(target_type, std::move(expression), try_cast); } } // namespace duckdb @@ -191627,9 +202420,9 @@ unique_ptr Transformer::TransformCoalesce(duckdb_libpgquery::P for (auto cell = coalesce_args->head; cell; cell = cell->next) { // get the value of the COALESCE auto value_expr = TransformExpression(reinterpret_cast(cell->data.ptr_value)); - coalesce_op->children.push_back(move(value_expr)); + coalesce_op->children.push_back(std::move(value_expr)); } - return move(coalesce_op); + return std::move(coalesce_op); } } // namespace duckdb @@ -191651,7 +202444,7 @@ unique_ptr Transformer::TransformStarExpression(duckdb_libpgqu if (result->exclude_list.find(exclude_entry) != result->exclude_list.end()) { throw ParserException("Duplicate entry \"%s\" in EXCLUDE list", exclude_entry); } - result->exclude_list.insert(move(exclude_entry)); + result->exclude_list.insert(std::move(exclude_entry)); } } if (star->replace_list) { @@ -191668,7 +202461,7 @@ unique_ptr Transformer::TransformStarExpression(duckdb_libpgqu if (result->exclude_list.find(exclude_entry) != result->exclude_list.end()) { throw ParserException("Column \"%s\" cannot occur in both EXCEPT and REPLACE list", exclude_entry); } - result->replace_list.insert(make_pair(move(exclude_entry), move(replace_expression))); + result->replace_list.insert(make_pair(std::move(exclude_entry), std::move(replace_expression))); } } if (star->regex) { @@ -191678,7 +202471,7 @@ unique_ptr Transformer::TransformStarExpression(duckdb_libpgqu result->regex = star->regex; } result->columns = star->columns; - return move(result); + return std::move(result); } unique_ptr Transformer::TransformColumnRef(duckdb_libpgquery::PGColumnRef *root) { @@ -191693,9 +202486,9 @@ unique_ptr Transformer::TransformColumnRef(duckdb_libpgquery:: for (auto node = fields->head; node; node = node->next) { column_names.emplace_back(reinterpret_cast(node->data.ptr_value)->val.str); } - auto colref = make_unique(move(column_names)); + auto colref = make_unique(std::move(column_names)); colref->query_location = root->location; - return move(colref); + return std::move(colref); } case duckdb_libpgquery::T_PGAStar: { return TransformStarExpression(head_node); @@ -191766,7 +202559,7 @@ unique_ptr Transformer::TransformValue(duckdb_libpgquery::PG // we can cast the value as a decimal Value val = Value(str_val); val = val.DefaultCastAs(LogicalType::DECIMAL(width, scale)); - return make_unique(move(val)); + return make_unique(std::move(val)); } } // if there is a decimal or the value is too big to cast as either hugeint or bigint @@ -191880,7 +202673,7 @@ void Transformer::TransformExpressionList(duckdb_libpgquery::PGList &list, auto expr = TransformExpression(target); D_ASSERT(expr); - result.push_back(move(expr)); + result.push_back(std::move(expr)); } } @@ -191983,15 +202776,24 @@ void Transformer::TransformWindowFrame(duckdb_libpgquery::PGWindowDef *window_sp unique_ptr Transformer::TransformFuncCall(duckdb_libpgquery::PGFuncCall *root) { auto name = root->funcname; - string schema, function_name; - if (name->length == 2) { + string catalog, schema, function_name; + if (name->length == 3) { + // catalog + schema + name + catalog = reinterpret_cast(name->head->data.ptr_value)->val.str; + schema = reinterpret_cast(name->head->next->data.ptr_value)->val.str; + function_name = reinterpret_cast(name->head->next->next->data.ptr_value)->val.str; + } else if (name->length == 2) { // schema + name + catalog = INVALID_CATALOG; schema = reinterpret_cast(name->head->data.ptr_value)->val.str; function_name = reinterpret_cast(name->head->next->data.ptr_value)->val.str; - } else { + } else if (name->length == 1) { // unqualified name + catalog = INVALID_CATALOG; schema = INVALID_SCHEMA; function_name = reinterpret_cast(name->head->data.ptr_value)->val.str; + } else { + throw InternalException("TransformFuncCall - Expected 1, 2 or 3 qualifications"); } auto lowercase_name = StringUtil::Lower(function_name); @@ -192021,12 +202823,12 @@ unique_ptr Transformer::TransformFuncCall(duckdb_libpgquery::P throw ParserException("IGNORE NULLS is not supported for windowed aggregates"); } - auto expr = make_unique(win_fun_type, schema, lowercase_name); + auto expr = make_unique(win_fun_type, std::move(catalog), std::move(schema), lowercase_name); expr->ignore_nulls = root->agg_ignore_nulls; if (root->agg_filter) { auto filter_expr = TransformExpression(root->agg_filter); - expr->filter_expr = move(filter_expr); + expr->filter_expr = std::move(filter_expr); } if (root->args) { @@ -192035,25 +202837,25 @@ unique_ptr Transformer::TransformFuncCall(duckdb_libpgquery::P if (win_fun_type == ExpressionType::WINDOW_AGGREGATE) { for (auto &child : function_list) { - expr->children.push_back(move(child)); + expr->children.push_back(std::move(child)); } } else { if (!function_list.empty()) { - expr->children.push_back(move(function_list[0])); + expr->children.push_back(std::move(function_list[0])); } if (win_fun_type == ExpressionType::WINDOW_LEAD || win_fun_type == ExpressionType::WINDOW_LAG) { if (function_list.size() > 1) { - expr->offset_expr = move(function_list[1]); + expr->offset_expr = std::move(function_list[1]); } if (function_list.size() > 2) { - expr->default_expr = move(function_list[2]); + expr->default_expr = std::move(function_list[2]); } if (function_list.size() > 3) { throw ParserException("Incorrect number of parameters for function %s", lowercase_name); } } else if (win_fun_type == ExpressionType::WINDOW_NTH_VALUE) { if (function_list.size() > 1) { - expr->children.push_back(move(function_list[1])); + expr->children.push_back(std::move(function_list[1])); } if (function_list.size() > 2) { throw ParserException("Incorrect number of parameters for function %s", lowercase_name); @@ -192086,7 +202888,7 @@ unique_ptr Transformer::TransformFuncCall(duckdb_libpgquery::P TransformWindowDef(window_ref, expr.get()); TransformWindowFrame(window_spec, expr.get()); expr->query_location = root->location; - return move(expr); + return std::move(expr); } if (root->agg_ignore_nulls) { @@ -192098,7 +202900,7 @@ unique_ptr Transformer::TransformFuncCall(duckdb_libpgquery::P if (root->args != nullptr) { for (auto node = root->args->head; node != nullptr; node = node->next) { auto child_expr = TransformExpression((duckdb_libpgquery::PGNode *)node->data.ptr_value); - children.push_back(move(child_expr)); + children.push_back(std::move(child_expr)); } } unique_ptr filter_expr; @@ -192148,15 +202950,15 @@ unique_ptr Transformer::TransformFuncCall(duckdb_libpgquery::P } auto expr = make_unique(); CaseCheck check; - check.when_expr = move(children[0]); - check.then_expr = move(children[1]); - expr->case_checks.push_back(move(check)); - expr->else_expr = move(children[2]); - return move(expr); + check.when_expr = std::move(children[0]); + check.then_expr = std::move(children[1]); + expr->case_checks.push_back(std::move(check)); + expr->else_expr = std::move(children[2]); + return std::move(expr); } else if (lowercase_name == "construct_array") { auto construct_array = make_unique(ExpressionType::ARRAY_CONSTRUCTOR); - construct_array->children = move(children); - return move(construct_array); + construct_array->children = std::move(children); + return std::move(construct_array); } else if (lowercase_name == "ifnull") { if (children.size() != 2) { throw ParserException("Wrong number of arguments to IFNULL."); @@ -192164,16 +202966,17 @@ unique_ptr Transformer::TransformFuncCall(duckdb_libpgquery::P // Two-argument COALESCE auto coalesce_op = make_unique(ExpressionType::OPERATOR_COALESCE); - coalesce_op->children.push_back(move(children[0])); - coalesce_op->children.push_back(move(children[1])); - return move(coalesce_op); + coalesce_op->children.push_back(std::move(children[0])); + coalesce_op->children.push_back(std::move(children[1])); + return std::move(coalesce_op); } - auto function = make_unique(schema, lowercase_name.c_str(), move(children), move(filter_expr), - move(order_bys), root->agg_distinct, false, root->export_state); + auto function = make_unique(std::move(catalog), std::move(schema), lowercase_name.c_str(), + std::move(children), std::move(filter_expr), std::move(order_bys), + root->agg_distinct, false, root->export_state); function->query_location = root->location; - return move(function); + return std::move(function); } static string SQLValueOpToString(duckdb_libpgquery::PGSQLValueFunctionOp op) { @@ -192217,7 +203020,7 @@ unique_ptr Transformer::TransformSQLValueFunction(duckdb_libpg D_ASSERT(node); vector> children; auto fname = SQLValueOpToString(node->op); - return make_unique(DEFAULT_SCHEMA, fname, move(children)); + return make_unique(fname, std::move(children)); } } // namespace duckdb @@ -192233,7 +203036,7 @@ unique_ptr Transformer::TransformGroupingFunction(duckdb_libpg op->children.push_back(TransformExpression(n)); } op->query_location = n->location; - return move(op); + return std::move(op); } } // namespace duckdb @@ -192268,7 +203071,7 @@ unique_ptr Transformer::TransformInterval(duckdb_libpgquery::P } if (!node->typmods) { - return make_unique(LogicalType::INTERVAL, move(expr)); + return make_unique(LogicalType::INTERVAL, std::move(expr)); } int32_t mask = ((duckdb_libpgquery::PGAConst *)node->typmods->head->data.ptr_value)->val.val.ival; @@ -192348,11 +203151,11 @@ unique_ptr Transformer::TransformInterval(duckdb_libpgquery::P throw InternalException("Unsupported interval post-fix"); } // first push a cast to the target type - expr = make_unique(target_type, move(expr)); + expr = make_unique(target_type, std::move(expr)); // now push the operation vector> children; - children.push_back(move(expr)); - return make_unique(fname, move(children)); + children.push_back(std::move(expr)); + return make_unique(fname, std::move(children)); } } // namespace duckdb @@ -192372,7 +203175,7 @@ unique_ptr Transformer::TransformNullTest(duckdb_libpgquery::P ? ExpressionType::OPERATOR_IS_NULL : ExpressionType::OPERATOR_IS_NOT_NULL; - return unique_ptr(new OperatorExpression(expr_type, move(arg))); + return unique_ptr(new OperatorExpression(expr_type, std::move(arg))); } } // namespace duckdb @@ -192391,7 +203194,7 @@ unique_ptr Transformer::TransformLambda(duckdb_libpgquery::PGL auto rhs = TransformExpression(node->rhs); D_ASSERT(lhs); D_ASSERT(rhs); - return make_unique(move(lhs), move(rhs)); + return make_unique(std::move(lhs), std::move(rhs)); } } // namespace duckdb @@ -192412,45 +203215,41 @@ unique_ptr Transformer::TransformLambda(duckdb_libpgquery::PGL namespace duckdb { unique_ptr Transformer::TransformUnaryOperator(const string &op, unique_ptr child) { - const auto schema = DEFAULT_SCHEMA; - vector> children; - children.push_back(move(child)); + children.push_back(std::move(child)); // built-in operator function - auto result = make_unique(schema, op, move(children)); + auto result = make_unique(op, std::move(children)); result->is_operator = true; - return move(result); + return std::move(result); } unique_ptr Transformer::TransformBinaryOperator(const string &op, unique_ptr left, unique_ptr right) { - const auto schema = DEFAULT_SCHEMA; - vector> children; - children.push_back(move(left)); - children.push_back(move(right)); + children.push_back(std::move(left)); + children.push_back(std::move(right)); if (op == "~" || op == "!~") { // rewrite 'asdf' SIMILAR TO '.*sd.*' into regexp_full_match('asdf', '.*sd.*') bool invert_similar = op == "!~"; - auto result = make_unique(schema, "regexp_full_match", move(children)); + auto result = make_unique("regexp_full_match", std::move(children)); if (invert_similar) { - return make_unique(ExpressionType::OPERATOR_NOT, move(result)); + return make_unique(ExpressionType::OPERATOR_NOT, std::move(result)); } else { - return move(result); + return std::move(result); } } else { auto target_type = OperatorToExpressionType(op); if (target_type != ExpressionType::INVALID) { // built-in comparison operator - return make_unique(target_type, move(children[0]), move(children[1])); + return make_unique(target_type, std::move(children[0]), std::move(children[1])); } // not a special operator: convert to a function expression - auto result = make_unique(schema, op, move(children)); + auto result = make_unique(op, std::move(children)); result->is_operator = true; - return move(result); + return std::move(result); } } @@ -192470,14 +203269,14 @@ unique_ptr Transformer::TransformAExprInternal(duckdb_libpgque auto select_statement = make_unique(); auto select_node = make_unique(); vector> children; - children.push_back(move(right_expr)); + children.push_back(std::move(right_expr)); - select_node->select_list.push_back(make_unique("UNNEST", move(children))); + select_node->select_list.push_back(make_unique("UNNEST", std::move(children))); select_node->from_table = make_unique(); - select_statement->node = move(select_node); - subquery_expr->subquery = move(select_statement); + select_statement->node = std::move(select_node); + subquery_expr->subquery = std::move(select_statement); subquery_expr->subquery_type = SubqueryType::ANY; - subquery_expr->child = move(left_expr); + subquery_expr->child = std::move(left_expr); subquery_expr->comparison_type = OperatorToExpressionType(name); subquery_expr->query_location = root->location; @@ -192486,9 +203285,9 @@ unique_ptr Transformer::TransformAExprInternal(duckdb_libpgque // e.g. [= ALL()] is equivalent to [NOT(<> ANY())] // first invert the comparison type subquery_expr->comparison_type = NegateComparisionExpression(subquery_expr->comparison_type); - return make_unique(ExpressionType::OPERATOR_NOT, move(subquery_expr)); + return make_unique(ExpressionType::OPERATOR_NOT, std::move(subquery_expr)); } - return move(subquery_expr); + return std::move(subquery_expr); } case duckdb_libpgquery::PG_AEXPR_IN: { auto left_expr = TransformExpression(root->lexpr); @@ -192501,17 +203300,17 @@ unique_ptr Transformer::TransformAExprInternal(duckdb_libpgque // IN operator_type = ExpressionType::COMPARE_IN; } - auto result = make_unique(operator_type, move(left_expr)); + auto result = make_unique(operator_type, std::move(left_expr)); result->query_location = root->location; TransformExpressionList(*((duckdb_libpgquery::PGList *)root->rexpr), result->children); - return move(result); + return std::move(result); } // rewrite NULLIF(a, b) into CASE WHEN a=b THEN NULL ELSE a END case duckdb_libpgquery::PG_AEXPR_NULLIF: { vector> children; children.push_back(TransformExpression(root->lexpr)); children.push_back(TransformExpression(root->rexpr)); - return make_unique("nullif", move(children)); + return make_unique("nullif", std::move(children)); } // rewrite (NOT) X BETWEEN A AND B into (NOT) AND(GREATERTHANOREQUALTO(X, // A), LESSTHANOREQUALTO(X, B)) @@ -192528,11 +203327,12 @@ unique_ptr Transformer::TransformAExprInternal(duckdb_libpgque auto between_right = TransformExpression(reinterpret_cast(between_args->tail->data.ptr_value)); - auto compare_between = make_unique(move(input), move(between_left), move(between_right)); + auto compare_between = + make_unique(std::move(input), std::move(between_left), std::move(between_right)); if (root->kind == duckdb_libpgquery::PG_AEXPR_BETWEEN) { - return move(compare_between); + return std::move(compare_between); } else { - return make_unique(ExpressionType::OPERATOR_NOT, move(compare_between)); + return make_unique(ExpressionType::OPERATOR_NOT, std::move(compare_between)); } } // rewrite SIMILAR TO into regexp_full_match('asdf', '.*sd.*') @@ -192541,7 +203341,7 @@ unique_ptr Transformer::TransformAExprInternal(duckdb_libpgque auto right_expr = TransformExpression(root->rexpr); vector> children; - children.push_back(move(left_expr)); + children.push_back(std::move(left_expr)); auto &similar_func = reinterpret_cast(*right_expr); D_ASSERT(similar_func.function_name == "similar_escape"); @@ -192554,7 +203354,7 @@ unique_ptr Transformer::TransformAExprInternal(duckdb_libpgque throw NotImplementedException("Custom escape in SIMILAR TO"); } // take the child of the similar_func - children.push_back(move(similar_func.children[0])); + children.push_back(std::move(similar_func.children[0])); // this looks very odd, but seems to be the way to find out its NOT IN bool invert_similar = false; @@ -192562,27 +203362,26 @@ unique_ptr Transformer::TransformAExprInternal(duckdb_libpgque // NOT SIMILAR TO invert_similar = true; } - const auto schema = DEFAULT_SCHEMA; const auto regex_function = "regexp_full_match"; - auto result = make_unique(schema, regex_function, move(children)); + auto result = make_unique(regex_function, std::move(children)); if (invert_similar) { - return make_unique(ExpressionType::OPERATOR_NOT, move(result)); + return make_unique(ExpressionType::OPERATOR_NOT, std::move(result)); } else { - return move(result); + return std::move(result); } } case duckdb_libpgquery::PG_AEXPR_NOT_DISTINCT: { auto left_expr = TransformExpression(root->lexpr); auto right_expr = TransformExpression(root->rexpr); - return make_unique(ExpressionType::COMPARE_NOT_DISTINCT_FROM, move(left_expr), - move(right_expr)); + return make_unique(ExpressionType::COMPARE_NOT_DISTINCT_FROM, std::move(left_expr), + std::move(right_expr)); } case duckdb_libpgquery::PG_AEXPR_DISTINCT: { auto left_expr = TransformExpression(root->lexpr); auto right_expr = TransformExpression(root->rexpr); - return make_unique(ExpressionType::COMPARE_DISTINCT_FROM, move(left_expr), - move(right_expr)); + return make_unique(ExpressionType::COMPARE_DISTINCT_FROM, std::move(left_expr), + std::move(right_expr)); } default: @@ -192593,12 +203392,12 @@ unique_ptr Transformer::TransformAExprInternal(duckdb_libpgque if (!left_expr) { // prefix operator - return TransformUnaryOperator(name, move(right_expr)); + return TransformUnaryOperator(name, std::move(right_expr)); } else if (!right_expr) { // postfix operator, only ! is currently supported - return TransformUnaryOperator(name + "__postfix", move(left_expr)); + return TransformUnaryOperator(name + "__postfix", std::move(left_expr)); } else { - return TransformBinaryOperator(name, move(left_expr), move(right_expr)); + return TransformBinaryOperator(name, std::move(left_expr), std::move(right_expr)); } } @@ -192623,13 +203422,36 @@ unique_ptr Transformer::TransformParamRef(duckdb_libpgquery::P if (node->number < 0) { throw ParserException("Parameter numbers cannot be negative"); } + + if (node->name) { + // This is a named parameter, try to find an entry for it + D_ASSERT(node->number == 0); + int32_t index; + if (GetNamedParam(node->name, index)) { + // We've seen this named parameter before and assigned it an index! + node->number = index; + } + } if (node->number == 0) { expr->parameter_nr = ParamCount() + 1; + if (node->name && !HasNamedParameters() && ParamCount() != 0) { + // This parameter is named, but there were other parameter before it, and they were not named + throw NotImplementedException("Mixing positional and named parameters is not supported yet"); + } + if (node->name) { + D_ASSERT(!named_param_map.count(node->name)); + // Add it to the named parameter map so we can find it next time it's referenced + SetNamedParam(node->name, expr->parameter_nr); + } } else { + if (!node->name && HasNamedParameters()) { + // This parameter does not have a name, but the named param map is not empty + throw NotImplementedException("Mixing positional and named parameters is not supported yet"); + } expr->parameter_nr = node->number; } SetParamCount(MaxValue(ParamCount(), expr->parameter_nr)); - return move(expr); + return std::move(expr); } } // namespace duckdb @@ -192645,7 +203467,7 @@ unique_ptr Transformer::TransformPositionalReference(duckdb_li } auto result = make_unique(node->position); result->query_location = node->location; - return move(result); + return std::move(result); } } // namespace duckdb @@ -192696,7 +203518,7 @@ unique_ptr Transformer::TransformSubquery(duckdb_libpgquery::P // e.g. [= ALL()] is equivalent to [NOT(<> ANY())] // first invert the comparison type subquery_expr->comparison_type = NegateComparisionExpression(subquery_expr->comparison_type); - return make_unique(ExpressionType::OPERATOR_NOT, move(subquery_expr)); + return make_unique(ExpressionType::OPERATOR_NOT, std::move(subquery_expr)); } break; } @@ -192718,30 +203540,30 @@ unique_ptr Transformer::TransformSubquery(duckdb_libpgquery::P vector> children; children.push_back( make_unique_base(subquery_column_alias, subquery_table_alias)); - auto aggr = make_unique("array_agg", move(children)); + auto aggr = make_unique("array_agg", std::move(children)); // ARRAY_AGG(i) IS NULL auto agg_is_null = make_unique(ExpressionType::OPERATOR_IS_NULL, aggr->Copy()); // empty list vector> list_children; - auto empty_list = make_unique("list_value", move(list_children)); + auto empty_list = make_unique("list_value", std::move(list_children)); // CASE auto case_expr = make_unique(); CaseCheck check; - check.when_expr = move(agg_is_null); - check.then_expr = move(empty_list); - case_expr->case_checks.push_back(move(check)); - case_expr->else_expr = move(aggr); + check.when_expr = std::move(agg_is_null); + check.then_expr = std::move(empty_list); + case_expr->case_checks.push_back(std::move(check)); + case_expr->else_expr = std::move(aggr); - select_node->select_list.push_back(move(case_expr)); + select_node->select_list.push_back(std::move(case_expr)); // FROM (...) tbl(i) - auto child_subquery = make_unique(move(subquery_expr->subquery), subquery_table_alias); + auto child_subquery = make_unique(std::move(subquery_expr->subquery), subquery_table_alias); child_subquery->column_name_alias.emplace_back(subquery_column_alias); - select_node->from_table = move(child_subquery); + select_node->from_table = std::move(child_subquery); auto new_subquery = make_unique(); - new_subquery->node = move(select_node); - subquery_expr->subquery = move(new_subquery); + new_subquery->node = std::move(select_node); + subquery_expr->subquery = std::move(new_subquery); subquery_expr->subquery_type = SubqueryType::SCALAR; break; @@ -192750,7 +203572,7 @@ unique_ptr Transformer::TransformSubquery(duckdb_libpgquery::P throw NotImplementedException("Subquery of type %d not implemented\n", (int)root->subLinkType); } subquery_expr->query_location = root->location; - return move(subquery_expr); + return std::move(subquery_expr); } } // namespace duckdb @@ -193568,6 +204390,12 @@ std::string Transformer::NodetypeToString(duckdb_libpgquery::PGNodeTag type) { / return "T_TsmRoutine"; case duckdb_libpgquery::T_PGForeignKeyCacheInfo: return "T_ForeignKeyCacheInfo"; + case duckdb_libpgquery::T_PGAttachStmt: + return "T_PGAttachStmt"; + case duckdb_libpgquery::T_PGUseStmt: + return "T_PGUseStmt"; + case duckdb_libpgquery::T_PGCreateDatabaseStmt: + return "T_PGCreateDatabaseStmt"; default: return "(UNKNOWN)"; } @@ -193638,7 +204466,8 @@ void Transformer::TransformCTE(duckdb_libpgquery::PGWithClause *de_with_clause, if (cte->cterecursive || de_with_clause->recursive) { info->query = TransformRecursiveCTE(cte, *info); } else { - info->query = TransformSelect(cte->ctequery); + Transformer cte_transformer(this); + info->query = cte_transformer.TransformSelect(cte->ctequery); } D_ASSERT(info->query); auto cte_name = string(cte->ctename); @@ -193648,7 +204477,7 @@ void Transformer::TransformCTE(duckdb_libpgquery::PGWithClause *de_with_clause, // can't have two CTEs with same name throw ParserException("Duplicate CTE name \"%s\"", cte_name); } - cte_map.map[cte_name] = move(info); + cte_map.map[cte_name] = std::move(info); } } @@ -193739,7 +204568,7 @@ void Transformer::AddGroupByExpression(unique_ptr expression, auto &func = (FunctionExpression &)*expression; if (func.function_name == "row") { for (auto &child : func.children) { - AddGroupByExpression(move(child), map, result, result_set); + AddGroupByExpression(std::move(child), map, result, result_set); } return; } @@ -193749,7 +204578,7 @@ void Transformer::AddGroupByExpression(unique_ptr expression, if (entry == map.map.end()) { result_idx = result.group_expressions.size(); map.map[expression.get()] = result_idx; - result.group_expressions.push_back(move(expression)); + result.group_expressions.push_back(std::move(expression)); } else { result_idx = entry->second; } @@ -193770,7 +204599,7 @@ static void AddCubeSets(const GroupingSet ¤t_set, vector &res void Transformer::TransformGroupByExpression(duckdb_libpgquery::PGNode *n, GroupingExpressionMap &map, GroupByNode &result, vector &indexes) { auto expression = TransformExpression(n); - AddGroupByExpression(move(expression), map, result, indexes); + AddGroupByExpression(std::move(expression), map, result, indexes); } // If one GROUPING SETS clause is nested inside another, @@ -193851,7 +204680,7 @@ bool Transformer::TransformGroupBy(duckdb_libpgquery::PGList *group, SelectNode CheckGroupingSetMax(result_sets.size()); if (result.grouping_sets.empty()) { // no grouping sets yet: use the current set of grouping sets - result.grouping_sets = move(result_sets); + result.grouping_sets = std::move(result_sets); } else { // compute the cross product vector new_sets; @@ -193865,10 +204694,10 @@ bool Transformer::TransformGroupBy(duckdb_libpgquery::PGList *group, SelectNode GroupingSet set; set.insert(current_set.begin(), current_set.end()); set.insert(new_set.begin(), new_set.end()); - new_sets.push_back(move(set)); + new_sets.push_back(std::move(set)); } } - result.grouping_sets = move(new_sets); + result.grouping_sets = std::move(new_sets); } } return true; @@ -193920,7 +204749,7 @@ bool Transformer::TransformOrderBy(duckdb_libpgquery::PGList *order, vectortype); } @@ -194007,6 +204836,8 @@ LogicalType Transformer::TransformTypeName(duckdb_libpgquery::PGTypeName *type_n LogicalType result_type; if (base_type == LogicalTypeId::LIST) { throw ParserException("LIST is not valid as a stand-alone type"); + } else if (base_type == LogicalTypeId::ENUM) { + throw ParserException("ENUM is not valid as a stand-alone type"); } else if (base_type == LogicalTypeId::STRUCT) { if (!type_name->typmods || type_name->typmods->length == 0) { throw ParserException("Struct needs a name and entries"); @@ -194037,23 +204868,16 @@ LogicalType Transformer::TransformTypeName(duckdb_libpgquery::PGTypeName *type_n children.push_back(make_pair(entry_name, entry_type)); } D_ASSERT(!children.empty()); - result_type = LogicalType::STRUCT(move(children)); + result_type = LogicalType::STRUCT(std::move(children)); } else if (base_type == LogicalTypeId::MAP) { - //! We transform MAP to STRUCT, LIST> if (!type_name->typmods || type_name->typmods->length != 2) { throw ParserException("Map type needs exactly two entries, key and value type"); } - child_list_t children; auto key_type = TransformTypeName((duckdb_libpgquery::PGTypeName *)type_name->typmods->head->data.ptr_value); auto value_type = TransformTypeName((duckdb_libpgquery::PGTypeName *)type_name->typmods->tail->data.ptr_value); - children.push_back({"key", LogicalType::LIST(key_type)}); - children.push_back({"value", LogicalType::LIST(value_type)}); - - D_ASSERT(children.size() == 2); - - result_type = LogicalType::MAP(move(children)); + result_type = LogicalType::MAP(std::move(key_type), std::move(value_type)); } else if (base_type == LogicalTypeId::UNION) { if (!type_name->typmods || type_name->typmods->length == 0) { throw ParserException("Union type needs at least one member"); @@ -194089,7 +204913,7 @@ LogicalType Transformer::TransformTypeName(duckdb_libpgquery::PGTypeName *type_n children.push_back(make_pair(entry_name, entry_type)); } D_ASSERT(!children.empty()); - result_type = LogicalType::UNION(move(children)); + result_type = LogicalType::UNION(std::move(children)); } else { int64_t width, scale; if (base_type == LogicalTypeId::DECIMAL) { @@ -194114,6 +204938,9 @@ LogicalType Transformer::TransformTypeName(duckdb_libpgquery::PGTypeName *type_n } if (modifier_idx == 0) { width = const_val.val.val.ival; + if (base_type == LogicalTypeId::BIT && const_val.location != -1) { + width = 0; + } } else if (modifier_idx == 1) { scale = const_val.val.val.ival; } else { @@ -194156,6 +204983,34 @@ LogicalType Transformer::TransformTypeName(duckdb_libpgquery::PGTypeName *type_n result_type = LogicalType::USER(user_type_name); break; } + case LogicalTypeId::BIT: { + if (!width && type_name->typmods) { + throw ParserException("Type %s does not support any modifiers!", LogicalType(base_type).ToString()); + } + result_type = LogicalType(base_type); + break; + } + case LogicalTypeId::TIMESTAMP: + if (modifier_idx == 0) { + result_type = LogicalType::TIMESTAMP; + } else { + if (modifier_idx > 1) { + throw ParserException("TIMESTAMP only supports a single modifier"); + } + if (width > 10) { + throw ParserException("TIMESTAMP only supports until nano-second precision (9)"); + } + if (width == 0) { + result_type = LogicalType::TIMESTAMP_S; + } else if (width <= 3) { + result_type = LogicalType::TIMESTAMP_MS; + } else if (width <= 6) { + result_type = LogicalType::TIMESTAMP; + } else { + result_type = LogicalType::TIMESTAMP_NS; + } + } + break; default: if (modifier_idx > 0) { throw ParserException("Type %s does not support any modifiers!", LogicalType(base_type).ToString()); @@ -194168,7 +205023,7 @@ LogicalType Transformer::TransformTypeName(duckdb_libpgquery::PGTypeName *type_n // array bounds: turn the type into a list idx_t extra_stack = 0; for (auto cell = type_name->arrayBounds->head; cell != nullptr; cell = cell->next) { - result_type = LogicalType::LIST(move(result_type)); + result_type = LogicalType::LIST(std::move(result_type)); StackCheck(extra_stack++); } } @@ -194213,6 +205068,7 @@ unique_ptr Transformer::TransformAlterSequence(duckdb_libpgquery auto result = make_unique(); auto qname = TransformQualifiedName(stmt->sequence); + auto sequence_catalog = qname.catalog; auto sequence_schema = qname.schema; auto sequence_name = qname.name; @@ -194248,8 +205104,8 @@ unique_ptr Transformer::TransformAlterSequence(duckdb_libpgquery opt_values.emplace_back(target->name); } D_ASSERT(!opt_values.empty()); - string owner_schema = ""; - string owner_name = ""; + string owner_schema = INVALID_SCHEMA; + string owner_name; if (opt_values.size() == 2) { owner_schema = opt_values[0]; owner_name = opt_values[1]; @@ -194259,9 +205115,9 @@ unique_ptr Transformer::TransformAlterSequence(duckdb_libpgquery } else { throw InternalException("Wrong argument for %s. Expected either . or ", opt_name); } - auto info = make_unique(CatalogType::SEQUENCE_ENTRY, sequence_schema, sequence_name, - owner_schema, owner_name, stmt->missing_ok); - result->info = move(info); + auto info = make_unique(CatalogType::SEQUENCE_ENTRY, sequence_catalog, sequence_schema, + sequence_name, owner_schema, owner_name, stmt->missing_ok); + result->info = std::move(info); } else { throw NotImplementedException("ALTER SEQUENCE option not supported yet!"); } @@ -194293,6 +205149,7 @@ unique_ptr Transformer::TransformAlter(duckdb_libpgquery::PGNode // first we check the type of ALTER for (auto c = stmt->cmds->head; c != nullptr; c = c->next) { auto command = reinterpret_cast(lfirst(c)); + AlterEntryData data(qname.catalog, qname.schema, qname.name, stmt->missing_ok); // TODO: Include more options for command->subtype switch (command->subtype) { case duckdb_libpgquery::PG_AT_AddColumn: { @@ -194315,8 +205172,7 @@ unique_ptr Transformer::TransformAlter(duckdb_libpgquery::PGNode throw ParserException("Adding columns with constraints not yet supported"); } } - result->info = make_unique(qname.schema, qname.name, stmt->missing_ok, move(centry), - command->missing_ok); + result->info = make_unique(std::move(data), std::move(centry), command->missing_ok); break; } case duckdb_libpgquery::PG_AT_DropColumn: { @@ -194325,8 +205181,7 @@ unique_ptr Transformer::TransformAlter(duckdb_libpgquery::PGNode if (stmt->relkind != duckdb_libpgquery::PG_OBJECT_TABLE) { throw ParserException("Dropping columns is only supported for tables"); } - result->info = make_unique(qname.schema, qname.name, stmt->missing_ok, command->name, - command->missing_ok, cascade); + result->info = make_unique(std::move(data), command->name, command->missing_ok, cascade); break; } case duckdb_libpgquery::PG_AT_ColumnDefault: { @@ -194335,8 +205190,7 @@ unique_ptr Transformer::TransformAlter(duckdb_libpgquery::PGNode if (stmt->relkind != duckdb_libpgquery::PG_OBJECT_TABLE) { throw ParserException("Alter column's default is only supported for tables"); } - result->info = - make_unique(qname.schema, qname.name, stmt->missing_ok, command->name, move(expr)); + result->info = make_unique(std::move(data), command->name, std::move(expr)); break; } case duckdb_libpgquery::PG_AT_AlterColumnType: { @@ -194351,18 +205205,18 @@ unique_ptr Transformer::TransformAlter(duckdb_libpgquery::PGNode expr = TransformExpression(cdef->raw_default); } else { auto colref = make_unique(command->name); - expr = make_unique(column_definition.Type(), move(colref)); + expr = make_unique(column_definition.Type(), std::move(colref)); } - result->info = make_unique(qname.schema, qname.name, stmt->missing_ok, command->name, - column_definition.Type(), move(expr)); + result->info = make_unique(std::move(data), command->name, column_definition.Type(), + std::move(expr)); break; } case duckdb_libpgquery::PG_AT_SetNotNull: { - result->info = make_unique(qname.schema, qname.name, stmt->missing_ok, command->name); + result->info = make_unique(std::move(data), command->name); break; } case duckdb_libpgquery::PG_AT_DropNotNull: { - result->info = make_unique(qname.schema, qname.name, stmt->missing_ok, command->name); + result->info = make_unique(std::move(data), command->name); break; } case duckdb_libpgquery::PG_AT_DropConstraint: @@ -194378,6 +205232,38 @@ unique_ptr Transformer::TransformAlter(duckdb_libpgquery::PGNode + + +namespace duckdb { + +unique_ptr Transformer::TransformAttach(duckdb_libpgquery::PGNode *node) { + auto stmt = reinterpret_cast(node); + auto result = make_unique(); + auto info = make_unique(); + info->name = stmt->name ? stmt->name : string(); + info->path = stmt->path; + + if (stmt->options) { + duckdb_libpgquery::PGListCell *cell = nullptr; + for_each_cell(cell, stmt->options->head) { + auto *def_elem = reinterpret_cast(cell->data.ptr_value); + Value val; + if (def_elem->arg) { + val = TransformValue(*((duckdb_libpgquery::PGValue *)def_elem->arg))->value; + } else { + val = Value::BOOLEAN(true); + } + info->options[StringUtil::Lower(def_elem->defname)] = std::move(val); + } + } + result->info = std::move(info); + return result; +} + +} // namespace duckdb + + + namespace duckdb { unique_ptr Transformer::TransformCall(duckdb_libpgquery::PGNode *node) { @@ -194394,6 +205280,7 @@ unique_ptr Transformer::TransformCall(duckdb_libpgquery::PGNode * + namespace duckdb { unique_ptr Transformer::TransformCheckpoint(duckdb_libpgquery::PGNode *node) { @@ -194401,10 +205288,14 @@ unique_ptr Transformer::TransformCheckpoint(duckdb_libpgquery::PGN vector> children; // transform into "CALL checkpoint()" or "CALL force_checkpoint()" + auto checkpoint_name = checkpoint->force ? "force_checkpoint" : "checkpoint"; auto result = make_unique(); - result->function = - make_unique(checkpoint->force ? "force_checkpoint" : "checkpoint", move(children)); - return move(result); + auto function = make_unique(checkpoint_name, std::move(children)); + if (checkpoint->name) { + function->children.push_back(make_unique(Value(checkpoint->name))); + } + result->function = std::move(function); + return std::move(result); } } // namespace duckdb @@ -194482,6 +205373,8 @@ unique_ptr Transformer::TransformCopy(duckdb_libpgquery::PGNode * } if (StringUtil::EndsWith(info.file_path, ".parquet")) { info.format = "parquet"; + } else if (StringUtil::EndsWith(info.file_path, ".json") || StringUtil::EndsWith(info.file_path, ".ndjson")) { + info.format = "json"; } else { info.format = "csv"; } @@ -194501,6 +205394,7 @@ unique_ptr Transformer::TransformCopy(duckdb_libpgquery::PGNode * auto &table = *reinterpret_cast(ref.get()); info.table = table.table_name; info.schema = table.schema_name; + info.catalog = table.catalog_name; } else { result->select_statement = TransformSelectNode((duckdb_libpgquery::PGSelectStmt *)stmt->query); } @@ -194518,6 +205412,35 @@ unique_ptr Transformer::TransformCopy(duckdb_libpgquery::PGNode * +namespace duckdb { + +unique_ptr Transformer::TransformCreateDatabase(duckdb_libpgquery::PGNode *node) { + auto stmt = reinterpret_cast(node); + auto result = make_unique(); + auto info = make_unique(); + + info->extension_name = stmt->extension ? stmt->extension : string(); + info->path = stmt->path ? stmt->path : string(); + + auto qualified_name = TransformQualifiedName(stmt->name); + if (!IsInvalidCatalog(qualified_name.catalog)) { + throw ParserException("Expected \"CREATE DATABASE database\" "); + } + + info->catalog = qualified_name.catalog; + info->name = qualified_name.name; + + result->info = std::move(info); + return result; +} + +} // namespace duckdb + + + + + + namespace duckdb { @@ -194538,14 +205461,15 @@ unique_ptr Transformer::TransformCreateFunction(duckdb_libpgque // function can be null here if (stmt->function) { auto expression = TransformExpression(stmt->function); - macro_func = make_unique(move(expression)); + macro_func = make_unique(std::move(expression)); } else if (stmt->query) { auto query_node = TransformSelect(stmt->query, true)->node->Copy(); - macro_func = make_unique(move(query_node)); + macro_func = make_unique(std::move(query_node)); } auto info = make_unique((stmt->function ? CatalogType::MACRO_ENTRY : CatalogType::TABLE_MACRO_ENTRY)); + info->catalog = qname.catalog; info->schema = qname.schema; info->name = qname.name; @@ -194577,21 +205501,21 @@ unique_ptr Transformer::TransformCreateFunction(duckdb_libpgque if (macro_func->default_parameters.find(param->alias) != macro_func->default_parameters.end()) { throw ParserException("Duplicate default parameter: '%s'", param->alias); } - macro_func->default_parameters[param->alias] = move(param); + macro_func->default_parameters[param->alias] = std::move(param); } else if (param->GetExpressionClass() == ExpressionClass::COLUMN_REF) { // positional parameters if (!macro_func->default_parameters.empty()) { throw ParserException("Positional parameters cannot come after parameters with a default value!"); } - macro_func->parameters.push_back(move(param)); + macro_func->parameters.push_back(std::move(param)); } else { throw ParserException("Invalid parameter: '%s'", param->ToString()); } } } - info->function = move(macro_func); - result->info = move(info); + info->function = std::move(macro_func); + result->info = std::move(info); return result; } @@ -194618,20 +205542,10 @@ static IndexType StringToIndexType(const string &str) { return IndexType::INVALID; } -unique_ptr Transformer::TransformCreateIndex(duckdb_libpgquery::PGNode *node) { - auto stmt = reinterpret_cast(node); - D_ASSERT(stmt); - auto result = make_unique(); - auto info = make_unique(); - if (stmt->unique) { - info->constraint_type = IndexConstraintType::UNIQUE; - } else { - info->constraint_type = IndexConstraintType::NONE; - } - - info->on_conflict = TransformOnConflict(stmt->onconflict); - - for (auto cell = stmt->indexParams->head; cell != nullptr; cell = cell->next) { +vector> Transformer::TransformIndexParameters(duckdb_libpgquery::PGList *list, + const string &relation_name) { + vector> expressions; + for (auto cell = list->head; cell != nullptr; cell = cell->next) { auto index_element = (duckdb_libpgquery::PGIndexElem *)cell->data.ptr_value; if (index_element->collation) { throw NotImplementedException("Index with collation not supported yet!"); @@ -194642,13 +205556,30 @@ unique_ptr Transformer::TransformCreateIndex(duckdb_libpgquery: if (index_element->name) { // create a column reference expression - info->expressions.push_back(make_unique(index_element->name, stmt->relation->relname)); + expressions.push_back(make_unique(index_element->name, relation_name)); } else { // parse the index expression D_ASSERT(index_element->expr); - info->expressions.push_back(TransformExpression(index_element->expr)); + expressions.push_back(TransformExpression(index_element->expr)); } } + return expressions; +} + +unique_ptr Transformer::TransformCreateIndex(duckdb_libpgquery::PGNode *node) { + auto stmt = reinterpret_cast(node); + D_ASSERT(stmt); + auto result = make_unique(); + auto info = make_unique(); + if (stmt->unique) { + info->constraint_type = IndexConstraintType::UNIQUE; + } else { + info->constraint_type = IndexConstraintType::NONE; + } + + info->on_conflict = TransformOnConflict(stmt->onconflict); + + info->expressions = TransformIndexParameters(stmt->indexParams, stmt->relation->relname); info->index_type = StringToIndexType(string(stmt->accessMethod)); auto tableref = make_unique(); @@ -194656,7 +205587,7 @@ unique_ptr Transformer::TransformCreateIndex(duckdb_libpgquery: if (stmt->relation->schemaname) { tableref->schema_name = stmt->relation->schemaname; } - info->table = move(tableref); + info->table = std::move(tableref); if (stmt->idxname) { info->index_name = stmt->idxname; } else { @@ -194665,7 +205596,7 @@ unique_ptr Transformer::TransformCreateIndex(duckdb_libpgquery: for (auto &expr : info->expressions) { info->parsed_expressions.emplace_back(expr->Copy()); } - result->info = move(info); + result->info = std::move(info); return result; } @@ -194683,6 +205614,7 @@ unique_ptr Transformer::TransformCreateSchema(duckdb_libpgquery auto info = make_unique(); D_ASSERT(stmt->schemaname); + info->catalog = stmt->catalogname ? stmt->catalogname : INVALID_CATALOG; info->schema = stmt->schemaname; info->on_conflict = TransformOnConflict(stmt->onconflict); @@ -194698,7 +205630,7 @@ unique_ptr Transformer::TransformCreateSchema(duckdb_libpgquery } } } - result->info = move(info); + result->info = std::move(info); return result; } @@ -194719,6 +205651,7 @@ unique_ptr Transformer::TransformCreateSequence(duckdb_libpgque auto info = make_unique(); auto qname = TransformQualifiedName(stmt->sequence); + info->catalog = qname.catalog; info->schema = qname.schema; info->name = qname.name; @@ -194827,7 +205760,7 @@ unique_ptr Transformer::TransformCreateSequence(duckdb_libpgque throw ParserException("START value (%lld) cannot be greater than MAXVALUE (%lld)", info->start_value, info->max_value); } - result->info = move(info); + result->info = std::move(info); return result; } @@ -194878,7 +205811,7 @@ OnCreateConflict Transformer::TransformOnConflict(duckdb_libpgquery::PGOnCreateC unique_ptr Transformer::TransformCollateExpr(duckdb_libpgquery::PGCollateClause *collate) { auto child = TransformExpression(collate->arg); auto collation = TransformCollation(collate); - return make_unique(collation, move(child)); + return make_unique(collation, std::move(child)); } ColumnDefinition Transformer::TransformColumnDefinition(duckdb_libpgquery::PGColumnDef *cdef) { @@ -194912,11 +205845,11 @@ unique_ptr Transformer::TransformCreateTable(duckdb_libpgquery: } D_ASSERT(stmt->relation); - info->schema = INVALID_SCHEMA; - if (stmt->relation->schemaname) { - info->schema = stmt->relation->schemaname; - } - info->table = stmt->relation->relname; + info->catalog = INVALID_CATALOG; + auto qname = TransformQualifiedName(stmt->relation); + info->catalog = qname.catalog; + info->schema = qname.schema; + info->table = qname.name; info->on_conflict = TransformOnConflict(stmt->onconflict); info->temporary = stmt->relation->relpersistence == duckdb_libpgquery::PGPostgresRelPersistence::PG_RELPERSISTENCE_TEMP; @@ -194940,11 +205873,11 @@ unique_ptr Transformer::TransformCreateTable(duckdb_libpgquery: for (auto constr = cdef->constraints->head; constr != nullptr; constr = constr->next) { auto constraint = TransformConstraint(constr, centry, info->columns.LogicalColumnCount()); if (constraint) { - info->constraints.push_back(move(constraint)); + info->constraints.push_back(std::move(constraint)); } } } - info->columns.AddColumn(move(centry)); + info->columns.AddColumn(std::move(centry)); column_count++; break; } @@ -194961,7 +205894,7 @@ unique_ptr Transformer::TransformCreateTable(duckdb_libpgquery: throw ParserException("Table must have at least one column!"); } - result->info = move(info); + result->info = std::move(info); return result; } @@ -194989,13 +205922,14 @@ unique_ptr Transformer::TransformCreateTableAs(duckdb_libpgquer auto result = make_unique(); auto info = make_unique(); + info->catalog = qname.catalog; info->schema = qname.schema; info->table = qname.name; info->on_conflict = TransformOnConflict(stmt->onconflict); info->temporary = stmt->into->rel->relpersistence == duckdb_libpgquery::PGPostgresRelPersistence::PG_RELPERSISTENCE_TEMP; - info->query = move(query); - result->info = move(info); + info->query = std::move(query); + result->info = std::move(info); return result; } @@ -195008,18 +205942,6 @@ unique_ptr Transformer::TransformCreateTableAs(duckdb_libpgquer namespace duckdb { -vector ReadPgListToString(duckdb_libpgquery::PGList *column_list) { - vector result; - if (!column_list) { - return result; - } - for (auto c = column_list->head; c != nullptr; c = lnext(c)) { - auto target = (duckdb_libpgquery::PGResTarget *)(c->data.ptr_value); - result.emplace_back(target->name); - } - return result; -} - Vector ReadPgListToVector(duckdb_libpgquery::PGList *column_list, idx_t &size) { if (!column_list) { Vector result(LogicalType::VARCHAR); @@ -195053,7 +205975,12 @@ unique_ptr Transformer::TransformCreateType(duckdb_libpgquery:: D_ASSERT(stmt); auto result = make_unique(); auto info = make_unique(); - info->name = ReadPgListToString(stmt->typeName)[0]; + + auto qualified_name = TransformQualifiedName(stmt->typeName); + info->catalog = qualified_name.catalog; + info->schema = qualified_name.schema; + info->name = qualified_name.name; + switch (stmt->kind) { case duckdb_libpgquery::PG_NEWTYPE_ENUM: { info->internal = false; @@ -195061,7 +205988,7 @@ unique_ptr Transformer::TransformCreateType(duckdb_libpgquery:: // CREATE TYPE mood AS ENUM (SELECT ...) D_ASSERT(stmt->vals == nullptr); auto query = TransformSelect(stmt->query, false); - info->query = move(query); + info->query = std::move(query); info->type = LogicalType::INVALID; } else { D_ASSERT(stmt->query == nullptr); @@ -195081,7 +206008,7 @@ unique_ptr Transformer::TransformCreateType(duckdb_libpgquery:: throw InternalException("Unknown kind of new type"); } - result->info = move(info); + result->info = std::move(info); return result; } } // namespace duckdb @@ -195102,13 +206029,13 @@ unique_ptr Transformer::TransformCreateView(duckdb_libpgquery:: auto result = make_unique(); auto info = make_unique(); - if (stmt->view->schemaname) { - info->schema = stmt->view->schemaname; - } - info->view_name = stmt->view->relname; + auto qname = TransformQualifiedName(stmt->view); + info->catalog = qname.catalog; + info->schema = qname.schema; + info->view_name = qname.name; info->temporary = !stmt->view->relpersistence; - if (info->temporary) { - info->schema = TEMP_SCHEMA; + if (info->temporary && IsInvalidCatalog(info->catalog)) { + info->catalog = TEMP_CATALOG; } info->on_conflict = TransformOnConflict(stmt->onconflict); @@ -195139,7 +206066,7 @@ unique_ptr Transformer::TransformCreateView(duckdb_libpgquery:: if (stmt->withCheckOption != duckdb_libpgquery::PGViewCheckOption::PG_NO_CHECK_OPTION) { throw NotImplementedException("VIEW CHECK options"); } - result->info = move(info); + result->info = std::move(info); return result; } @@ -195147,7 +206074,6 @@ unique_ptr Transformer::TransformCreateView(duckdb_libpgquery:: - namespace duckdb { unique_ptr Transformer::TransformDelete(duckdb_libpgquery::PGNode *node) { @@ -195167,7 +206093,7 @@ unique_ptr Transformer::TransformDelete(duckdb_libpgquery::PGNo for (auto n = stmt->usingClause->head; n != nullptr; n = n->next) { auto target = reinterpret_cast(n->data.ptr_value); auto using_entry = TransformTableRefNode(target); - result->using_clauses.push_back(move(using_entry)); + result->using_clauses.push_back(std::move(using_entry)); } } @@ -195216,34 +206142,52 @@ unique_ptr Transformer::TransformDrop(duckdb_libpgquery::PGNode *n case duckdb_libpgquery::PG_OBJECT_TYPE: info.type = CatalogType::TYPE_ENTRY; break; + case duckdb_libpgquery::PG_OBJECT_DATABASE: + info.type = CatalogType::DATABASE_ENTRY; + break; default: throw NotImplementedException("Cannot drop this type yet"); } switch (stmt->removeType) { - case duckdb_libpgquery::PG_OBJECT_SCHEMA: - info.name = ((duckdb_libpgquery::PGValue *)stmt->objects->head->data.ptr_value)->val.str; - break; case duckdb_libpgquery::PG_OBJECT_TYPE: { auto view_list = (duckdb_libpgquery::PGList *)stmt->objects; auto target = (duckdb_libpgquery::PGTypeName *)(view_list->head->data.ptr_value); info.name = (reinterpret_cast(target->names->tail->data.ptr_value)->val.str); break; } - default: { + case duckdb_libpgquery::PG_OBJECT_SCHEMA: { auto view_list = (duckdb_libpgquery::PGList *)stmt->objects->head->data.ptr_value; if (view_list->length == 2) { - info.schema = ((duckdb_libpgquery::PGValue *)view_list->head->data.ptr_value)->val.str; + info.catalog = ((duckdb_libpgquery::PGValue *)view_list->head->data.ptr_value)->val.str; info.name = ((duckdb_libpgquery::PGValue *)view_list->head->next->data.ptr_value)->val.str; + } else if (view_list->length == 1) { + info.name = ((duckdb_libpgquery::PGValue *)view_list->head->data.ptr_value)->val.str; } else { + throw ParserException("Expected \"catalog.schema\" or \"schema\""); + } + break; + } + default: { + auto view_list = (duckdb_libpgquery::PGList *)stmt->objects->head->data.ptr_value; + if (view_list->length == 3) { + info.catalog = ((duckdb_libpgquery::PGValue *)view_list->head->data.ptr_value)->val.str; + info.schema = ((duckdb_libpgquery::PGValue *)view_list->head->next->data.ptr_value)->val.str; + info.name = ((duckdb_libpgquery::PGValue *)view_list->head->next->next->data.ptr_value)->val.str; + } else if (view_list->length == 2) { + info.schema = ((duckdb_libpgquery::PGValue *)view_list->head->data.ptr_value)->val.str; + info.name = ((duckdb_libpgquery::PGValue *)view_list->head->next->data.ptr_value)->val.str; + } else if (view_list->length == 1) { info.name = ((duckdb_libpgquery::PGValue *)view_list->head->data.ptr_value)->val.str; + } else { + throw ParserException("Expected \"catalog.schema.name\", \"schema.name\"or \"name\""); } break; } } info.cascade = stmt->behavior == duckdb_libpgquery::PGDropBehavior::PG_DROP_CASCADE; info.if_exists = stmt->missing_ok; - return move(result); + return std::move(result); } } // namespace duckdb @@ -195285,7 +206229,11 @@ unique_ptr Transformer::TransformExport(duckdb_libpgquery::PGNo // handle export options TransformCopyOptions(*info, stmt->options); - return make_unique(move(info)); + auto result = make_unique(std::move(info)); + if (stmt->database) { + result->database = stmt->database; + } + return result; } } // namespace duckdb @@ -195321,19 +206269,19 @@ unique_ptr Transformer::TransformValuesList(duckdb_libpgquery::PGList throw ParserException("VALUES lists must all be the same length"); } } - result->values.push_back(move(insert_values)); + result->values.push_back(std::move(insert_values)); } result->alias = "valueslist"; - return move(result); + return std::move(result); } unique_ptr Transformer::TransformInsert(duckdb_libpgquery::PGNode *node) { auto stmt = reinterpret_cast(node); D_ASSERT(stmt); - if (stmt->onConflictClause && stmt->onConflictClause->action != duckdb_libpgquery::PG_ONCONFLICT_NONE) { - throw ParserException("ON CONFLICT IGNORE/UPDATE clauses are not supported"); - } + if (!stmt->selectStmt) { + // TODO: This should be easy to add, we already support DEFAULT in the values list, + // this could probably just be transformed into VALUES (DEFAULT, DEFAULT, DEFAULT, ..) in the Binder throw ParserException("DEFAULT VALUES clause is not supported!"); } @@ -195359,6 +206307,22 @@ unique_ptr Transformer::TransformInsert(duckdb_libpgquery::PGNo auto qname = TransformQualifiedName(stmt->relation); result->table = qname.name; result->schema = qname.schema; + + if (stmt->onConflictClause) { + if (stmt->onConflictAlias != duckdb_libpgquery::PG_ONCONFLICT_ALIAS_NONE) { + // OR REPLACE | OR IGNORE are shorthands for the ON CONFLICT clause + throw ParserException("You can not provide both OR REPLACE|IGNORE and an ON CONFLICT clause, please remove " + "the first if you want to have more granual control"); + } + result->on_conflict_info = TransformOnConflictClause(stmt->onConflictClause, result->schema); + result->table_ref = TransformRangeVar(stmt->relation); + } + if (stmt->onConflictAlias != duckdb_libpgquery::PG_ONCONFLICT_ALIAS_NONE) { + D_ASSERT(!stmt->onConflictClause); + result->on_conflict_info = DummyOnConflictClause(stmt->onConflictAlias, result->schema); + result->table_ref = TransformRangeVar(stmt->relation); + } + result->catalog = qname.catalog; return result; } @@ -195386,7 +206350,7 @@ unique_ptr Transformer::TransformLoad(duckdb_libpgquery::PGNode * load_info->load_type = LoadType::FORCE_INSTALL; break; } - load_stmt->info = move(load_info); + load_stmt->info = std::move(load_info); return load_stmt; } @@ -195429,6 +206393,13 @@ unique_ptr Transformer::TransformPragma(duckdb_libpgquery::PGNode } else if (node->type == duckdb_libpgquery::T_PGAConst) { auto constant = TransformConstant((duckdb_libpgquery::PGAConst *)node); info.parameters.push_back(((ConstantExpression &)*constant).value); + } else if (expr->type == ExpressionType::COLUMN_REF) { + auto &colref = (ColumnRefExpression &)*expr; + if (!colref.IsQualified()) { + info.parameters.emplace_back(colref.GetColumnName()); + } else { + info.parameters.emplace_back(expr->ToString()); + } } else { info.parameters.emplace_back(expr->ToString()); } @@ -195456,8 +206427,8 @@ unique_ptr Transformer::TransformPragma(duckdb_libpgquery::PGNode if (sqlite_compat_pragmas.find(info.name) != sqlite_compat_pragmas.end()) { break; } - auto set_statement = make_unique(info.name, info.parameters[0], SetScope::AUTOMATIC); - return move(set_statement); + auto set_statement = make_unique(info.name, info.parameters[0], SetScope::AUTOMATIC); + return std::move(set_statement); } case duckdb_libpgquery::PG_PRAGMA_TYPE_CALL: break; @@ -195465,7 +206436,7 @@ unique_ptr Transformer::TransformPragma(duckdb_libpgquery::PGNode throw InternalException("Unknown pragma type"); } - return move(result); + return std::move(result); } } // namespace duckdb @@ -195487,6 +206458,9 @@ unique_ptr Transformer::TransformPrepare(duckdb_libpgquery::PG auto result = make_unique(); result->name = string(stmt->name); result->statement = TransformStatement(stmt->query); + if (!result->statement->named_param_map.empty()) { + throw NotImplementedException("Named parameters are not supported in this client yet"); + } SetParamCount(0); return result; @@ -195536,60 +206510,37 @@ unique_ptr Transformer::TransformRename(duckdb_libpgquery::PGNod unique_ptr info; + AlterEntryData data; + data.if_exists = stmt->missing_ok; + data.catalog = stmt->relation->catalogname ? stmt->relation->catalogname : INVALID_CATALOG; + data.schema = stmt->relation->schemaname ? stmt->relation->schemaname : INVALID_SCHEMA; + if (stmt->relation->relname) { + data.name = stmt->relation->relname; + } + if (stmt->relation->schemaname) { + } // first we check the type of ALTER switch (stmt->renameType) { case duckdb_libpgquery::PG_OBJECT_COLUMN: { // change column name - // get the table and schema - string schema = INVALID_SCHEMA; - string table; - D_ASSERT(stmt->relation->relname); - if (stmt->relation->relname) { - table = stmt->relation->relname; - } - if (stmt->relation->schemaname) { - schema = stmt->relation->schemaname; - } // get the old name and the new name string old_name = stmt->subname; string new_name = stmt->newname; - info = make_unique(schema, table, stmt->missing_ok, old_name, new_name); + info = make_unique(std::move(data), old_name, new_name); break; } case duckdb_libpgquery::PG_OBJECT_TABLE: { // change table name - - // get the table and schema - string schema = INVALID_SCHEMA; - string table; - D_ASSERT(stmt->relation->relname); - if (stmt->relation->relname) { - table = stmt->relation->relname; - } - if (stmt->relation->schemaname) { - schema = stmt->relation->schemaname; - } string new_name = stmt->newname; - info = make_unique(schema, table, stmt->missing_ok, new_name); + info = make_unique(std::move(data), new_name); break; } case duckdb_libpgquery::PG_OBJECT_VIEW: { // change view name - - // get the view and schema - string schema = INVALID_SCHEMA; - string view; - D_ASSERT(stmt->relation->relname); - if (stmt->relation->relname) { - view = stmt->relation->relname; - } - if (stmt->relation->schemaname) { - schema = stmt->relation->schemaname; - } string new_name = stmt->newname; - info = make_unique(schema, view, stmt->missing_ok, new_name); + info = make_unique(std::move(data), new_name); break; } case duckdb_libpgquery::PG_OBJECT_DATABASE: @@ -195597,10 +206548,9 @@ unique_ptr Transformer::TransformRename(duckdb_libpgquery::PGNod throw NotImplementedException("Schema element not supported yet!"); } D_ASSERT(info); - info->if_exists = stmt->missing_ok; auto result = make_unique(); - result->info = move(info); + result->info = std::move(info); return result; } @@ -195677,7 +206627,7 @@ unique_ptr Transformer::TransformSelectNode(duckdb_libpgquery::PGSele // add the columns defined in the ON clause to the select list TransformExpressionList(*stmt->distinctClause, modifier->distinct_on_targets); } - result->modifiers.push_back(move(modifier)); + result->modifiers.push_back(std::move(modifier)); } // do this early so the value lists also have a `FROM` @@ -195758,8 +206708,8 @@ unique_ptr Transformer::TransformSelectNode(duckdb_libpgquery::PGSele TransformOrderBy(stmt->sortClause, orders); if (!orders.empty()) { auto order_modifier = make_unique(); - order_modifier->orders = move(orders); - node->modifiers.push_back(move(order_modifier)); + order_modifier->orders = std::move(orders); + node->modifiers.push_back(std::move(order_modifier)); } if (stmt->limitCount || stmt->limitOffset) { if (stmt->limitCount && stmt->limitCount->type == duckdb_libpgquery::T_PGLimitPercent) { @@ -195769,7 +206719,7 @@ unique_ptr Transformer::TransformSelectNode(duckdb_libpgquery::PGSele if (stmt->limitOffset) { limit_percent_modifier->offset = TransformExpression(stmt->limitOffset); } - node->modifiers.push_back(move(limit_percent_modifier)); + node->modifiers.push_back(std::move(limit_percent_modifier)); } else { auto limit_modifier = make_unique(); if (stmt->limitCount) { @@ -195778,7 +206728,7 @@ unique_ptr Transformer::TransformSelectNode(duckdb_libpgquery::PGSele if (stmt->limitOffset) { limit_modifier->offset = TransformExpression(stmt->limitOffset); } - node->modifiers.push_back(move(limit_modifier)); + node->modifiers.push_back(std::move(limit_modifier)); } } return node; @@ -195809,15 +206759,21 @@ SetScope ToSetScope(duckdb_libpgquery::VariableSetScope pg_scope) { } } +SetType ToSetType(duckdb_libpgquery::VariableSetKind pg_kind) { + switch (pg_kind) { + case duckdb_libpgquery::VariableSetKind::VAR_SET_VALUE: + return SetType::SET; + case duckdb_libpgquery::VariableSetKind::VAR_RESET: + return SetType::RESET; + default: + throw NotImplementedException("Can only SET or RESET a variable"); + } +} + } // namespace -unique_ptr Transformer::TransformSet(duckdb_libpgquery::PGNode *node) { - D_ASSERT(node->type == duckdb_libpgquery::T_PGVariableSetStmt); - auto stmt = reinterpret_cast(node); - - if (stmt->kind != duckdb_libpgquery::VariableSetKind::VAR_SET_VALUE) { - throw ParserException("Can only SET a variable to a value"); - } +unique_ptr Transformer::TransformSetVariable(duckdb_libpgquery::PGVariableSetStmt *stmt) { + D_ASSERT(stmt->kind == duckdb_libpgquery::VariableSetKind::VAR_SET_VALUE); if (stmt->scope == duckdb_libpgquery::VariableSetScope::VAR_SET_SCOPE_LOCAL) { throw NotImplementedException("SET LOCAL is not implemented."); @@ -195833,7 +206789,36 @@ unique_ptr Transformer::TransformSet(duckdb_libpgquery::PGNode *no auto value = TransformValue(((duckdb_libpgquery::PGAConst *)stmt->args->head->data.ptr_value)->val)->value; - return make_unique(name, value, ToSetScope(stmt->scope)); + return make_unique(name, value, ToSetScope(stmt->scope)); +} + +unique_ptr Transformer::TransformResetVariable(duckdb_libpgquery::PGVariableSetStmt *stmt) { + D_ASSERT(stmt->kind == duckdb_libpgquery::VariableSetKind::VAR_RESET); + + if (stmt->scope == duckdb_libpgquery::VariableSetScope::VAR_SET_SCOPE_LOCAL) { + throw NotImplementedException("RESET LOCAL is not implemented."); + } + + auto name = std::string(stmt->name); + D_ASSERT(!name.empty()); // parser protect us! + + return make_unique(name, ToSetScope(stmt->scope)); +} + +unique_ptr Transformer::TransformSet(duckdb_libpgquery::PGNode *node) { + D_ASSERT(node->type == duckdb_libpgquery::T_PGVariableSetStmt); + auto stmt = reinterpret_cast(node); + + SetType set_type = ToSetType(stmt->kind); + + switch (set_type) { + case SetType::SET: + return TransformSetVariable(stmt); + case SetType::RESET: + return TransformResetVariable(stmt); + default: + throw NotImplementedException("Type not implemented for SetType"); + } } } // namespace duckdb @@ -195848,11 +206833,14 @@ namespace duckdb { static void TransformShowName(unique_ptr &result, const string &name) { auto &info = *result->info; + auto lname = StringUtil::Lower(name); - if (name == "\"tables\"") { + if (lname == "\"databases\"") { + info.name = "show_databases"; + } else if (lname == "\"tables\"") { // show all tables info.name = "show_tables"; - } else if (name == "__show_tables_expanded") { + } else if (lname == "__show_tables_expanded") { info.name = "show_tables_expanded"; } else { // show one specific table @@ -195876,17 +206864,17 @@ unique_ptr Transformer::TransformShow(duckdb_libpgquery::PGNode *n auto qualified_name = QualifiedName::Parse(stmt->name); basetable->schema_name = qualified_name.schema; basetable->table_name = qualified_name.name; - select->from_table = move(basetable); + select->from_table = std::move(basetable); - info.query = move(select); - return move(result); + info.query = std::move(select); + return std::move(result); } auto result = make_unique(); auto show_name = stmt->name; TransformShowName(result, show_name); - return move(result); + return std::move(result); } } // namespace duckdb @@ -195938,6 +206926,20 @@ unique_ptr Transformer::TransformTransaction(duckdb_libpgq namespace duckdb { +unique_ptr Transformer::TransformUpdateSetInfo(duckdb_libpgquery::PGList *target_list, + duckdb_libpgquery::PGNode *where_clause) { + auto result = make_unique(); + + auto root = target_list; + for (auto cell = root->head; cell != nullptr; cell = cell->next) { + auto target = (duckdb_libpgquery::PGResTarget *)(cell->data.ptr_value); + result->columns.emplace_back(target->name); + result->expressions.push_back(TransformExpression(target->val)); + } + result->condition = TransformExpression(where_clause); + return result; +} + unique_ptr Transformer::TransformUpdate(duckdb_libpgquery::PGNode *node) { auto stmt = reinterpret_cast(node); D_ASSERT(stmt); @@ -195952,19 +206954,13 @@ unique_ptr Transformer::TransformUpdate(duckdb_libpgquery::PGNo result->from_table = TransformFrom(stmt->fromClause); } - auto root = stmt->targetList; - for (auto cell = root->head; cell != nullptr; cell = cell->next) { - auto target = (duckdb_libpgquery::PGResTarget *)(cell->data.ptr_value); - result->columns.emplace_back(target->name); - result->expressions.push_back(TransformExpression(target->val)); - } + result->set_info = TransformUpdateSetInfo(stmt->targetList, stmt->whereClause); // Grab and transform the returning columns from the parser. if (stmt->returningList) { Transformer::TransformExpressionList(*(stmt->returningList), result->returning_list); } - result->condition = TransformExpression(stmt->whereClause); return result; } @@ -195972,6 +206968,122 @@ unique_ptr Transformer::TransformUpdate(duckdb_libpgquery::PGNo + + +namespace duckdb { + +OnConflictAction TransformOnConflictAction(duckdb_libpgquery::PGOnConflictClause *on_conflict) { + if (!on_conflict) { + return OnConflictAction::THROW; + } + switch (on_conflict->action) { + case duckdb_libpgquery::PG_ONCONFLICT_NONE: + return OnConflictAction::THROW; + case duckdb_libpgquery::PG_ONCONFLICT_NOTHING: + return OnConflictAction::NOTHING; + case duckdb_libpgquery::PG_ONCONFLICT_UPDATE: + return OnConflictAction::UPDATE; + default: + throw InternalException("Type not implemented for OnConflictAction"); + } +} + +vector TransformConflictTarget(duckdb_libpgquery::PGList *list) { + vector columns; + for (auto cell = list->head; cell != nullptr; cell = cell->next) { + auto index_element = (duckdb_libpgquery::PGIndexElem *)cell->data.ptr_value; + if (index_element->collation) { + throw NotImplementedException("Index with collation not supported yet!"); + } + if (index_element->opclass) { + throw NotImplementedException("Index with opclass not supported yet!"); + } + if (!index_element->name) { + throw NotImplementedException("Non-column index element not supported yet!"); + } + if (index_element->nulls_ordering) { + throw NotImplementedException("Index with null_ordering not supported yet!"); + } + if (index_element->ordering) { + throw NotImplementedException("Index with ordering not supported yet!"); + } + columns.emplace_back(index_element->name); + } + return columns; +} + +unique_ptr Transformer::DummyOnConflictClause(duckdb_libpgquery::PGOnConflictActionAlias type, + const string &relname) { + switch (type) { + case duckdb_libpgquery::PGOnConflictActionAlias::PG_ONCONFLICT_ALIAS_REPLACE: { + // This can not be fully resolved yet until the bind stage + auto result = make_unique(); + result->action_type = OnConflictAction::REPLACE; + return result; + } + case duckdb_libpgquery::PGOnConflictActionAlias::PG_ONCONFLICT_ALIAS_IGNORE: { + // We can just fully replace this with DO NOTHING, and be done with it + auto result = make_unique(); + result->action_type = OnConflictAction::NOTHING; + return result; + } + default: { + throw InternalException("Type not implemented for PGOnConflictActionAlias"); + } + } +} + +unique_ptr Transformer::TransformOnConflictClause(duckdb_libpgquery::PGOnConflictClause *node, + const string &relname) { + auto stmt = reinterpret_cast(node); + D_ASSERT(stmt); + + auto result = make_unique(); + result->action_type = TransformOnConflictAction(stmt); + if (stmt->infer) { + // A filter for the ON CONFLICT ... is specified + if (stmt->infer->indexElems) { + // Columns are specified + result->indexed_columns = TransformConflictTarget(stmt->infer->indexElems); + if (stmt->infer->whereClause) { + result->condition = TransformExpression(stmt->infer->whereClause); + } + } else { + throw NotImplementedException("ON CONSTRAINT conflict target is not supported yet"); + } + } + + if (result->action_type == OnConflictAction::UPDATE) { + result->set_info = TransformUpdateSetInfo(stmt->targetList, stmt->whereClause); + } + return result; +} + +} // namespace duckdb + + + +namespace duckdb { + +unique_ptr Transformer::TransformUse(duckdb_libpgquery::PGNode *node) { + auto stmt = reinterpret_cast(node); + auto qualified_name = TransformQualifiedName(stmt->name); + if (!IsInvalidCatalog(qualified_name.catalog)) { + throw ParserException("Expected \"USE database\" or \"USE database.schema\""); + } + string name; + if (IsInvalidSchema(qualified_name.schema)) { + name = qualified_name.name; + } else { + name = qualified_name.schema + "." + qualified_name.name; + } + return make_unique("schema", std::move(name), SetScope::AUTOMATIC); +} + +} // namespace duckdb + + + namespace duckdb { VacuumOptions ParseOptions(int options) { @@ -196022,7 +207134,7 @@ unique_ptr Transformer::TransformVacuum(duckdb_libpgquery::PGNode } } - return move(result); + return std::move(result); } } // namespace duckdb @@ -196038,6 +207150,9 @@ unique_ptr Transformer::TransformRangeVar(duckdb_libpgquery::PGRangeVa if (root->relname) { result->table_name = root->relname; } + if (root->catalogname) { + result->catalog_name = root->catalogname; + } if (root->schemaname) { result->schema_name = root->schemaname; } @@ -196045,21 +207160,26 @@ unique_ptr Transformer::TransformRangeVar(duckdb_libpgquery::PGRangeVa result->sample = TransformSampleOptions(root->sample); } result->query_location = root->location; - return move(result); + return std::move(result); } QualifiedName Transformer::TransformQualifiedName(duckdb_libpgquery::PGRangeVar *root) { QualifiedName qname; - if (root->relname) { - qname.name = root->relname; + if (root->catalogname) { + qname.catalog = root->catalogname; } else { - qname.name = string(); + qname.catalog = INVALID_CATALOG; } if (root->schemaname) { qname.schema = root->schemaname; } else { qname.schema = INVALID_SCHEMA; } + if (root->relname) { + qname.name = root->relname; + } else { + qname.name = string(); + } return qname; } @@ -196077,27 +207197,27 @@ unique_ptr Transformer::TransformFrom(duckdb_libpgquery::PGList *root) if (root->length > 1) { // Cross Product - auto result = make_unique(); - CrossProductRef *cur_root = result.get(); + auto result = make_unique(JoinRefType::CROSS); + JoinRef *cur_root = result.get(); idx_t list_size = 0; for (auto node = root->head; node != nullptr; node = node->next) { auto n = reinterpret_cast(node->data.ptr_value); unique_ptr next = TransformTableRefNode(n); if (!cur_root->left) { - cur_root->left = move(next); + cur_root->left = std::move(next); } else if (!cur_root->right) { - cur_root->right = move(next); + cur_root->right = std::move(next); } else { - auto old_res = move(result); - result = make_unique(); - result->left = move(old_res); - result->right = move(next); + auto old_res = std::move(result); + result = make_unique(JoinRefType::CROSS); + result->left = std::move(old_res); + result->right = std::move(next); cur_root = result.get(); } list_size++; StackCheck(list_size); } - return move(result); + return std::move(result); } auto n = reinterpret_cast(root->head->data.ptr_value); @@ -196110,11 +207230,10 @@ unique_ptr Transformer::TransformFrom(duckdb_libpgquery::PGList *root) - namespace duckdb { unique_ptr Transformer::TransformJoin(duckdb_libpgquery::PGJoinExpr *root) { - auto result = make_unique(); + auto result = make_unique(JoinRefType::REGULAR); switch (root->jointype) { case duckdb_libpgquery::PG_JOIN_INNER: { result->type = JoinType::INNER; @@ -196136,6 +207255,10 @@ unique_ptr Transformer::TransformJoin(duckdb_libpgquery::PGJoinExpr *r result->type = JoinType::SEMI; break; } + case duckdb_libpgquery::PG_JOIN_POSITION: { + result->ref_type = JoinRefType::POSITIONAL; + break; + } default: { throw NotImplementedException("Join type %d not supported\n", root->jointype); } @@ -196144,7 +207267,9 @@ unique_ptr Transformer::TransformJoin(duckdb_libpgquery::PGJoinExpr *r // Check the type of left arg and right arg before transform result->left = TransformTableRefNode(root->larg); result->right = TransformTableRefNode(root->rarg); - result->is_natural = root->isNatural; + if (root->isNatural) { + result->ref_type = JoinRefType::NATURAL; + } result->query_location = root->location; if (root->usingClause && root->usingClause->length > 0) { @@ -196155,17 +207280,14 @@ unique_ptr Transformer::TransformJoin(duckdb_libpgquery::PGJoinExpr *r auto column_name = string(reinterpret_cast(target)->val.str); result->using_columns.push_back(column_name); } - return move(result); + return std::move(result); } - if (!root->quals && result->using_columns.empty() && !result->is_natural) { // CROSS PRODUCT - auto cross = make_unique(); - cross->left = move(result->left); - cross->right = move(result->right); - return move(cross); + if (!root->quals && result->using_columns.empty() && result->ref_type == JoinRefType::REGULAR) { // CROSS PRODUCT + result->ref_type = JoinRefType::CROSS; } result->condition = TransformExpression(root->quals); - return move(result); + return std::move(result); } } // namespace duckdb @@ -196180,15 +207302,12 @@ unique_ptr Transformer::TransformRangeSubselect(duckdb_libpgquery::PGR if (!subquery) { return nullptr; } - if (root->lateral) { - throw NotImplementedException("LATERAL not implemented"); - } - auto result = make_unique(move(subquery)); + auto result = make_unique(std::move(subquery)); result->alias = TransformAlias(root->alias, result->column_name_alias); if (root->sample) { result->sample = TransformSampleOptions(root->sample); } - return move(result); + return std::move(result); } } // namespace duckdb @@ -196199,9 +207318,6 @@ unique_ptr Transformer::TransformRangeSubselect(duckdb_libpgquery::PGR namespace duckdb { unique_ptr Transformer::TransformRangeFunction(duckdb_libpgquery::PGRangeFunction *root) { - if (root->lateral) { - throw NotImplementedException("LATERAL not implemented"); - } if (root->ordinality) { throw NotImplementedException("WITH ORDINALITY not implemented"); } @@ -196238,7 +207354,7 @@ unique_ptr Transformer::TransformRangeFunction(duckdb_libpgquery::PGRa if (root->sample) { result->sample = TransformSampleOptions(root->sample); } - return move(result); + return std::move(result); } } // namespace duckdb @@ -196280,6 +207396,7 @@ unique_ptr Transformer::TransformTableRefNode(duckdb_libpgquery::PGNod + //===----------------------------------------------------------------------===// // DuckDB // @@ -196298,7 +207415,7 @@ namespace duckdb { class LogicalPlanStatement : public SQLStatement { public: explicit LogicalPlanStatement(unique_ptr plan_p) - : SQLStatement(StatementType::LOGICAL_PLAN_STATEMENT), plan(move(plan_p)) {}; + : SQLStatement(StatementType::LOGICAL_PLAN_STATEMENT), plan(std::move(plan_p)) {}; unique_ptr plan; @@ -196353,7 +207470,7 @@ bool Transformer::TransformParseTree(duckdb_libpgquery::PGList *tree, vectordata.ptr_value); D_ASSERT(stmt); stmt->n_param = ParamCount(); - statements.push_back(move(stmt)); + statements.push_back(std::move(stmt)); } return true; } @@ -196379,6 +207496,10 @@ StackChecker Transformer::StackCheck(idx_t extra_stack) { unique_ptr Transformer::TransformStatement(duckdb_libpgquery::PGNode *stmt) { auto result = TransformStatementInternal(stmt); result->n_param = ParamCount(); + if (!named_param_map.empty()) { + // Avoid overriding a previous move with nothing + result->named_param_map = std::move(named_param_map); + } return result; } @@ -196457,6 +207578,12 @@ unique_ptr Transformer::TransformStatementInternal(duckdb_libpgque return TransformCreateType(stmt); case duckdb_libpgquery::T_PGAlterSeqStmt: return TransformAlterSequence(stmt); + case duckdb_libpgquery::T_PGAttachStmt: + return TransformAttach(stmt); + case duckdb_libpgquery::T_PGUseStmt: + return TransformUse(stmt); + case duckdb_libpgquery::T_PGCreateDatabaseStmt: + return TransformCreateDatabase(stmt); default: throw NotImplementedException(NodetypeToString(stmt->type)); } @@ -196480,6 +207607,7 @@ unique_ptr Transformer::TransformStatementInternal(duckdb_libpgque + #include namespace duckdb { @@ -196521,7 +207649,7 @@ void BindContext::AddUsingBinding(const string &column_name, UsingColumnSet *set } void BindContext::AddUsingBindingSet(unique_ptr set) { - using_column_sets.push_back(move(set)); + using_column_sets.push_back(std::move(set)); } bool BindContext::FindUsingBinding(const string &column_name, unordered_set **out) { @@ -196657,23 +207785,26 @@ static bool ColumnIsGenerated(Binding *binding, column_t index) { } D_ASSERT(catalog_entry->type == CatalogType::TABLE_ENTRY); auto table_entry = (TableCatalogEntry *)catalog_entry; - return table_entry->columns.GetColumn(LogicalIndex(index)).Generated(); + return table_entry->GetColumn(LogicalIndex(index)).Generated(); } -unique_ptr BindContext::CreateColumnReference(const string &schema_name, const string &table_name, - const string &column_name) { +unique_ptr BindContext::CreateColumnReference(const string &catalog_name, const string &schema_name, + const string &table_name, const string &column_name) { string error_message; vector names; + if (!catalog_name.empty()) { + names.push_back(catalog_name); + } if (!schema_name.empty()) { names.push_back(schema_name); } names.push_back(table_name); names.push_back(column_name); - auto result = make_unique(move(names)); + auto result = make_unique(std::move(names)); auto binding = GetBinding(table_name, error_message); if (!binding) { - return move(result); + return std::move(result); } auto column_index = binding->GetBindingIndex(column_name); if (ColumnIsGenerated(binding, column_index)) { @@ -196683,7 +207814,13 @@ unique_ptr BindContext::CreateColumnReference(const string &sc // as it appears in the binding itself result->alias = binding->names[column_index]; } - return move(result); + return std::move(result); +} + +unique_ptr BindContext::CreateColumnReference(const string &schema_name, const string &table_name, + const string &column_name) { + string catalog_name; + return CreateColumnReference(catalog_name, schema_name, table_name, column_name); } Binding *BindContext::GetCTEBinding(const string &ctename) { @@ -196769,7 +207906,7 @@ bool BindContext::CheckExclusionList(StarExpression &expr, Binding *binding, con auto new_entry = entry->second->Copy(); new_entry->alias = entry->first; excluded_columns.insert(entry->first); - new_select_list.push_back(move(new_entry)); + new_select_list.push_back(std::move(new_entry)); return true; } return false; @@ -196828,7 +207965,7 @@ void BindContext::GenerateAllColumnExpressions(StarExpression &expr, coalesce->children.push_back(make_unique(column_name, child_binding)); } coalesce->alias = column_name; - new_select_list.push_back(move(coalesce)); + new_select_list.push_back(std::move(coalesce)); } else { // primary binding: output the qualified column ref new_select_list.push_back( @@ -196905,13 +208042,13 @@ void BindContext::AddBinding(const string &alias, unique_ptr binding) { throw BinderException("Duplicate alias \"%s\" in query!", alias); } bindings_list.emplace_back(alias, binding.get()); - bindings[alias] = move(binding); + bindings[alias] = std::move(binding); } void BindContext::AddBaseTable(idx_t index, const string &alias, const vector &names, const vector &types, vector &bound_column_ids, - StandardEntry *entry) { - AddBinding(alias, make_unique(alias, types, names, bound_column_ids, entry, index, true)); + StandardEntry *entry, bool add_row_id) { + AddBinding(alias, make_unique(alias, types, names, bound_column_ids, entry, index, add_row_id)); } void BindContext::AddTableFunction(idx_t index, const string &alias, const vector &names, @@ -196924,7 +208061,7 @@ static string AddColumnNameToBinding(const string &base_name, case_insensitive_s idx_t index = 1; string name = base_name; while (current_names.find(name) != current_names.end()) { - name = base_name + ":" + to_string(index++); + name = base_name + ":" + std::to_string(index++); } current_names.insert(name); return name; @@ -196983,7 +208120,7 @@ void BindContext::AddCTEBinding(idx_t index, const string &alias, const vector(0); } @@ -196992,10 +208129,10 @@ void BindContext::AddContext(BindContext other) { if (bindings.find(binding.first) != bindings.end()) { throw BinderException("Duplicate alias \"%s\" in query!", binding.first); } - bindings[binding.first] = move(binding.second); + bindings[binding.first] = std::move(binding.second); } for (auto &binding : other.bindings_list) { - bindings_list.push_back(move(binding)); + bindings_list.push_back(std::move(binding)); } for (auto &entry : other.using_columns) { for (auto &alias : entry.second) { @@ -197019,6 +208156,7 @@ void BindContext::AddContext(BindContext other) { + //===----------------------------------------------------------------------===// // DuckDB // @@ -197219,7 +208357,47 @@ class BoundSelectNode : public BoundQueryNode { namespace duckdb { -static void InvertPercentileFractions(ClientContext &context, unique_ptr &fractions) { +static Value NegatePercentileValue(const Value &v, const bool desc) { + if (v.IsNull()) { + return v; + } + + const auto frac = v.GetValue(); + if (frac < 0 || frac > 1) { + throw BinderException("PERCENTILEs can only take parameters in the range [0, 1]"); + } + + if (!desc) { + return v; + } + + const auto &type = v.type(); + switch (type.id()) { + case LogicalTypeId::DECIMAL: { + // Negate DECIMALs as DECIMAL. + const auto integral = IntegralValue::Get(v); + const auto width = DecimalType::GetWidth(type); + const auto scale = DecimalType::GetScale(type); + switch (type.InternalType()) { + case PhysicalType::INT16: + return Value::DECIMAL(Cast::Operation(-integral), width, scale); + case PhysicalType::INT32: + return Value::DECIMAL(Cast::Operation(-integral), width, scale); + case PhysicalType::INT64: + return Value::DECIMAL(Cast::Operation(-integral), width, scale); + case PhysicalType::INT128: + return Value::DECIMAL(-integral, width, scale); + default: + throw InternalException("Unknown DECIMAL type"); + } + } + default: + // Everything else can just be a DOUBLE + return Value::DOUBLE(-v.GetValue()); + } +} + +static void NegatePercentileFractions(ClientContext &context, unique_ptr &fractions, bool desc) { D_ASSERT(fractions.get()); D_ASSERT(fractions->expression_class == ExpressionClass::BOUND_EXPRESSION); auto &bound = (BoundExpression &)*fractions; @@ -197232,17 +208410,11 @@ static void InvertPercentileFractions(ClientContext &context, unique_ptr values; for (const auto &element_val : ListValue::GetChildren(value)) { - if (element_val.IsNull()) { - values.push_back(element_val); - } else { - values.push_back(Value::DOUBLE(1 - element_val.GetValue())); - } + values.push_back(NegatePercentileValue(element_val, desc)); } bound.expr = make_unique(Value::LIST(values)); - } else if (value.IsNull()) { - bound.expr = make_unique(value); } else { - bound.expr = make_unique(Value::DOUBLE(1 - value.GetValue())); + bound.expr = make_unique(NegatePercentileValue(value, desc)); } } @@ -197261,7 +208433,7 @@ BindResult SelectBinder::BindAggregate(FunctionExpression &aggr, AggregateFuncti // Handle ordered-set aggregates by moving the single ORDER BY expression to the front of the children. // https://www.postgresql.org/docs/current/functions-aggregate.html#FUNCTIONS-ORDEREDSET-TABLE bool ordered_set_agg = false; - bool invert_fractions = false; + bool negate_fractions = false; if (aggr.order_bys && aggr.order_bys->orders.size() == 1) { const auto &func_name = aggr.function_name; ordered_set_agg = (func_name == "quantile_cont" || func_name == "quantile_disc" || func_name == "mode"); @@ -197271,15 +208443,15 @@ BindResult SelectBinder::BindAggregate(FunctionExpression &aggr, AggregateFuncti const auto &order = aggr.order_bys->orders[0]; const auto sense = (order.type == OrderType::ORDER_DEFAULT) ? config.options.default_order_type : order.type; - invert_fractions = (sense == OrderType::DESCENDING); + negate_fractions = (sense == OrderType::DESCENDING); } } for (auto &child : aggr.children) { aggregate_binder.BindChild(child, 0, error); - // We have to invert the fractions for PERCENTILE_XXXX DESC - if (error.empty() && invert_fractions) { - InvertPercentileFractions(context, child); + // We have to negate the fractions for PERCENTILE_XXXX DESC + if (error.empty() && ordered_set_agg) { + NegatePercentileFractions(context, child, negate_fractions); } } @@ -197337,7 +208509,7 @@ BindResult SelectBinder::BindAggregate(FunctionExpression &aggr, AggregateFuncti if (aggr.filter) { auto &child = (BoundExpression &)*aggr.filter; - bound_filter = BoundCastExpression::AddCastToType(context, move(child.expr), LogicalType::BOOLEAN); + bound_filter = BoundCastExpression::AddCastToType(context, std::move(child.expr), LogicalType::BOOLEAN); } // all children bound successfully @@ -197351,7 +208523,7 @@ BindResult SelectBinder::BindAggregate(FunctionExpression &aggr, AggregateFuncti auto &child = (BoundExpression &)*order.expression; types.push_back(child.expr->return_type); arguments.push_back(child.expr->return_type); - children.push_back(move(child.expr)); + children.push_back(std::move(child.expr)); } aggr.order_bys->orders.clear(); } @@ -197360,7 +208532,7 @@ BindResult SelectBinder::BindAggregate(FunctionExpression &aggr, AggregateFuncti auto &child = (BoundExpression &)*aggr.children[i]; types.push_back(child.expr->return_type); arguments.push_back(child.expr->return_type); - children.push_back(move(child.expr)); + children.push_back(std::move(child.expr)); } // bind the aggregate @@ -197383,15 +208555,15 @@ BindResult SelectBinder::BindAggregate(FunctionExpression &aggr, AggregateFuncti const auto null_order = (order.null_order == OrderByNullType::ORDER_DEFAULT) ? config.options.default_null_order : order.null_order; - order_bys->orders.emplace_back(BoundOrderByNode(sense, null_order, move(order_expr.expr))); + order_bys->orders.emplace_back(BoundOrderByNode(sense, null_order, std::move(order_expr.expr))); } } auto aggregate = function_binder.BindAggregateFunction( - bound_function, move(children), move(bound_filter), - aggr.distinct ? AggregateType::DISTINCT : AggregateType::NON_DISTINCT, move(order_bys)); + bound_function, std::move(children), std::move(bound_filter), + aggr.distinct ? AggregateType::DISTINCT : AggregateType::NON_DISTINCT, std::move(order_bys)); if (aggr.export_state) { - aggregate = ExportAggregateFunction::Bind(move(aggregate)); + aggregate = ExportAggregateFunction::Bind(std::move(aggregate)); } // check for all the aggregates if this aggregate already exists @@ -197401,7 +208573,7 @@ BindResult SelectBinder::BindAggregate(FunctionExpression &aggr, AggregateFuncti // new aggregate: insert into aggregate list aggr_index = node.aggregates.size(); node.aggregate_map.insert(make_pair(aggregate.get(), aggr_index)); - node.aggregates.push_back(move(aggregate)); + node.aggregates.push_back(std::move(aggregate)); } else { // duplicate aggregate: simplify refer to this aggregate aggr_index = entry->second; @@ -197412,7 +208584,7 @@ BindResult SelectBinder::BindAggregate(FunctionExpression &aggr, AggregateFuncti aggr.alias.empty() ? node.aggregates[aggr_index]->ToString() : aggr.alias, node.aggregates[aggr_index]->return_type, ColumnBinding(node.aggregate_index, aggr_index), depth); // move the aggregate expression into the set of bound aggregates - return BindResult(move(colref)); + return BindResult(std::move(colref)); } } // namespace duckdb @@ -197448,31 +208620,31 @@ BindResult ExpressionBinder::BindExpression(BetweenExpression &expr, idx_t depth auto input_type = BoundComparisonExpression::BindComparison(input_sql_type, lower_sql_type); input_type = BoundComparisonExpression::BindComparison(input_type, upper_sql_type); // add casts (if necessary) - input.expr = BoundCastExpression::AddCastToType(context, move(input.expr), input_type); - lower.expr = BoundCastExpression::AddCastToType(context, move(lower.expr), input_type); - upper.expr = BoundCastExpression::AddCastToType(context, move(upper.expr), input_type); + input.expr = BoundCastExpression::AddCastToType(context, std::move(input.expr), input_type); + lower.expr = BoundCastExpression::AddCastToType(context, std::move(lower.expr), input_type); + upper.expr = BoundCastExpression::AddCastToType(context, std::move(upper.expr), input_type); if (input_type.id() == LogicalTypeId::VARCHAR) { // handle collation auto collation = StringType::GetCollation(input_type); - input.expr = PushCollation(context, move(input.expr), collation, false); - lower.expr = PushCollation(context, move(lower.expr), collation, false); - upper.expr = PushCollation(context, move(upper.expr), collation, false); + input.expr = PushCollation(context, std::move(input.expr), collation, false); + lower.expr = PushCollation(context, std::move(lower.expr), collation, false); + upper.expr = PushCollation(context, std::move(upper.expr), collation, false); } if (!input.expr->HasSideEffects() && !input.expr->HasParameter() && !input.expr->HasSubquery()) { // the expression does not have side effects and can be copied: create two comparisons // the reason we do this is that individual comparisons are easier to handle in optimizers // if both comparisons remain they will be folded together again into a single BETWEEN in the optimizer auto left_compare = make_unique(ExpressionType::COMPARE_GREATERTHANOREQUALTO, - input.expr->Copy(), move(lower.expr)); + input.expr->Copy(), std::move(lower.expr)); auto right_compare = make_unique(ExpressionType::COMPARE_LESSTHANOREQUALTO, - move(input.expr), move(upper.expr)); - return BindResult(make_unique(ExpressionType::CONJUNCTION_AND, move(left_compare), - move(right_compare))); + std::move(input.expr), std::move(upper.expr)); + return BindResult(make_unique(ExpressionType::CONJUNCTION_AND, + std::move(left_compare), std::move(right_compare))); } else { // expression has side effects: we cannot duplicate it // create a bound_between directly - return BindResult( - make_unique(move(input.expr), move(lower.expr), move(upper.expr), true, true)); + return BindResult(make_unique(std::move(input.expr), std::move(lower.expr), + std::move(upper.expr), true, true)); } } @@ -197511,13 +208683,13 @@ BindResult ExpressionBinder::BindExpression(CaseExpression &expr, idx_t depth) { auto &then_expr = (BoundExpression &)*check.then_expr; BoundCaseCheck result_check; result_check.when_expr = - BoundCastExpression::AddCastToType(context, move(when_expr.expr), LogicalType::BOOLEAN); - result_check.then_expr = BoundCastExpression::AddCastToType(context, move(then_expr.expr), return_type); - result->case_checks.push_back(move(result_check)); + BoundCastExpression::AddCastToType(context, std::move(when_expr.expr), LogicalType::BOOLEAN); + result_check.then_expr = BoundCastExpression::AddCastToType(context, std::move(then_expr.expr), return_type); + result->case_checks.push_back(std::move(result_check)); } auto &else_expr = (BoundExpression &)*expr.else_expr; - result->else_expr = BoundCastExpression::AddCastToType(context, move(else_expr.expr), return_type); - return BindResult(move(result)); + result->else_expr = BoundCastExpression::AddCastToType(context, std::move(else_expr.expr), return_type); + return BindResult(std::move(result)); } } // namespace duckdb @@ -197536,20 +208708,20 @@ BindResult ExpressionBinder::BindExpression(CastExpression &expr, idx_t depth) { } // FIXME: We can also implement 'hello'::schema.custom_type; and pass by the schema down here. // Right now just considering its DEFAULT_SCHEMA always - Binder::BindLogicalType(context, expr.cast_type, DEFAULT_SCHEMA); + Binder::BindLogicalType(context, expr.cast_type); // the children have been successfully resolved auto &child = (BoundExpression &)*expr.child; if (expr.try_cast) { if (child.expr->return_type == expr.cast_type) { // no cast required: type matches - return BindResult(move(child.expr)); + return BindResult(std::move(child.expr)); } - child.expr = BoundCastExpression::AddCastToType(context, move(child.expr), expr.cast_type, true); + child.expr = BoundCastExpression::AddCastToType(context, std::move(child.expr), expr.cast_type, true); } else { // otherwise add a cast to the target type - child.expr = BoundCastExpression::AddCastToType(context, move(child.expr), expr.cast_type); + child.expr = BoundCastExpression::AddCastToType(context, std::move(child.expr), expr.cast_type); } - return BindResult(move(child.expr)); + return BindResult(std::move(child.expr)); } } // namespace duckdb @@ -197574,7 +208746,7 @@ BindResult ExpressionBinder::BindExpression(CollateExpression &expr, idx_t depth // Validate the collation, but don't use it PushCollation(context, child.expr->Copy(), expr.collation, false); child.expr->return_type = LogicalType::VARCHAR_COLLATION(expr.collation); - return BindResult(move(child.expr)); + return BindResult(std::move(child.expr)); } } // namespace duckdb @@ -197590,6 +208762,61 @@ BindResult ExpressionBinder::BindExpression(CollateExpression &expr, idx_t depth +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/expression/bound_lambdaref_expression.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +class FieldReader; +class FieldWriter; + +//! A BoundLambdaRef expression represents a LambdaRef expression that was bound to an lambda parameter +//! in the lambda bindings vector. When capturing lambdas the BoundLambdaRef becomes a +//! BoundReferenceExpresssion, indexing the corresponding lambda parameter in the lambda bindings vector, +//! which refers to the physical chunk of the lambda parameter during execution. +class BoundLambdaRefExpression : public Expression { +public: + BoundLambdaRefExpression(LogicalType type, ColumnBinding binding, idx_t lambda_index, idx_t depth = 0); + BoundLambdaRefExpression(string alias, LogicalType type, ColumnBinding binding, idx_t lambda_index, + idx_t depth = 0); + //! Column index set by the binder, used to generate the final BoundExpression + ColumnBinding binding; + //! The index of the lambda parameter in the lambda bindings vector + idx_t lambda_index; + //! The subquery depth (i.e. depth 0 = current query, depth 1 = parent query, depth 2 = parent of parent, etc...). + //! This is only non-zero for correlated expressions inside subqueries. + idx_t depth; + +public: + bool IsScalar() const override { + return false; + } + bool IsFoldable() const override { + return false; + } + + string ToString() const override; + + bool Equals(const BaseExpression *other) const override; + hash_t Hash() const override; + + unique_ptr Copy() override; + + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(ExpressionDeserializationState &state, FieldReader &reader); +}; +} // namespace duckdb + //===----------------------------------------------------------------------===// @@ -197642,10 +208869,11 @@ unique_ptr ExpressionBinder::QualifyColumnName(const string &c } else { // // we cannot! we need to bind this as a coalesce between all the relevant columns auto coalesce = make_unique(ExpressionType::OPERATOR_COALESCE); + coalesce->children.reserve(using_binding->bindings.size()); for (auto &entry : using_binding->bindings) { coalesce->children.push_back(make_unique(column_name, entry)); } - return move(coalesce); + return std::move(coalesce); } } @@ -197703,7 +208931,7 @@ void ExpressionBinder::QualifyColumnNames(unique_ptr &expr) { new_expr->alias = expr->alias; } new_expr->query_location = colref.query_location; - expr = move(new_expr); + expr = std::move(new_expr); } break; } @@ -197748,37 +208976,50 @@ unique_ptr ExpressionBinder::CreateStructExtract(unique_ptr> children; - children.push_back(move(base)); - children.push_back(make_unique_base(Value(move(field_name)))); - auto extract_fun = make_unique(ExpressionType::STRUCT_EXTRACT, move(children)); - return move(extract_fun); + children.push_back(std::move(base)); + children.push_back(make_unique_base(Value(std::move(field_name)))); + auto extract_fun = make_unique(ExpressionType::STRUCT_EXTRACT, std::move(children)); + return std::move(extract_fun); } unique_ptr ExpressionBinder::CreateStructPack(ColumnRefExpression &colref) { - D_ASSERT(colref.column_names.size() <= 2); + D_ASSERT(colref.column_names.size() <= 3); string error_message; auto &table_name = colref.column_names.back(); auto binding = binder.bind_context.GetBinding(table_name, error_message); if (!binding) { return nullptr; } - if (colref.column_names.size() == 2) { + if (colref.column_names.size() >= 2) { // "schema_name.table_name" auto catalog_entry = binding->GetStandardEntry(); if (!catalog_entry) { return nullptr; } - auto &schema_name = colref.column_names[0]; - if (catalog_entry->schema->name != schema_name || catalog_entry->name != table_name) { + if (catalog_entry->name != table_name) { return nullptr; } + if (colref.column_names.size() == 2) { + auto &qualifier = colref.column_names[0]; + if (catalog_entry->catalog->GetName() != qualifier && catalog_entry->schema->name != qualifier) { + return nullptr; + } + } else if (colref.column_names.size() == 3) { + auto &catalog_name = colref.column_names[0]; + auto &schema_name = colref.column_names[1]; + if (catalog_entry->catalog->GetName() != catalog_name || catalog_entry->schema->name != schema_name) { + return nullptr; + } + } else { + throw InternalException("Expected 2 or 3 column names for CreateStructPack"); + } } // We found the table, now create the struct_pack expression vector> child_exprs; for (const auto &column_name : binding->names) { child_exprs.push_back(make_unique(column_name, table_name)); } - return make_unique("struct_pack", move(child_exprs)); + return make_unique("struct_pack", std::move(child_exprs)); } unique_ptr ExpressionBinder::QualifyColumnName(ColumnRefExpression &colref, string &error_message) { @@ -197813,29 +209054,46 @@ unique_ptr ExpressionBinder::QualifyColumnName(ColumnRefExpres auto qualified_colref = QualifyColumnName(colref.column_names[0], other_error); if (qualified_colref) { // we could: create a struct extract - return CreateStructExtract(move(qualified_colref), colref.column_names[1]); + return CreateStructExtract(std::move(qualified_colref), colref.column_names[1]); } // we could not! Try creating an implicit struct_pack return CreateStructPack(colref); } } else { // two or more dots (i.e. "part1.part2.part3.part4...") + // -> part1 is a catalog, part2 is a schema, part3 is a table, part4 is a column name, part 5 and beyond are + // struct fields + // -> part1 is a catalog, part2 is a table, part3 is a column name, part4 and beyond are struct fields // -> part1 is a schema, part2 is a table, part3 is a column name, part4 and beyond are struct fields // -> part1 is a table, part2 is a column name, part3 and beyond are struct fields // -> part1 is a column, part2 and beyond are struct fields // we always prefer the most top-level view // i.e. in case of multiple resolution options, we resolve in order: - // -> 1. resolve "part1" as a schema - // -> 2. resolve "part1" as a table - // -> 3. resolve "part1" as a column + // -> 1. resolve "part1" as a catalog + // -> 2. resolve "part1" as a schema + // -> 3. resolve "part1" as a table + // -> 4. resolve "part1" as a column unique_ptr result_expr; idx_t struct_extract_start; - // first check if part1 is a schema - if (binder.HasMatchingBinding(colref.column_names[0], colref.column_names[1], colref.column_names[2], - error_message)) { - // it is! the column reference is "schema.table.column" + // first check if part1 is a catalog + if (colref.column_names.size() > 3 && + binder.HasMatchingBinding(colref.column_names[0], colref.column_names[1], colref.column_names[2], + colref.column_names[3], error_message)) { + // part1 is a catalog - the column reference is "catalog.schema.table.column" + result_expr = binder.bind_context.CreateColumnReference(colref.column_names[0], colref.column_names[1], + colref.column_names[2], colref.column_names[3]); + struct_extract_start = 4; + } else if (binder.HasMatchingBinding(colref.column_names[0], INVALID_SCHEMA, colref.column_names[1], + colref.column_names[2], error_message)) { + // part1 is a catalog - the column reference is "catalog.table.column" + result_expr = binder.bind_context.CreateColumnReference(colref.column_names[0], INVALID_SCHEMA, + colref.column_names[1], colref.column_names[2]); + struct_extract_start = 3; + } else if (binder.HasMatchingBinding(colref.column_names[0], colref.column_names[1], colref.column_names[2], + error_message)) { + // part1 is a schema - the column reference is "schema.table.column" // any additional fields are turned into struct_extract calls result_expr = binder.bind_context.CreateColumnReference(colref.column_names[0], colref.column_names[1], colref.column_names[2]); @@ -197851,14 +209109,14 @@ unique_ptr ExpressionBinder::QualifyColumnName(ColumnRefExpres string col_error; result_expr = QualifyColumnName(colref.column_names[0], col_error); if (!result_expr) { - // it is not! return the error - return nullptr; + // it is not! Try creating an implicit struct_pack + return CreateStructPack(colref); } // it is! add the struct extract calls struct_extract_start = 1; } for (idx_t i = struct_extract_start; i < colref.column_names.size(); i++) { - result_expr = CreateStructExtract(move(result_expr), colref.column_names[i]); + result_expr = CreateStructExtract(std::move(result_expr), colref.column_names[i]); } return result_expr; } @@ -197880,7 +209138,7 @@ BindResult ExpressionBinder::BindExpression(ColumnRefExpression &colref_p, idx_t auto alias = expr->alias; auto result = BindExpression(&expr, depth); if (result.expression) { - result.expression->alias = move(alias); + result.expression->alias = std::move(alias); } return result; } @@ -197900,7 +209158,7 @@ BindResult ExpressionBinder::BindExpression(ColumnRefExpression &colref_p, idx_t if (lambda_bindings) { for (idx_t i = 0; i < lambda_bindings->size(); i++) { if (table_name == (*lambda_bindings)[i].alias) { - result = (*lambda_bindings)[i].Bind(colref, depth); + result = (*lambda_bindings)[i].Bind(colref, i, depth); found_lambda_binding = true; break; } @@ -197919,7 +209177,7 @@ BindResult ExpressionBinder::BindExpression(ColumnRefExpression &colref_p, idx_t BoundColumnReferenceInfo ref; ref.name = colref.column_names.back(); ref.query_location = colref.query_location; - bound_columns.push_back(move(ref)); + bound_columns.push_back(std::move(ref)); } else { result.error = binder.FormatError(colref_p, result.error); } @@ -197962,7 +209220,7 @@ unique_ptr ExpressionBinder::PushCollation(ClientContext &context, u // binary collation: just skip return source; } - auto &catalog = Catalog::GetCatalog(context); + auto &catalog = Catalog::GetSystemCatalog(context); auto splits = StringUtil::Split(StringUtil::Lower(collation), "."); vector entries; for (auto &collation_argument : splits) { @@ -197982,11 +209240,11 @@ unique_ptr ExpressionBinder::PushCollation(ClientContext &context, u continue; } vector> children; - children.push_back(move(source)); + children.push_back(std::move(source)); FunctionBinder function_binder(context); - auto function = function_binder.BindScalarFunction(collation_entry->function, move(children)); - source = move(function); + auto function = function_binder.BindScalarFunction(collation_entry->function, std::move(children)); + source = std::move(function); } return source; } @@ -198056,19 +209314,20 @@ BindResult ExpressionBinder::BindExpression(ComparisonExpression &expr, idx_t de // now obtain the result type of the input types auto input_type = BoundComparisonExpression::BindComparison(left_sql_type, right_sql_type); // add casts (if necessary) - left.expr = BoundCastExpression::AddCastToType(context, move(left.expr), input_type, + left.expr = BoundCastExpression::AddCastToType(context, std::move(left.expr), input_type, input_type.id() == LogicalTypeId::ENUM); - right.expr = BoundCastExpression::AddCastToType(context, move(right.expr), input_type, + right.expr = BoundCastExpression::AddCastToType(context, std::move(right.expr), input_type, input_type.id() == LogicalTypeId::ENUM); if (input_type.id() == LogicalTypeId::VARCHAR) { // handle collation auto collation = StringType::GetCollation(input_type); - left.expr = PushCollation(context, move(left.expr), collation, expr.type == ExpressionType::COMPARE_EQUAL); - right.expr = PushCollation(context, move(right.expr), collation, expr.type == ExpressionType::COMPARE_EQUAL); + left.expr = PushCollation(context, std::move(left.expr), collation, expr.type == ExpressionType::COMPARE_EQUAL); + right.expr = + PushCollation(context, std::move(right.expr), collation, expr.type == ExpressionType::COMPARE_EQUAL); } // now create the bound comparison expression - return BindResult(make_unique(expr.type, move(left.expr), move(right.expr))); + return BindResult(make_unique(expr.type, std::move(left.expr), std::move(right.expr))); } } // namespace duckdb @@ -198094,10 +209353,11 @@ BindResult ExpressionBinder::BindExpression(ConjunctionExpression &expr, idx_t d auto result = make_unique(expr.type); for (auto &child_expr : expr.children) { auto &child = (BoundExpression &)*child_expr; - result->children.push_back(BoundCastExpression::AddCastToType(context, move(child.expr), LogicalType::BOOLEAN)); + result->children.push_back( + BoundCastExpression::AddCastToType(context, std::move(child.expr), LogicalType::BOOLEAN)); } // now create the bound conjunction expression - return BindResult(move(result)); + return BindResult(std::move(result)); } } // namespace duckdb @@ -198125,6 +209385,7 @@ BindResult ExpressionBinder::BindExpression(ConstantExpression &expr, idx_t dept + namespace duckdb { BindResult ExpressionBinder::BindExpression(FunctionExpression &function, idx_t depth, @@ -198138,9 +209399,31 @@ BindResult ExpressionBinder::BindExpression(FunctionExpression &function, idx_t // have unnest live in catalog, too return BindUnnest(function, depth); } - auto &catalog = Catalog::GetCatalog(context); - auto func = catalog.GetEntry(context, CatalogType::SCALAR_FUNCTION_ENTRY, function.schema, function.function_name, - false, error_context); + auto func = Catalog::GetEntry(context, CatalogType::SCALAR_FUNCTION_ENTRY, function.catalog, function.schema, + function.function_name, true, error_context); + if (!func) { + // function was not found - check if we this is a table function + auto table_func = Catalog::GetEntry(context, CatalogType::TABLE_FUNCTION_ENTRY, function.catalog, + function.schema, function.function_name, true, error_context); + if (table_func) { + throw BinderException(binder.FormatError( + function, + StringUtil::Format("Function \"%s\" is a table function but it was used as a scalar function. This " + "function has to be called in a FROM clause (similar to a table).", + function.function_name))); + } + // not a table function - search again without if_exists to throw the error + Catalog::GetEntry(context, CatalogType::SCALAR_FUNCTION_ENTRY, function.catalog, function.schema, + function.function_name, false, error_context); + throw InternalException("Catalog::GetEntry for scalar function did not throw a second time"); + } + + if (func->type != CatalogType::AGGREGATE_FUNCTION_ENTRY && + (function.distinct || function.filter || !function.order_bys->orders.empty())) { + throw InvalidInputException("Function \"%s\" is a %s. \"DISTINCT\", \"FILTER\", and \"ORDER BY\" are only " + "applicable to aggregate functions.", + function.function_name, CatalogTypeToString(func->type)); + } switch (func->type) { case CatalogType::SCALAR_FUNCTION_ENTRY: @@ -198190,16 +209473,16 @@ BindResult ExpressionBinder::BindFunction(FunctionExpression &function, ScalarFu for (idx_t i = 0; i < function.children.size(); i++) { auto &child = (BoundExpression &)*function.children[i]; D_ASSERT(child.expr); - children.push_back(move(child.expr)); + children.push_back(std::move(child.expr)); } FunctionBinder function_binder(context); unique_ptr result = - function_binder.BindScalarFunction(*func, move(children), error, function.is_operator, &binder); + function_binder.BindScalarFunction(*func, std::move(children), error, function.is_operator, &binder); if (!result) { throw BinderException(binder.FormatError(function, error)); } - return BindResult(move(result)); + return BindResult(std::move(result)); } BindResult ExpressionBinder::BindLambdaFunction(FunctionExpression &function, ScalarFunctionCatalogEntry *func, @@ -198243,7 +209526,7 @@ BindResult ExpressionBinder::BindLambdaFunction(FunctionExpression &function, Sc } else { // successfully bound: replace the node with a BoundExpression auto alias = function.children[1]->alias; - function.children[1] = make_unique(move(bind_lambda_result.expression)); + function.children[1] = make_unique(std::move(bind_lambda_result.expression)); auto be = (BoundExpression *)function.children[1].get(); D_ASSERT(be); be->alias = alias; @@ -198265,34 +209548,53 @@ BindResult ExpressionBinder::BindLambdaFunction(FunctionExpression &function, Sc for (idx_t i = 0; i < function.children.size(); i++) { auto &child = (BoundExpression &)*function.children[i]; D_ASSERT(child.expr); - children.push_back(move(child.expr)); + children.push_back(std::move(child.expr)); } // capture the (lambda) columns auto &bound_lambda_expr = (BoundLambdaExpression &)*children.back(); - CaptureLambdaColumns(bound_lambda_expr.captures, list_child_type, bound_lambda_expr.lambda_expr, - children[0]->alias); + CaptureLambdaColumns(bound_lambda_expr.captures, list_child_type, bound_lambda_expr.lambda_expr); FunctionBinder function_binder(context); unique_ptr result = - function_binder.BindScalarFunction(*func, move(children), error, function.is_operator, &binder); + function_binder.BindScalarFunction(*func, std::move(children), error, function.is_operator, &binder); if (!result) { throw BinderException(binder.FormatError(function, error)); } - // remove the lambda expression from the children auto &bound_function_expr = (BoundFunctionExpression &)*result; - auto lambda = move(bound_function_expr.children.back()); + D_ASSERT(bound_function_expr.children.size() == 2); + + // remove the lambda expression from the children + auto lambda = std::move(bound_function_expr.children.back()); bound_function_expr.children.pop_back(); auto &bound_lambda = (BoundLambdaExpression &)*lambda; + // push back (in reverse order) any nested lambda parameters so that we can later use them in the lambda expression + // (rhs) + if (lambda_bindings) { + for (idx_t i = lambda_bindings->size(); i > 0; i--) { + + idx_t lambda_index = lambda_bindings->size() - i + 1; + auto &binding = (*lambda_bindings)[i - 1]; + + D_ASSERT(binding.names.size() == 1); + D_ASSERT(binding.types.size() == 1); + + bound_function_expr.function.arguments.push_back(binding.types[0]); + auto bound_lambda_param = + make_unique(binding.names[0], binding.types[0], lambda_index); + bound_function_expr.children.push_back(std::move(bound_lambda_param)); + } + } + // push back the captures into the children vector and the correct return types into the bound_function arguments for (auto &capture : bound_lambda.captures) { bound_function_expr.function.arguments.push_back(capture->return_type); - bound_function_expr.children.push_back(move(capture)); + bound_function_expr.children.push_back(std::move(capture)); } - return BindResult(move(result)); + return BindResult(std::move(result)); } BindResult ExpressionBinder::BindAggregate(FunctionExpression &expr, AggregateFunctionCatalogEntry *function, @@ -198324,6 +209626,7 @@ string ExpressionBinder::UnsupportedUnnestMessage() { + namespace duckdb { BindResult ExpressionBinder::BindExpression(LambdaExpression &expr, idx_t depth, const bool is_lambda, @@ -198332,7 +209635,7 @@ BindResult ExpressionBinder::BindExpression(LambdaExpression &expr, idx_t depth, if (!is_lambda) { // this is for binding JSON auto lhs_expr = expr.lhs->Copy(); - OperatorExpression arrow_expr(ExpressionType::ARROW, move(lhs_expr), expr.expr->Copy()); + OperatorExpression arrow_expr(ExpressionType::ARROW, std::move(lhs_expr), expr.expr->Copy()); return BindExpression(arrow_expr, depth); } @@ -198346,11 +209649,11 @@ BindResult ExpressionBinder::BindExpression(LambdaExpression &expr, idx_t depth, // move the lambda parameters to the params vector if (expr.lhs->expression_class == ExpressionClass::COLUMN_REF) { - expr.params.push_back(move(expr.lhs)); + expr.params.push_back(std::move(expr.lhs)); } else { auto &func_expr = (FunctionExpression &)*expr.lhs; for (idx_t i = 0; i < func_expr.children.size(); i++) { - expr.params.push_back(move(func_expr.children[i])); + expr.params.push_back(std::move(func_expr.children[i])); } } D_ASSERT(!expr.params.empty()); @@ -198411,39 +209714,54 @@ BindResult ExpressionBinder::BindExpression(LambdaExpression &expr, idx_t depth, } return BindResult(make_unique(ExpressionType::LAMBDA, LogicalType::LAMBDA, - move(result.expression), params_strings.size())); + std::move(result.expression), params_strings.size())); } void ExpressionBinder::TransformCapturedLambdaColumn(unique_ptr &original, unique_ptr &replacement, vector> &captures, - LogicalType &list_child_type, string &alias) { + LogicalType &list_child_type) { // check if the original expression is a lambda parameter - bool is_lambda_parameter = false; - if (original->expression_class == ExpressionClass::BOUND_COLUMN_REF) { + if (original->expression_class == ExpressionClass::BOUND_LAMBDA_REF) { // determine if this is the lambda parameter - auto &bound_col_ref = (BoundColumnRefExpression &)*original; - if (bound_col_ref.binding.table_index == DConstants::INVALID_INDEX) { - is_lambda_parameter = true; - } - } + auto &bound_lambda_ref = (BoundLambdaRefExpression &)*original; + auto alias = bound_lambda_ref.alias; - if (is_lambda_parameter) { - // this is a lambda parameter, so the replacement refers to the first argument, which is the list - replacement = make_unique(alias, list_child_type, 0); + if (lambda_bindings && bound_lambda_ref.lambda_index != lambda_bindings->size()) { + + D_ASSERT(bound_lambda_ref.lambda_index < lambda_bindings->size()); + auto &lambda_binding = (*lambda_bindings)[bound_lambda_ref.lambda_index]; + + D_ASSERT(lambda_binding.names.size() == 1); + D_ASSERT(lambda_binding.types.size() == 1); + // refers to a lambda parameter outside of the current lambda function + replacement = + make_unique(lambda_binding.names[0], lambda_binding.types[0], + lambda_bindings->size() - bound_lambda_ref.lambda_index + 1); + + } else { + // refers to current lambda parameter + replacement = make_unique(alias, list_child_type, 0); + } } else { + // always at least the current lambda parameter + idx_t index_offset = 1; + if (lambda_bindings) { + index_offset += lambda_bindings->size(); + } + // this is not a lambda parameter, so we need to create a new argument for the arguments vector - replacement = - make_unique(original->alias, original->return_type, captures.size() + 1); - captures.push_back(move(original)); + replacement = make_unique(original->alias, original->return_type, + captures.size() + index_offset + 1); + captures.push_back(std::move(original)); } } void ExpressionBinder::CaptureLambdaColumns(vector> &captures, LogicalType &list_child_type, - unique_ptr &expr, string &alias) { + unique_ptr &expr) { if (expr->expression_class == ExpressionClass::BOUND_SUBQUERY) { throw InvalidInputException("Subqueries are not supported in lambda expressions!"); @@ -198452,23 +209770,25 @@ void ExpressionBinder::CaptureLambdaColumns(vector> &capt // these expression classes do not have children, transform them if (expr->expression_class == ExpressionClass::BOUND_CONSTANT || expr->expression_class == ExpressionClass::BOUND_COLUMN_REF || - expr->expression_class == ExpressionClass::BOUND_PARAMETER) { + expr->expression_class == ExpressionClass::BOUND_PARAMETER || + expr->expression_class == ExpressionClass::BOUND_LAMBDA_REF) { // move the expr because we are going to replace it - auto original = move(expr); + auto original = std::move(expr); unique_ptr replacement; - TransformCapturedLambdaColumn(original, replacement, captures, list_child_type, alias); + TransformCapturedLambdaColumn(original, replacement, captures, list_child_type); // replace the expression - expr = move(replacement); + expr = std::move(replacement); } else { // recursively enumerate the children of the expression - ExpressionIterator::EnumerateChildren(*expr, [&](unique_ptr &child) { - CaptureLambdaColumns(captures, list_child_type, child, alias); - }); + ExpressionIterator::EnumerateChildren( + *expr, [&](unique_ptr &child) { CaptureLambdaColumns(captures, list_child_type, child); }); } + + expr->Verify(); } } // namespace duckdb @@ -198547,7 +209867,7 @@ BindResult ExpressionBinder::BindMacro(FunctionExpression &function, ScalarMacro types.emplace_back(LogicalType::SQLNULL); names.push_back(it->first); // now push the defaults into the positionals - positionals.push_back(move(defaults[it->first])); + positionals.push_back(std::move(defaults[it->first])); } auto new_macro_binding = make_unique(types, names, macro_func->name); new_macro_binding->arguments = &positionals; @@ -198575,7 +209895,7 @@ namespace duckdb { static LogicalType ResolveNotType(OperatorExpression &op, vector &children) { // NOT expression, cast child to BOOLEAN D_ASSERT(children.size() == 1); - children[0]->expr = BoundCastExpression::AddDefaultCastToType(move(children[0]->expr), LogicalType::BOOLEAN); + children[0]->expr = BoundCastExpression::AddDefaultCastToType(std::move(children[0]->expr), LogicalType::BOOLEAN); return LogicalType(LogicalTypeId::BOOLEAN); } @@ -198591,7 +209911,7 @@ static LogicalType ResolveInType(OperatorExpression &op, vectorexpr = BoundCastExpression::AddDefaultCastToType(move(children[i]->expr), max_type); + children[i]->expr = BoundCastExpression::AddDefaultCastToType(std::move(children[i]->expr), max_type); } // (NOT) IN always returns a boolean return LogicalType::BOOLEAN; @@ -198678,7 +209998,7 @@ BindResult ExpressionBinder::BindExpression(OperatorExpression &op, idx_t depth) break; } if (!function_name.empty()) { - auto function = make_unique(function_name, move(op.children)); + auto function = make_unique(function_name, std::move(op.children)); return BindExpression(*function, depth, nullptr); } @@ -198694,15 +210014,15 @@ BindResult ExpressionBinder::BindExpression(OperatorExpression &op, idx_t depth) throw BinderException("COALESCE needs at least one child"); } if (children.size() == 1) { - return BindResult(move(children[0]->expr)); + return BindResult(std::move(children[0]->expr)); } } auto result = make_unique(op.type, result_type); for (auto &child : children) { - result->children.push_back(move(child->expr)); + result->children.push_back(std::move(child->expr)); } - return BindResult(move(result)); + return BindResult(std::move(result)); } } // namespace duckdb @@ -198728,7 +210048,7 @@ BindResult ExpressionBinder::BindExpression(ParameterExpression &expr, idx_t dep auto &data = binder.parameters->parameter_data[parameter_idx - 1]; auto constant = make_unique(data.value); constant->alias = expr.alias; - return BindResult(move(constant)); + return BindResult(std::move(constant)); } auto entry = binder.parameters->parameters.find(parameter_idx); if (entry == binder.parameters->parameters.end()) { @@ -198737,14 +210057,14 @@ BindResult ExpressionBinder::BindExpression(ParameterExpression &expr, idx_t dep data->return_type = binder.parameters->GetReturnType(parameter_idx - 1); bound_parameter->return_type = data->return_type; bound_parameter->parameter_data = data; - binder.parameters->parameters[parameter_idx] = move(data); + binder.parameters->parameters[parameter_idx] = std::move(data); } else { // a prepared statement with this parameter index was already there: use it auto &data = entry->second; bound_parameter->parameter_data = data; bound_parameter->return_type = binder.parameters->GetReturnType(parameter_idx - 1); } - return BindResult(move(bound_parameter)); + return BindResult(std::move(bound_parameter)); } } // namespace duckdb @@ -198775,8 +210095,8 @@ class BoundSubqueryNode : public QueryNode { public: BoundSubqueryNode(shared_ptr subquery_binder, unique_ptr bound_node, unique_ptr subquery) - : QueryNode(QueryNodeType::BOUND_SUBQUERY_NODE), subquery_binder(move(subquery_binder)), - bound_node(move(bound_node)), subquery(move(subquery)) { + : QueryNode(QueryNodeType::BOUND_SUBQUERY_NODE), subquery_binder(std::move(subquery_binder)), + bound_node(std::move(bound_node)), subquery(std::move(subquery)) { } shared_ptr subquery_binder; @@ -198819,10 +210139,10 @@ BindResult ExpressionBinder::BindExpression(SubqueryExpression &expr, idx_t dept throw BinderException(binder.FormatError( expr, StringUtil::Format("Subquery returns %zu columns - expected 1", bound_node->types.size()))); } - auto prior_subquery = move(expr.subquery); + auto prior_subquery = std::move(expr.subquery); expr.subquery = make_unique(); - expr.subquery->node = - make_unique(move(subquery_binder), move(bound_node), move(prior_subquery)); + expr.subquery->node = make_unique(std::move(subquery_binder), std::move(bound_node), + std::move(prior_subquery)); } // now bind the child node of the subquery if (expr.child) { @@ -198836,8 +210156,8 @@ BindResult ExpressionBinder::BindExpression(SubqueryExpression &expr, idx_t dept D_ASSERT(expr.subquery->node->type == QueryNodeType::BOUND_SUBQUERY_NODE); auto bound_subquery = (BoundSubqueryNode *)expr.subquery->node.get(); auto child = (BoundExpression *)expr.child.get(); - auto subquery_binder = move(bound_subquery->subquery_binder); - auto bound_node = move(bound_subquery->bound_node); + auto subquery_binder = std::move(bound_subquery->subquery_binder); + auto bound_node = std::move(bound_subquery->bound_node); LogicalType return_type = expr.subquery_type == SubqueryType::SCALAR ? bound_node->types[0] : LogicalType(LogicalTypeId::BOOLEAN); if (return_type.id() == LogicalTypeId::UNKNOWN) { @@ -198850,17 +210170,17 @@ BindResult ExpressionBinder::BindExpression(SubqueryExpression &expr, idx_t dept // cast child and subquery child to equivalent types D_ASSERT(bound_node->types.size() == 1); auto compare_type = LogicalType::MaxLogicalType(child->expr->return_type, bound_node->types[0]); - child->expr = BoundCastExpression::AddCastToType(context, move(child->expr), compare_type); + child->expr = BoundCastExpression::AddCastToType(context, std::move(child->expr), compare_type); result->child_type = bound_node->types[0]; result->child_target = compare_type; } - result->binder = move(subquery_binder); - result->subquery = move(bound_node); + result->binder = std::move(subquery_binder); + result->subquery = std::move(bound_node); result->subquery_type = expr.subquery_type; - result->child = child ? move(child->expr) : nullptr; + result->child = child ? std::move(child->expr) : nullptr; result->comparison_type = expr.comparison_type; - return BindResult(move(result)); + return BindResult(std::move(result)); } } // namespace duckdb @@ -198914,10 +210234,10 @@ BindResult SelectBinder::BindUnnest(FunctionExpression &function, idx_t depth) { } auto result = make_unique(return_type); - result->child = move(child.expr); + result->child = std::move(child.expr); auto unnest_index = node.unnests.size(); - node.unnests.push_back(move(result)); + node.unnests.push_back(std::move(result)); // TODO what if we have multiple unnests in the same projection list? ignore for now @@ -198926,7 +210246,7 @@ BindResult SelectBinder::BindUnnest(FunctionExpression &function, idx_t depth) { function.alias.empty() ? node.unnests[unnest_index]->ToString() : function.alias, return_type, ColumnBinding(node.unnest_index, unnest_index), depth); - return BindResult(move(colref)); + return BindResult(std::move(colref)); } } // namespace duckdb @@ -199010,7 +210330,7 @@ static unique_ptr GetExpression(unique_ptr &expr) } D_ASSERT(expr.get()); D_ASSERT(expr->expression_class == ExpressionClass::BOUND_EXPRESSION); - return move(((BoundExpression &)*expr).expr); + return std::move(((BoundExpression &)*expr).expr); } static unique_ptr CastWindowExpression(unique_ptr &expr, const LogicalType &type) { @@ -199021,9 +210341,9 @@ static unique_ptr CastWindowExpression(unique_ptr D_ASSERT(expr->expression_class == ExpressionClass::BOUND_EXPRESSION); auto &bound = (BoundExpression &)*expr; - bound.expr = BoundCastExpression::AddDefaultCastToType(move(bound.expr), type); + bound.expr = BoundCastExpression::AddDefaultCastToType(std::move(bound.expr), type); - return move(bound.expr); + return std::move(bound.expr); } static LogicalType BindRangeExpression(ClientContext &context, const string &name, unique_ptr &expr, @@ -199039,15 +210359,15 @@ static LogicalType BindRangeExpression(ClientContext &context, const string &nam D_ASSERT(expr.get()); D_ASSERT(expr->expression_class == ExpressionClass::BOUND_EXPRESSION); auto &bound = (BoundExpression &)*expr; - children.emplace_back(move(bound.expr)); + children.emplace_back(std::move(bound.expr)); string error; FunctionBinder function_binder(context); - auto function = function_binder.BindScalarFunction(DEFAULT_SCHEMA, name, move(children), error, true); + auto function = function_binder.BindScalarFunction(DEFAULT_SCHEMA, name, std::move(children), error, true); if (!function) { throw BinderException(error); } - bound.expr = move(function); + bound.expr = std::move(function); return bound.expr->return_type; } @@ -199104,19 +210424,19 @@ BindResult SelectBinder::BindWindow(WindowExpression &window, idx_t depth) { case ExpressionType::WINDOW_NTILE: // ntile(bigint) if (argno == 0) { - bound.expr = BoundCastExpression::AddCastToType(context, move(bound.expr), LogicalType::BIGINT); + bound.expr = BoundCastExpression::AddCastToType(context, std::move(bound.expr), LogicalType::BIGINT); } break; case ExpressionType::WINDOW_NTH_VALUE: // nth_value(, index) if (argno == 1) { - bound.expr = BoundCastExpression::AddCastToType(context, move(bound.expr), LogicalType::BIGINT); + bound.expr = BoundCastExpression::AddCastToType(context, std::move(bound.expr), LogicalType::BIGINT); } default: break; } types.push_back(bound.expr->return_type); - children.push_back(move(bound.expr)); + children.push_back(std::move(bound.expr)); } // Determine the function type. LogicalType sql_type; @@ -199124,9 +210444,8 @@ BindResult SelectBinder::BindWindow(WindowExpression &window, idx_t depth) { unique_ptr bind_info; if (window.type == ExpressionType::WINDOW_AGGREGATE) { // Look up the aggregate function in the catalog - auto func = - (AggregateFunctionCatalogEntry *)Catalog::GetCatalog(context).GetEntry( - context, window.schema, window.function_name, false, error_context); + auto func = Catalog::GetEntry(context, window.catalog, window.schema, + window.function_name, false, error_context); D_ASSERT(func->type == CatalogType::AGGREGATE_FUNCTION_ENTRY); // bind the aggregate @@ -199138,18 +210457,18 @@ BindResult SelectBinder::BindWindow(WindowExpression &window, idx_t depth) { } // found a matching function! bind it as an aggregate auto bound_function = func->functions.GetFunctionByOffset(best_function); - auto bound_aggregate = function_binder.BindAggregateFunction(bound_function, move(children)); + auto bound_aggregate = function_binder.BindAggregateFunction(bound_function, std::move(children)); // create the aggregate aggregate = make_unique(bound_aggregate->function); - bind_info = move(bound_aggregate->bind_info); - children = move(bound_aggregate->children); + bind_info = std::move(bound_aggregate->bind_info); + children = std::move(bound_aggregate->children); sql_type = bound_aggregate->return_type; } else { // fetch the child of the non-aggregate window function (if any) sql_type = ResolveWindowExpressionType(window.type, types); } - auto result = make_unique(window.type, sql_type, move(aggregate), move(bind_info)); - result->children = move(children); + auto result = make_unique(window.type, sql_type, std::move(aggregate), std::move(bind_info)); + result->children = std::move(children); for (auto &child : window.partitions) { result->partitions.push_back(GetExpression(child)); } @@ -199204,7 +210523,7 @@ BindResult SelectBinder::BindWindow(WindowExpression &window, idx_t depth) { } // Cast all three to match - bound_order.expr = BoundCastExpression::AddCastToType(context, move(bound_order.expr), order_type); + bound_order.expr = BoundCastExpression::AddCastToType(context, std::move(bound_order.expr), order_type); start_type = end_type = order_type; } @@ -199212,7 +210531,7 @@ BindResult SelectBinder::BindWindow(WindowExpression &window, idx_t depth) { auto type = ResolveOrderType(config, order.type); auto null_order = ResolveNullOrder(config, order.null_order); auto expression = GetExpression(order.expression); - result->orders.emplace_back(type, null_order, move(expression)); + result->orders.emplace_back(type, null_order, std::move(expression)); } result->filter_expr = CastWindowExpression(window.filter_expr, LogicalType::BOOLEAN); @@ -199225,11 +210544,11 @@ BindResult SelectBinder::BindWindow(WindowExpression &window, idx_t depth) { result->end = window.end; // create a BoundColumnRef that references this entry - auto colref = make_unique(move(name), result->return_type, + auto colref = make_unique(std::move(name), result->return_type, ColumnBinding(node.window_index, node.windows.size()), depth); // move the WINDOW expression into the set of bound windows - node.windows.push_back(move(result)); - return BindResult(move(colref)); + node.windows.push_back(std::move(result)); + return BindResult(std::move(colref)); } } // namespace duckdb @@ -199334,7 +210653,7 @@ unique_ptr Binder::BindNode(RecursiveCTENode &statement) { throw NotImplementedException("FIXME: bind modifiers in recursive CTE"); } - return move(result); + return std::move(result); } } // namespace duckdb @@ -199379,7 +210698,7 @@ class ColumnAliasBinder { private: BoundSelectNode &node; const case_insensitive_map_t &alias_map; - bool in_alias; + unordered_set visited_select_indexes; }; } // namespace duckdb @@ -199594,7 +210913,7 @@ namespace duckdb { unique_ptr Binder::BindOrderExpression(OrderBinder &order_binder, unique_ptr expr) { // we treat the Distinct list as a order by - auto bound_expr = order_binder.Bind(move(expr)); + auto bound_expr = order_binder.Bind(std::move(expr)); if (!bound_expr) { // DISTINCT ON non-integer constant // remove the expression from the DISTINCT ON list @@ -199612,7 +210931,7 @@ unique_ptr Binder::BindDelimiter(ClientContext &context, OrderBinder if (!order_binder.HasExtraList()) { throw BinderException("Subquery in LIMIT/OFFSET not supported in set operation"); } - return order_binder.CreateExtraReference(move(delimiter)); + return order_binder.CreateExtraReference(std::move(delimiter)); } ExpressionBinder expr_binder(*new_binder, context); expr_binder.target_type = type; @@ -199634,7 +210953,7 @@ unique_ptr Binder::BindLimit(OrderBinder &order_binder, Lim auto result = make_unique(); if (limit_mod.limit) { Value val; - result->limit = BindDelimiter(context, order_binder, move(limit_mod.limit), LogicalType::BIGINT, val); + result->limit = BindDelimiter(context, order_binder, std::move(limit_mod.limit), LogicalType::BIGINT, val); if (!result->limit) { result->limit_val = val.IsNull() ? NumericLimits::Maximum() : val.GetValue(); if (result->limit_val < 0) { @@ -199644,7 +210963,7 @@ unique_ptr Binder::BindLimit(OrderBinder &order_binder, Lim } if (limit_mod.offset) { Value val; - result->offset = BindDelimiter(context, order_binder, move(limit_mod.offset), LogicalType::BIGINT, val); + result->offset = BindDelimiter(context, order_binder, std::move(limit_mod.offset), LogicalType::BIGINT, val); if (!result->offset) { result->offset_val = val.IsNull() ? 0 : val.GetValue(); if (result->offset_val < 0) { @@ -199652,14 +210971,14 @@ unique_ptr Binder::BindLimit(OrderBinder &order_binder, Lim } } } - return move(result); + return std::move(result); } unique_ptr Binder::BindLimitPercent(OrderBinder &order_binder, LimitPercentModifier &limit_mod) { auto result = make_unique(); if (limit_mod.limit) { Value val; - result->limit = BindDelimiter(context, order_binder, move(limit_mod.limit), LogicalType::DOUBLE, val); + result->limit = BindDelimiter(context, order_binder, std::move(limit_mod.limit), LogicalType::DOUBLE, val); if (!result->limit) { result->limit_percent = val.IsNull() ? 100 : val.GetValue(); if (result->limit_percent < 0.0) { @@ -199669,12 +210988,12 @@ unique_ptr Binder::BindLimitPercent(OrderBinder &order_bind } if (limit_mod.offset) { Value val; - result->offset = BindDelimiter(context, order_binder, move(limit_mod.offset), LogicalType::BIGINT, val); + result->offset = BindDelimiter(context, order_binder, std::move(limit_mod.offset), LogicalType::BIGINT, val); if (!result->offset) { result->offset_val = val.IsNull() ? 0 : val.GetValue(); } } - return move(result); + return std::move(result); } void Binder::BindModifiers(OrderBinder &order_binder, QueryNode &statement, BoundQueryNode &result) { @@ -199690,13 +211009,13 @@ void Binder::BindModifiers(OrderBinder &order_binder, QueryNode &statement, Boun } } for (auto &distinct_on_target : distinct.distinct_on_targets) { - auto expr = BindOrderExpression(order_binder, move(distinct_on_target)); + auto expr = BindOrderExpression(order_binder, std::move(distinct_on_target)); if (!expr) { continue; } - bound_distinct->target_distincts.push_back(move(expr)); + bound_distinct->target_distincts.push_back(std::move(expr)); } - bound_modifier = move(bound_distinct); + bound_modifier = std::move(bound_distinct); break; } case ResultModifierType::ORDER_MODIFIER: { @@ -199716,10 +211035,10 @@ void Binder::BindModifiers(OrderBinder &order_binder, QueryNode &statement, Boun new_orders.emplace_back(order_type, null_order, make_unique(Value::INTEGER(i + 1))); } - order.orders = move(new_orders); + order.orders = std::move(new_orders); } for (auto &order_node : order.orders) { - auto order_expression = BindOrderExpression(order_binder, move(order_node.expression)); + auto order_expression = BindOrderExpression(order_binder, std::move(order_node.expression)); if (!order_expression) { continue; } @@ -199728,10 +211047,10 @@ void Binder::BindModifiers(OrderBinder &order_binder, QueryNode &statement, Boun auto null_order = order_node.null_order == OrderByNullType::ORDER_DEFAULT ? config.options.default_null_order : order_node.null_order; - bound_order->orders.emplace_back(type, null_order, move(order_expression)); + bound_order->orders.emplace_back(type, null_order, std::move(order_expression)); } if (!bound_order->orders.empty()) { - bound_modifier = move(bound_order); + bound_modifier = std::move(bound_order); } break; } @@ -199745,7 +211064,7 @@ void Binder::BindModifiers(OrderBinder &order_binder, QueryNode &statement, Boun throw Exception("Unsupported result modifier"); } if (bound_modifier) { - result.modifiers.push_back(move(bound_modifier)); + result.modifiers.push_back(std::move(bound_modifier)); } } } @@ -199789,7 +211108,7 @@ void Binder::BindModifierTypes(BoundQueryNode &result, const vector auto &bound_colref = (BoundColumnRefExpression &)*target_distinct; const auto &sql_type = sql_types[bound_colref.binding.column_index]; if (sql_type.id() == LogicalTypeId::VARCHAR) { - target_distinct = ExpressionBinder::PushCollation(context, move(target_distinct), + target_distinct = ExpressionBinder::PushCollation(context, std::move(target_distinct), StringType::GetCollation(sql_type), true); } } @@ -199820,7 +211139,7 @@ void Binder::BindModifierTypes(BoundQueryNode &result, const vector const auto &sql_type = sql_types[bound_colref.binding.column_index]; bound_colref.return_type = sql_types[bound_colref.binding.column_index]; if (sql_type.id() == LogicalTypeId::VARCHAR) { - order_node.expression = ExpressionBinder::PushCollation(context, move(order_node.expression), + order_node.expression = ExpressionBinder::PushCollation(context, std::move(order_node.expression), StringType::GetCollation(sql_type)); } } @@ -199837,7 +211156,7 @@ bool Binder::FindStarExpression(ParsedExpression &expr, StarExpression **star) { auto current_star = (StarExpression *)&expr; if (*star) { // we can have multiple - if (!StarExpression::Equals(*star, current_star)) { + if (!StarExpression::Equal(*star, current_star)) { throw BinderException( FormatError(expr, "Multiple different STAR/COLUMNS in the same expression are not supported")); } @@ -199872,7 +211191,7 @@ void Binder::ExpandStarExpression(unique_ptr expr, if (!FindStarExpression(*expr, &star)) { // no star expression: add it as-is D_ASSERT(!star); - new_select_list.push_back(move(expr)); + new_select_list.push_back(std::move(expr)); return; } D_ASSERT(star); @@ -199884,14 +211203,14 @@ void Binder::ExpandStarExpression(unique_ptr expr, for (idx_t i = 0; i < star_list.size(); i++) { auto new_expr = expr->Copy(); ReplaceStarExpression(new_expr, star_list[i]); - new_select_list.push_back(move(new_expr)); + new_select_list.push_back(std::move(new_expr)); } } void Binder::ExpandStarExpressions(vector> &select_list, vector> &new_select_list) { for (auto &select_element : select_list) { - ExpandStarExpression(move(select_element), new_select_list); + ExpandStarExpression(std::move(select_element), new_select_list); } } @@ -199910,7 +211229,7 @@ unique_ptr Binder::BindNode(SelectNode &statement) { // bind the sample clause if (statement.sample) { - result->sample_options = move(statement.sample); + result->sample_options = std::move(statement.sample); } // visit the select list and expand any "*" statements @@ -199920,7 +211239,7 @@ unique_ptr Binder::BindNode(SelectNode &statement) { if (new_select_list.empty()) { throw BinderException("SELECT list is empty after resolving * expressions!"); } - statement.select_list = move(new_select_list); + statement.select_list = std::move(new_select_list); // create a mapping of (alias -> index) and a mapping of (Expression -> index) for the SELECT list case_insensitive_map_t alias_map; @@ -199943,7 +211262,7 @@ unique_ptr Binder::BindNode(SelectNode &statement) { if (statement.where_clause) { ColumnAliasBinder alias_binder(*result, alias_map); WhereBinder where_binder(*this, context, &alias_binder); - unique_ptr condition = move(statement.where_clause); + unique_ptr condition = std::move(statement.where_clause); result->where_clause = where_binder.Bind(condition); } @@ -199973,20 +211292,20 @@ unique_ptr Binder::BindNode(SelectNode &statement) { D_ASSERT(bound_expr->return_type.id() != LogicalTypeId::INVALID); // push a potential collation, if necessary - bound_expr = - ExpressionBinder::PushCollation(context, move(bound_expr), StringType::GetCollation(group_type), true); - result->groups.group_expressions.push_back(move(bound_expr)); + bound_expr = ExpressionBinder::PushCollation(context, std::move(bound_expr), + StringType::GetCollation(group_type), true); + result->groups.group_expressions.push_back(std::move(bound_expr)); // in the unbound expression we DO bind the table names of any ColumnRefs // we do this to make sure that "table.a" and "a" are treated the same // if we wouldn't do this then (SELECT test.a FROM test GROUP BY a) would not work because "test.a" <> "a" // hence we convert "a" -> "test.a" in the unbound expression - unbound_groups[i] = move(group_binder.unbound_expression); + unbound_groups[i] = std::move(group_binder.unbound_expression); ExpressionBinder::QualifyColumnNames(*this, unbound_groups[i]); info.map[unbound_groups[i].get()] = i; } } - result->groups.grouping_sets = move(statement.groups.grouping_sets); + result->groups.grouping_sets = std::move(statement.groups.grouping_sets); // bind the HAVING clause, if any if (statement.having) { @@ -200013,6 +211332,7 @@ unique_ptr Binder::BindNode(SelectNode &statement) { vector internal_sql_types; for (idx_t i = 0; i < statement.select_list.size(); i++) { bool is_window = statement.select_list[i]->IsWindow(); + idx_t unnest_count = result->unnests.size(); LogicalType result_type; auto expr = select_binder.Bind(statement.select_list[i], &result_type); if (statement.aggregate_handling == AggregateHandling::FORCE_AGGREGATES && select_binder.HasBoundColumns()) { @@ -200022,14 +211342,17 @@ unique_ptr Binder::BindNode(SelectNode &statement) { if (is_window) { throw BinderException("Cannot group on a window clause"); } + if (result->unnests.size() > unnest_count) { + throw BinderException("Cannot group on an UNNEST or UNLIST clause"); + } // we are forcing aggregates, and the node has columns bound // this entry becomes a group auto group_ref = make_unique( expr->return_type, ColumnBinding(result->group_index, result->groups.group_expressions.size())); - result->groups.group_expressions.push_back(move(expr)); - expr = move(group_ref); + result->groups.group_expressions.push_back(std::move(expr)); + expr = std::move(group_ref); } - result->select_list.push_back(move(expr)); + result->select_list.push_back(std::move(expr)); if (i < result->column_count) { result->types.push_back(result_type); } @@ -200069,7 +211392,7 @@ unique_ptr Binder::BindNode(SelectNode &statement) { // now that the SELECT list is bound, we set the types of DISTINCT/ORDER BY expressions BindModifierTypes(*result, internal_sql_types, result->projection_index); - return move(result); + return std::move(result); } } // namespace duckdb @@ -200278,8 +211601,8 @@ static void BuildUnionByNameInfo(BoundSetOperationNode &result, bool can_contain result.types.push_back(result_type); } - result.left_reorder_idx = move(left_reorder_idx); - result.right_reorder_idx = move(right_reorder_idx); + result.left_reorder_idx = std::move(left_reorder_idx); + result.right_reorder_idx = std::move(right_reorder_idx); // If reorder is required, collect reorder expressions for push projection // into the two child nodes of union node @@ -200309,8 +211632,8 @@ static void BuildUnionByNameInfo(BoundSetOperationNode &result, bool can_contain right_node->types[right_index->second], ColumnBinding(right_node->GetRootIndex(), right_index->second)); } - result.left_reorder_exprs.push_back(move(left_reorder_expr)); - result.right_reorder_exprs.push_back(move(right_reorder_expr)); + result.left_reorder_exprs.push_back(std::move(left_reorder_expr)); + result.right_reorder_exprs.push_back(std::move(right_reorder_expr)); } } } @@ -200388,7 +211711,7 @@ unique_ptr Binder::BindNode(SetOperationNode &statement) { // finally bind the types of the ORDER/DISTINCT clause expressions BindModifierTypes(*result, result->types, result->setop_index); - return move(result); + return std::move(result); } } // namespace duckdb @@ -200443,7 +211766,7 @@ unique_ptr Binder::BindTableMacro(FunctionExpression &function, Table types.emplace_back(LogicalType::SQLNULL); names.push_back(it->first); // now push the defaults into the positionals - positionals.push_back(move(defaults[it->first])); + positionals.push_back(std::move(defaults[it->first])); } auto new_macro_binding = make_unique(types, names, macro_func->name); new_macro_binding->arguments = &positionals; @@ -200476,32 +211799,32 @@ unique_ptr Binder::VisitQueryNode(BoundQueryNode &node, unique_ switch (mod->type) { case ResultModifierType::DISTINCT_MODIFIER: { auto &bound = (BoundDistinctModifier &)*mod; - auto distinct = make_unique(move(bound.target_distincts)); - distinct->AddChild(move(root)); - root = move(distinct); + auto distinct = make_unique(std::move(bound.target_distincts)); + distinct->AddChild(std::move(root)); + root = std::move(distinct); break; } case ResultModifierType::ORDER_MODIFIER: { auto &bound = (BoundOrderModifier &)*mod; - auto order = make_unique(move(bound.orders)); - order->AddChild(move(root)); - root = move(order); + auto order = make_unique(std::move(bound.orders)); + order->AddChild(std::move(root)); + root = std::move(order); break; } case ResultModifierType::LIMIT_MODIFIER: { auto &bound = (BoundLimitModifier &)*mod; - auto limit = - make_unique(bound.limit_val, bound.offset_val, move(bound.limit), move(bound.offset)); - limit->AddChild(move(root)); - root = move(limit); + auto limit = make_unique(bound.limit_val, bound.offset_val, std::move(bound.limit), + std::move(bound.offset)); + limit->AddChild(std::move(root)); + root = std::move(limit); break; } case ResultModifierType::LIMIT_PERCENT_MODIFIER: { auto &bound = (BoundLimitPercentModifier &)*mod; - auto limit = make_unique(bound.limit_percent, bound.offset_val, move(bound.limit), - move(bound.offset)); - limit->AddChild(move(root)); - root = move(limit); + auto limit = make_unique(bound.limit_percent, bound.offset_val, std::move(bound.limit), + std::move(bound.offset)); + limit->AddChild(std::move(root)); + root = std::move(limit); break; } default: @@ -200535,19 +211858,20 @@ unique_ptr Binder::CreatePlan(BoundRecursiveCTENode &node) { node.left_binder->has_unplanned_subqueries || node.right_binder->has_unplanned_subqueries; // for both the left and right sides, cast them to the same types - left_node = CastLogicalOperatorToTypes(node.left->types, node.types, move(left_node)); - right_node = CastLogicalOperatorToTypes(node.right->types, node.types, move(right_node)); + left_node = CastLogicalOperatorToTypes(node.left->types, node.types, std::move(left_node)); + right_node = CastLogicalOperatorToTypes(node.right->types, node.types, std::move(right_node)); if (!node.right_binder->bind_context.cte_references[node.ctename] || *node.right_binder->bind_context.cte_references[node.ctename] == 0) { - auto root = make_unique(node.setop_index, node.types.size(), move(left_node), - move(right_node), LogicalOperatorType::LOGICAL_UNION); - return VisitQueryNode(node, move(root)); + auto root = make_unique(node.setop_index, node.types.size(), std::move(left_node), + std::move(right_node), LogicalOperatorType::LOGICAL_UNION); + return VisitQueryNode(node, std::move(root)); } - auto root = make_unique(node.setop_index, node.types.size(), node.union_all, move(left_node), - move(right_node), LogicalOperatorType::LOGICAL_RECURSIVE_CTE); + auto root = + make_unique(node.setop_index, node.types.size(), node.union_all, std::move(left_node), + std::move(right_node), LogicalOperatorType::LOGICAL_RECURSIVE_CTE); - return VisitQueryNode(node, move(root)); + return VisitQueryNode(node, std::move(root)); } } // namespace duckdb @@ -200565,9 +211889,9 @@ namespace duckdb { unique_ptr Binder::PlanFilter(unique_ptr condition, unique_ptr root) { PlanSubqueries(&condition, &root); - auto filter = make_unique(move(condition)); - filter->AddChild(move(root)); - return move(filter); + auto filter = make_unique(std::move(condition)); + filter->AddChild(std::move(root)); + return std::move(filter); } unique_ptr Binder::CreatePlan(BoundSelectNode &statement) { @@ -200578,11 +211902,11 @@ unique_ptr Binder::CreatePlan(BoundSelectNode &statement) { // plan the sample clause if (statement.sample_options) { - root = make_unique(move(statement.sample_options), move(root)); + root = make_unique(std::move(statement.sample_options), std::move(root)); } if (statement.where_clause) { - root = PlanFilter(move(statement.where_clause), move(root)); + root = PlanFilter(std::move(statement.where_clause), std::move(root)); } if (!statement.aggregates.empty() || !statement.groups.group_expressions.empty()) { @@ -200597,15 +211921,15 @@ unique_ptr Binder::CreatePlan(BoundSelectNode &statement) { PlanSubqueries(&expr, &root); } // finally create the aggregate node with the group_index and aggregate_index as obtained from the binder - auto aggregate = - make_unique(statement.group_index, statement.aggregate_index, move(statement.aggregates)); - aggregate->groups = move(statement.groups.group_expressions); + auto aggregate = make_unique(statement.group_index, statement.aggregate_index, + std::move(statement.aggregates)); + aggregate->groups = std::move(statement.groups.group_expressions); aggregate->groupings_index = statement.groupings_index; - aggregate->grouping_sets = move(statement.groups.grouping_sets); - aggregate->grouping_functions = move(statement.grouping_functions); + aggregate->grouping_sets = std::move(statement.groups.grouping_sets); + aggregate->grouping_functions = std::move(statement.grouping_functions); - aggregate->AddChild(move(root)); - root = move(aggregate); + aggregate->AddChild(std::move(root)); + root = std::move(aggregate); } else if (!statement.groups.grouping_sets.empty()) { // edge case: we have grouping sets but no groups or aggregates // this can only happen if we have e.g. select 1 from tbl group by (); @@ -200615,42 +211939,42 @@ unique_ptr Binder::CreatePlan(BoundSelectNode &statement) { if (statement.having) { PlanSubqueries(&statement.having, &root); - auto having = make_unique(move(statement.having)); + auto having = make_unique(std::move(statement.having)); - having->AddChild(move(root)); - root = move(having); + having->AddChild(std::move(root)); + root = std::move(having); } if (!statement.windows.empty()) { auto win = make_unique(statement.window_index); - win->expressions = move(statement.windows); + win->expressions = std::move(statement.windows); // visit the window expressions for (auto &expr : win->expressions) { PlanSubqueries(&expr, &root); } D_ASSERT(!win->expressions.empty()); - win->AddChild(move(root)); - root = move(win); + win->AddChild(std::move(root)); + root = std::move(win); } if (statement.qualify) { PlanSubqueries(&statement.qualify, &root); - auto qualify = make_unique(move(statement.qualify)); + auto qualify = make_unique(std::move(statement.qualify)); - qualify->AddChild(move(root)); - root = move(qualify); + qualify->AddChild(std::move(root)); + root = std::move(qualify); } if (!statement.unnests.empty()) { auto unnest = make_unique(statement.unnest_index); - unnest->expressions = move(statement.unnests); + unnest->expressions = std::move(statement.unnests); // visit the unnest expressions for (auto &expr : unnest->expressions) { PlanSubqueries(&expr, &root); } D_ASSERT(!unnest->expressions.empty()); - unnest->AddChild(move(root)); - root = move(unnest); + unnest->AddChild(std::move(root)); + root = std::move(unnest); } for (auto &expr : statement.select_list) { @@ -200658,13 +211982,13 @@ unique_ptr Binder::CreatePlan(BoundSelectNode &statement) { } // create the projection - auto proj = make_unique(statement.projection_index, move(statement.select_list)); + auto proj = make_unique(statement.projection_index, std::move(statement.select_list)); auto &projection = *proj; - proj->AddChild(move(root)); - root = move(proj); + proj->AddChild(std::move(root)); + root = std::move(proj); // finish the plan by handling the elements of the QueryNode - root = VisitQueryNode(statement, move(root)); + root = VisitQueryNode(statement, std::move(root)); // add a prune node if necessary if (statement.need_prune) { @@ -200674,9 +211998,9 @@ unique_ptr Binder::CreatePlan(BoundSelectNode &statement) { prune_expressions.push_back(make_unique( projection.expressions[i]->return_type, ColumnBinding(statement.projection_index, i))); } - auto prune = make_unique(statement.prune_index, move(prune_expressions)); - prune->AddChild(move(root)); - root = move(prune); + auto prune = make_unique(statement.prune_index, std::move(prune_expressions)); + prune->AddChild(std::move(root)); + root = std::move(prune); } return root; } @@ -200691,6 +212015,7 @@ unique_ptr Binder::CreatePlan(BoundSelectNode &statement) { namespace duckdb { +// Optionally push a PROJECTION operator unique_ptr Binder::CastLogicalOperatorToTypes(vector &source_types, vector &target_types, unique_ptr op) { @@ -200712,7 +212037,7 @@ unique_ptr Binder::CastLogicalOperatorToTypes(vectorexpressions[i]->alias; node->expressions[i] = - BoundCastExpression::AddCastToType(context, move(node->expressions[i]), target_types[i]); + BoundCastExpression::AddCastToType(context, std::move(node->expressions[i]), target_types[i]); node->expressions[i]->alias = alias; } } @@ -200731,13 +212056,13 @@ unique_ptr Binder::CastLogicalOperatorToTypes(vector result = make_unique(source_types[i], setop_columns[i]); if (source_types[i] != target_types[i]) { // add a cast only if the source and target types are not equivalent - result = BoundCastExpression::AddCastToType(context, move(result), target_types[i]); + result = BoundCastExpression::AddCastToType(context, std::move(result), target_types[i]); } - select_list.push_back(move(result)); + select_list.push_back(std::move(result)); } - auto projection = make_unique(GenerateTableIndex(), move(select_list)); - projection->children.push_back(move(op)); - return move(projection); + auto projection = make_unique(GenerateTableIndex(), std::move(select_list)); + projection->children.push_back(std::move(op)); + return std::move(projection); } } @@ -200762,19 +212087,20 @@ unique_ptr Binder::CreatePlan(BoundSetOperationNode &node) { right_types.push_back(node.right_reorder_exprs[i]->return_type); } - auto left_projection = make_unique(GenerateTableIndex(), move(node.left_reorder_exprs)); - left_projection->children.push_back(move(left_node)); - left_node = move(left_projection); + auto left_projection = make_unique(GenerateTableIndex(), std::move(node.left_reorder_exprs)); + left_projection->children.push_back(std::move(left_node)); + left_node = std::move(left_projection); - auto right_projection = make_unique(GenerateTableIndex(), move(node.right_reorder_exprs)); - right_projection->children.push_back(move(right_node)); - right_node = move(right_projection); + auto right_projection = + make_unique(GenerateTableIndex(), std::move(node.right_reorder_exprs)); + right_projection->children.push_back(std::move(right_node)); + right_node = std::move(right_projection); - left_node = CastLogicalOperatorToTypes(left_types, node.types, move(left_node)); - right_node = CastLogicalOperatorToTypes(right_types, node.types, move(right_node)); + left_node = CastLogicalOperatorToTypes(left_types, node.types, std::move(left_node)); + right_node = CastLogicalOperatorToTypes(right_types, node.types, std::move(right_node)); } else { - left_node = CastLogicalOperatorToTypes(node.left->types, node.types, move(left_node)); - right_node = CastLogicalOperatorToTypes(node.right->types, node.types, move(right_node)); + left_node = CastLogicalOperatorToTypes(node.left->types, node.types, std::move(left_node)); + right_node = CastLogicalOperatorToTypes(node.right->types, node.types, std::move(right_node)); } // check if there are any unplanned subqueries left in either child @@ -200797,10 +212123,10 @@ unique_ptr Binder::CreatePlan(BoundSetOperationNode &node) { break; } - auto root = make_unique(node.setop_index, node.types.size(), move(left_node), move(right_node), - logical_type); + auto root = make_unique(node.setop_index, node.types.size(), std::move(left_node), + std::move(right_node), logical_type); - return VisitQueryNode(node, move(root)); + return VisitQueryNode(node, std::move(root)); } } // namespace duckdb @@ -200844,7 +212170,7 @@ struct FlattenDependentJoins { //! Detects which Logical Operators have correlated expressions that they are dependent upon, filling the //! has_correlated_expressions map. - bool DetectCorrelatedExpressions(LogicalOperator *op); + bool DetectCorrelatedExpressions(LogicalOperator *op, bool lateral = false); //! Push the dependent join down a LogicalOperator unique_ptr PushDownDependentJoin(unique_ptr plan); @@ -200881,8 +212207,8 @@ static unique_ptr PlanUncorrelatedSubquery(Binder &binder, BoundSubq // uncorrelated EXISTS // we only care about existence, hence we push a LIMIT 1 operator auto limit = make_unique(1, 0, nullptr, nullptr); - limit->AddChild(move(plan)); - plan = move(limit); + limit->AddChild(std::move(plan)); + plan = std::move(limit); // now we push a COUNT(*) aggregate onto the limit, this will be either 0 or 1 (EXISTS or NOT EXISTS) auto count_star_fun = CountStarFun::GetFunction(); @@ -200892,29 +212218,29 @@ static unique_ptr PlanUncorrelatedSubquery(Binder &binder, BoundSubq function_binder.BindAggregateFunction(count_star_fun, {}, nullptr, AggregateType::NON_DISTINCT); auto idx_type = count_star->return_type; vector> aggregate_list; - aggregate_list.push_back(move(count_star)); + aggregate_list.push_back(std::move(count_star)); auto aggregate_index = binder.GenerateTableIndex(); auto aggregate = - make_unique(binder.GenerateTableIndex(), aggregate_index, move(aggregate_list)); - aggregate->AddChild(move(plan)); - plan = move(aggregate); + make_unique(binder.GenerateTableIndex(), aggregate_index, std::move(aggregate_list)); + aggregate->AddChild(std::move(plan)); + plan = std::move(aggregate); // now we push a projection with a comparison to 1 auto left_child = make_unique(idx_type, ColumnBinding(aggregate_index, 0)); auto right_child = make_unique(Value::Numeric(idx_type, 1)); - auto comparison = - make_unique(ExpressionType::COMPARE_EQUAL, move(left_child), move(right_child)); + auto comparison = make_unique(ExpressionType::COMPARE_EQUAL, std::move(left_child), + std::move(right_child)); vector> projection_list; - projection_list.push_back(move(comparison)); + projection_list.push_back(std::move(comparison)); auto projection_index = binder.GenerateTableIndex(); - auto projection = make_unique(projection_index, move(projection_list)); - projection->AddChild(move(plan)); - plan = move(projection); + auto projection = make_unique(projection_index, std::move(projection_list)); + projection->AddChild(std::move(plan)); + plan = std::move(projection); // we add it to the main query by adding a cross product // FIXME: should use something else besides cross product as we always add only one scalar constant - root = LogicalCrossProduct::Create(move(root), move(plan)); + root = LogicalCrossProduct::Create(std::move(root), std::move(plan)); // we replace the original subquery with a ColumnRefExpression referring to the result of the projection (either // TRUE or FALSE) @@ -200931,30 +212257,30 @@ static unique_ptr PlanUncorrelatedSubquery(Binder &binder, BoundSubq // in the uncorrelated case we are only interested in the first result of the query // hence we simply push a LIMIT 1 to get the first row of the subquery auto limit = make_unique(1, 0, nullptr, nullptr); - limit->AddChild(move(plan)); - plan = move(limit); + limit->AddChild(std::move(plan)); + plan = std::move(limit); // we push an aggregate that returns the FIRST element vector> expressions; auto bound = make_unique(expr.return_type, ColumnBinding(table_idx, 0)); vector> first_children; - first_children.push_back(move(bound)); + first_children.push_back(std::move(bound)); FunctionBinder function_binder(binder.context); auto first_agg = function_binder.BindAggregateFunction( - FirstFun::GetFunction(expr.return_type), move(first_children), nullptr, AggregateType::NON_DISTINCT); + FirstFun::GetFunction(expr.return_type), std::move(first_children), nullptr, AggregateType::NON_DISTINCT); - expressions.push_back(move(first_agg)); + expressions.push_back(std::move(first_agg)); auto aggr_index = binder.GenerateTableIndex(); - auto aggr = make_unique(binder.GenerateTableIndex(), aggr_index, move(expressions)); - aggr->AddChild(move(plan)); - plan = move(aggr); + auto aggr = make_unique(binder.GenerateTableIndex(), aggr_index, std::move(expressions)); + aggr->AddChild(std::move(plan)); + plan = std::move(aggr); // in the uncorrelated case, we add the value to the main query through a cross product // FIXME: should use something else besides cross product as we always add only one scalar constant and cross // product is not optimized for this. D_ASSERT(root); - root = LogicalCrossProduct::Create(move(root), move(plan)); + root = LogicalCrossProduct::Create(std::move(root), std::move(plan)); // we replace the original subquery with a BoundColumnRefExpression referring to the first result of the // aggregation @@ -200972,16 +212298,16 @@ static unique_ptr PlanUncorrelatedSubquery(Binder &binder, BoundSubq idx_t mark_index = binder.GenerateTableIndex(); auto join = make_unique(JoinType::MARK); join->mark_index = mark_index; - join->AddChild(move(root)); - join->AddChild(move(plan)); + join->AddChild(std::move(root)); + join->AddChild(std::move(plan)); // create the JOIN condition JoinCondition cond; - cond.left = move(expr.child); + cond.left = std::move(expr.child); cond.right = BoundCastExpression::AddDefaultCastToType( make_unique(expr.child_type, plan_columns[0]), expr.child_target); cond.comparison = expr.comparison_type; - join->conditions.push_back(move(cond)); - root = move(join); + join->conditions.push_back(std::move(cond)); + root = std::move(join); // we replace the original subquery with a BoundColumnRefExpression referring to the mark column return make_unique(expr.GetName(), expr.return_type, ColumnBinding(mark_index, 0)); @@ -200989,10 +212315,9 @@ static unique_ptr PlanUncorrelatedSubquery(Binder &binder, BoundSubq } } -static unique_ptr CreateDuplicateEliminatedJoin(vector &correlated_columns, - JoinType join_type, - unique_ptr original_plan, - bool perform_delim) { +static unique_ptr +CreateDuplicateEliminatedJoin(const vector &correlated_columns, JoinType join_type, + unique_ptr original_plan, bool perform_delim) { auto delim_join = make_unique(join_type); if (!perform_delim) { // if we are not performing a delim join, we push a row_number() OVER() window operator on the LHS @@ -201004,11 +212329,11 @@ static unique_ptr CreateDuplicateEliminatedJoin(vectorstart = WindowBoundary::UNBOUNDED_PRECEDING; row_number->end = WindowBoundary::CURRENT_ROW_ROWS; row_number->alias = "delim_index"; - window->expressions.push_back(move(row_number)); - window->AddChild(move(original_plan)); - original_plan = move(window); + window->expressions.push_back(std::move(row_number)); + window->AddChild(std::move(original_plan)); + original_plan = std::move(window); } - delim_join->AddChild(move(original_plan)); + delim_join->AddChild(std::move(original_plan)); for (idx_t i = 0; i < correlated_columns.size(); i++) { auto &col = correlated_columns[i]; delim_join->duplicate_eliminated_columns.push_back( @@ -201018,16 +212343,21 @@ static unique_ptr CreateDuplicateEliminatedJoin(vector &correlated_columns, +static void CreateDelimJoinConditions(LogicalDelimJoin &delim_join, + const vector &correlated_columns, vector bindings, idx_t base_offset, bool perform_delim) { auto col_count = perform_delim ? correlated_columns.size() : 1; for (idx_t i = 0; i < col_count; i++) { auto &col = correlated_columns[i]; + auto binding_idx = base_offset + i; + if (binding_idx >= bindings.size()) { + throw InternalException("Delim join - binding index out of range"); + } JoinCondition cond; cond.left = make_unique(col.name, col.type, col.binding); - cond.right = make_unique(col.name, col.type, bindings[base_offset + i]); + cond.right = make_unique(col.name, col.type, bindings[binding_idx]); cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM; - delim_join.conditions.push_back(move(cond)); + delim_join.conditions.push_back(std::move(cond)); } } @@ -201064,7 +212394,7 @@ static bool PerformDuplicateElimination(Binder &binder, vector PlanCorrelatedSubquery(Binder &binder, BoundSubque // the left side is the original plan // this is the side that will be duplicate eliminated and pushed into the RHS auto delim_join = - CreateDuplicateEliminatedJoin(correlated_columns, JoinType::SINGLE, move(root), perform_delim); + CreateDuplicateEliminatedJoin(correlated_columns, JoinType::SINGLE, std::move(root), perform_delim); // the right side initially is a DEPENDENT join between the duplicate eliminated scan and the subquery // HOWEVER: we do not explicitly create the dependent join @@ -201104,7 +212434,7 @@ static unique_ptr PlanCorrelatedSubquery(Binder &binder, BoundSubque // first we check which logical operators have correlated expressions in the first place flatten.DetectCorrelatedExpressions(plan.get()); // now we push the dependent join down - auto dependent_join = flatten.PushDownDependentJoin(move(plan)); + auto dependent_join = flatten.PushDownDependentJoin(std::move(plan)); // now the dependent join is fully eliminated // we only need to create the join conditions between the LHS and the RHS @@ -201113,8 +212443,8 @@ static unique_ptr PlanCorrelatedSubquery(Binder &binder, BoundSubque // now create the join conditions CreateDelimJoinConditions(*delim_join, correlated_columns, plan_columns, flatten.delim_offset, perform_delim); - delim_join->AddChild(move(dependent_join)); - root = move(delim_join); + delim_join->AddChild(std::move(dependent_join)); + root = std::move(delim_join); // finally push the BoundColumnRefExpression referring to the data element returned by the join return make_unique(expr.GetName(), expr.return_type, plan_columns[flatten.data_offset]); @@ -201123,20 +212453,21 @@ static unique_ptr PlanCorrelatedSubquery(Binder &binder, BoundSubque // correlated EXISTS query // this query is similar to the correlated SCALAR query, except we use a MARK join here idx_t mark_index = binder.GenerateTableIndex(); - auto delim_join = CreateDuplicateEliminatedJoin(correlated_columns, JoinType::MARK, move(root), perform_delim); + auto delim_join = + CreateDuplicateEliminatedJoin(correlated_columns, JoinType::MARK, std::move(root), perform_delim); delim_join->mark_index = mark_index; // RHS FlattenDependentJoins flatten(binder, correlated_columns, perform_delim, true); flatten.DetectCorrelatedExpressions(plan.get()); - auto dependent_join = flatten.PushDownDependentJoin(move(plan)); + auto dependent_join = flatten.PushDownDependentJoin(std::move(plan)); // fetch the set of columns auto plan_columns = dependent_join->GetColumnBindings(); // now we create the join conditions between the dependent join and the original table CreateDelimJoinConditions(*delim_join, correlated_columns, plan_columns, flatten.delim_offset, perform_delim); - delim_join->AddChild(move(dependent_join)); - root = move(delim_join); + delim_join->AddChild(std::move(dependent_join)); + root = std::move(delim_join); // finally push the BoundColumnRefExpression referring to the marker return make_unique(expr.GetName(), expr.return_type, ColumnBinding(mark_index, 0)); } @@ -201150,12 +212481,13 @@ static unique_ptr PlanCorrelatedSubquery(Binder &binder, BoundSubque // as the MARK join has one extra join condition (the original condition, of the ANY expression, e.g. // [i=ANY(...)]) idx_t mark_index = binder.GenerateTableIndex(); - auto delim_join = CreateDuplicateEliminatedJoin(correlated_columns, JoinType::MARK, move(root), perform_delim); + auto delim_join = + CreateDuplicateEliminatedJoin(correlated_columns, JoinType::MARK, std::move(root), perform_delim); delim_join->mark_index = mark_index; // RHS FlattenDependentJoins flatten(binder, correlated_columns, true, true); flatten.DetectCorrelatedExpressions(plan.get()); - auto dependent_join = flatten.PushDownDependentJoin(move(plan)); + auto dependent_join = flatten.PushDownDependentJoin(std::move(plan)); // fetch the columns auto plan_columns = dependent_join->GetColumnBindings(); @@ -201164,14 +212496,14 @@ static unique_ptr PlanCorrelatedSubquery(Binder &binder, BoundSubque CreateDelimJoinConditions(*delim_join, correlated_columns, plan_columns, flatten.delim_offset, perform_delim); // add the actual condition based on the ANY/ALL predicate JoinCondition compare_cond; - compare_cond.left = move(expr.child); + compare_cond.left = std::move(expr.child); compare_cond.right = BoundCastExpression::AddDefaultCastToType( make_unique(expr.child_type, plan_columns[0]), expr.child_target); compare_cond.comparison = expr.comparison_type; - delim_join->conditions.push_back(move(compare_cond)); + delim_join->conditions.push_back(std::move(compare_cond)); - delim_join->AddChild(move(dependent_join)); - root = move(delim_join); + delim_join->AddChild(std::move(dependent_join)); + root = std::move(delim_join); // finally push the BoundColumnRefExpression referring to the marker return make_unique(expr.GetName(), expr.return_type, ColumnBinding(mark_index, 0)); } @@ -201184,10 +212516,10 @@ class RecursiveSubqueryPlanner : public LogicalOperatorVisitor { } void VisitOperator(LogicalOperator &op) override { if (!op.children.empty()) { - root = move(op.children[0]); + root = std::move(op.children[0]); D_ASSERT(root); VisitOperatorExpressions(op); - op.children[0] = move(root); + op.children[0] = std::move(root); for (idx_t i = 0; i < op.children.size(); i++) { D_ASSERT(op.children[i]); VisitOperator(*op.children[i]); @@ -201214,12 +212546,12 @@ unique_ptr Binder::PlanSubquery(BoundSubqueryExpression &expr, uniqu D_ASSERT(subquery_root); // now we actually flatten the subquery - auto plan = move(subquery_root); + auto plan = std::move(subquery_root); unique_ptr result_expression; if (!expr.IsCorrelated()) { - result_expression = PlanUncorrelatedSubquery(*this, expr, root, move(plan)); + result_expression = PlanUncorrelatedSubquery(*this, expr, root, std::move(plan)); } else { - result_expression = PlanCorrelatedSubquery(*this, expr, root, move(plan)); + result_expression = PlanCorrelatedSubquery(*this, expr, root, std::move(plan)); } // finally, we recursively plan the nested subqueries (if there are any) if (sub_binder->has_unplanned_subqueries) { @@ -201253,6 +212585,57 @@ void Binder::PlanSubqueries(unique_ptr *expr_ptr, unique_ptr Binder::PlanLateralJoin(unique_ptr left, unique_ptr right, + vector &correlated_columns, + JoinType join_type, unique_ptr condition) { + // scan the right operator for correlated columns + // correlated LATERAL JOIN + vector conditions; + vector> arbitrary_expressions; + if (condition) { + // extract join conditions, if there are any + LogicalComparisonJoin::ExtractJoinConditions(join_type, left, right, std::move(condition), conditions, + arbitrary_expressions); + } + + auto perform_delim = PerformDuplicateElimination(*this, correlated_columns); + auto delim_join = CreateDuplicateEliminatedJoin(correlated_columns, join_type, std::move(left), perform_delim); + + FlattenDependentJoins flatten(*this, correlated_columns, perform_delim); + + // first we check which logical operators have correlated expressions in the first place + flatten.DetectCorrelatedExpressions(right.get(), true); + // now we push the dependent join down + auto dependent_join = flatten.PushDownDependentJoin(std::move(right)); + + // now the dependent join is fully eliminated + // we only need to create the join conditions between the LHS and the RHS + // fetch the set of columns + auto plan_columns = dependent_join->GetColumnBindings(); + + // now create the join conditions + // start off with the conditions that were passed in (if any) + D_ASSERT(delim_join->conditions.empty()); + delim_join->conditions = std::move(conditions); + // then add the delim join conditions + CreateDelimJoinConditions(*delim_join, correlated_columns, plan_columns, flatten.delim_offset, perform_delim); + delim_join->AddChild(std::move(dependent_join)); + + // check if there are any arbitrary expressions left + if (!arbitrary_expressions.empty()) { + // we can only evaluate scalar arbitrary expressions for inner joins + if (join_type != JoinType::INNER) { + throw BinderException( + "Join condition for non-inner LATERAL JOIN must be a comparison between the left and right side"); + } + auto filter = make_unique(); + filter->expressions = std::move(arbitrary_expressions); + filter->AddChild(std::move(delim_join)); + return std::move(filter); + } + return std::move(delim_join); +} + } // namespace duckdb @@ -201276,7 +212659,7 @@ namespace duckdb { class BoundTableFunction : public BoundTableRef { public: explicit BoundTableFunction(unique_ptr get) - : BoundTableRef(TableReferenceType::TABLE_FUNCTION), get(move(get)) { + : BoundTableRef(TableReferenceType::TABLE_FUNCTION), get(std::move(get)) { } unique_ptr get; @@ -201286,13 +212669,33 @@ class BoundTableFunction : public BoundTableRef { +namespace duckdb { + +BoundStatement Binder::Bind(AttachStatement &stmt) { + BoundStatement result; + result.types = {LogicalType::BOOLEAN}; + result.names = {"Success"}; + + result.plan = make_unique(LogicalOperatorType::LOGICAL_ATTACH, std::move(stmt.info)); + properties.allow_stream_result = false; + properties.return_type = StatementReturnType::NOTHING; + return result; +} + +} // namespace duckdb + + + + + + namespace duckdb { BoundStatement Binder::Bind(CallStatement &stmt) { BoundStatement result; TableFunctionRef ref; - ref.function = move(stmt.function); + ref.function = std::move(stmt.function); auto bound_func = Bind(ref); auto &bound_table_func = (BoundTableFunction &)*bound_func; @@ -201327,11 +212730,52 @@ BoundStatement Binder::Bind(CallStatement &stmt) { + + + #include namespace duckdb { +static vector ColumnListToIndices(const vector &vec) { + vector ret; + for (idx_t i = 0; i < vec.size(); i++) { + if (vec[i]) { + ret.push_back(i); + } + } + return ret; +} + +vector GetUniqueNames(const vector &original_names) { + unordered_set name_set; + vector unique_names; + unique_names.reserve(original_names.size()); + + for (auto &name : original_names) { + auto insert_result = name_set.insert(name); + if (insert_result.second == false) { + // Could not be inserted, name already exists + idx_t index = 1; + string postfixed_name; + while (true) { + postfixed_name = StringUtil::Format("%s:%d", name, index); + auto res = name_set.insert(postfixed_name); + if (!res.second) { + index++; + continue; + } + break; + } + unique_names.push_back(postfixed_name); + } else { + unique_names.push_back(name); + } + } + return unique_names; +} + BoundStatement Binder::BindCopyTo(CopyStatement &stmt) { // COPY TO a file auto &config = DBConfig::GetConfig(context); @@ -201342,35 +212786,87 @@ BoundStatement Binder::BindCopyTo(CopyStatement &stmt) { result.types = {LogicalType::BIGINT}; result.names = {"Count"}; + // lookup the format in the catalog + auto copy_function = + Catalog::GetEntry(context, INVALID_CATALOG, DEFAULT_SCHEMA, stmt.info->format); + if (copy_function->function.plan) { + // plan rewrite COPY TO + return copy_function->function.plan(*this, stmt); + } + // bind the select statement auto select_node = Bind(*stmt.select_statement); - // lookup the format in the catalog - auto &catalog = Catalog::GetCatalog(context); - auto copy_function = catalog.GetEntry(context, DEFAULT_SCHEMA, stmt.info->format); if (!copy_function->function.copy_to_bind) { throw NotImplementedException("COPY TO is not supported for FORMAT \"%s\"", stmt.info->format); } bool use_tmp_file = true; - for (auto &option : stmt.info->options) { + bool allow_overwrite = false; + bool user_set_use_tmp_file = false; + bool per_thread_output = false; + vector partition_cols; + + auto original_options = stmt.info->options; + stmt.info->options.clear(); + + for (auto &option : original_options) { auto loption = StringUtil::Lower(option.first); if (loption == "use_tmp_file") { use_tmp_file = option.second[0].CastAs(context, LogicalType::BOOLEAN).GetValue(); - stmt.info->options.erase(option.first); - break; + user_set_use_tmp_file = true; + continue; + } + if (loption == "allow_overwrite") { + allow_overwrite = option.second[0].CastAs(context, LogicalType::BOOLEAN).GetValue(); + continue; + } + + if (loption == "per_thread_output") { + per_thread_output = option.second[0].CastAs(context, LogicalType::BOOLEAN).GetValue(); + continue; } + if (loption == "partition_by") { + auto converted = ConvertVectorToValue(std::move(option.second)); + partition_cols = ColumnListToIndices(ParseColumnList(converted, select_node.names, loption)); + continue; + } + stmt.info->options[option.first] = option.second; + } + if (user_set_use_tmp_file && per_thread_output) { + throw NotImplementedException("Can't combine USE_TMP_FILE and PER_THREAD_OUTPUT for COPY"); + } + if (user_set_use_tmp_file && !partition_cols.empty()) { + throw NotImplementedException("Can't combine USE_TMP_FILE and PARTITION_BY for COPY"); + } + if (per_thread_output && !partition_cols.empty()) { + throw NotImplementedException("Can't combine PER_THREAD_OUTPUT and PARTITION_BY for COPY"); + } + bool is_file_and_exists = config.file_system->FileExists(stmt.info->file_path); + bool is_stdout = stmt.info->file_path == "/dev/stdout"; + if (!user_set_use_tmp_file) { + use_tmp_file = is_file_and_exists && !per_thread_output && partition_cols.empty() && !is_stdout; } + + auto unique_column_names = GetUniqueNames(select_node.names); + auto function_data = - copy_function->function.copy_to_bind(context, *stmt.info, select_node.names, select_node.types); + copy_function->function.copy_to_bind(context, *stmt.info, unique_column_names, select_node.types); // now create the copy information - auto copy = make_unique(copy_function->function, move(function_data)); + auto copy = make_unique(copy_function->function, std::move(function_data)); copy->file_path = stmt.info->file_path; copy->use_tmp_file = use_tmp_file; - copy->is_file_and_exists = config.file_system->FileExists(copy->file_path); + copy->allow_overwrite = allow_overwrite; + copy->per_thread_output = per_thread_output; + copy->per_thread_output = per_thread_output; + copy->partition_output = !partition_cols.empty(); + copy->partition_columns = std::move(partition_cols); - copy->AddChild(move(select_node.plan)); + copy->names = unique_column_names; + copy->expected_types = select_node.types; - result.plan = move(copy); + copy->AddChild(std::move(select_node.plan)); + + result.plan = std::move(copy); return result; } @@ -201390,6 +212886,7 @@ BoundStatement Binder::BindCopyFrom(CopyStatement &stmt) { InsertStatement insert; insert.table = stmt.info->table; insert.schema = stmt.info->schema; + insert.catalog = stmt.info->catalog; insert.columns = stmt.info->select_list; // bind the insert statement to the base table @@ -201399,17 +212896,18 @@ BoundStatement Binder::BindCopyFrom(CopyStatement &stmt) { auto &bound_insert = (LogicalInsert &)*insert_statement.plan; // lookup the format in the catalog - auto &catalog = Catalog::GetCatalog(context); + auto &catalog = Catalog::GetSystemCatalog(context); auto copy_function = catalog.GetEntry(context, DEFAULT_SCHEMA, stmt.info->format); if (!copy_function->function.copy_from_bind) { throw NotImplementedException("COPY FROM is not supported for FORMAT \"%s\"", stmt.info->format); } // lookup the table to copy into - auto table = Catalog::GetCatalog(context).GetEntry(context, stmt.info->schema, stmt.info->table); + BindSchemaOrCatalog(stmt.info->catalog, stmt.info->schema); + auto table = Catalog::GetEntry(context, stmt.info->catalog, stmt.info->schema, stmt.info->table); vector expected_names; if (!bound_insert.column_index_map.empty()) { expected_names.resize(bound_insert.expected_types.size()); - for (auto &col : table->columns.Logical()) { + for (auto &col : table->GetColumns().Logical()) { auto i = col.Physical(); if (bound_insert.column_index_map[i] != DConstants::INVALID_INDEX) { expected_names[bound_insert.column_index_map[i]] = col.Name(); @@ -201417,7 +212915,7 @@ BoundStatement Binder::BindCopyFrom(CopyStatement &stmt) { } } else { expected_names.reserve(bound_insert.expected_types.size()); - for (auto &col : table->columns.Logical()) { + for (auto &col : table->GetColumns().Logical()) { expected_names.push_back(col.Name()); } } @@ -201425,12 +212923,12 @@ BoundStatement Binder::BindCopyFrom(CopyStatement &stmt) { auto function_data = copy_function->function.copy_from_bind(context, *stmt.info, expected_names, bound_insert.expected_types); auto get = make_unique(GenerateTableIndex(), copy_function->function.copy_from_function, - move(function_data), bound_insert.expected_types, expected_names); + std::move(function_data), bound_insert.expected_types, expected_names); for (idx_t i = 0; i < bound_insert.expected_types.size(); i++) { get->column_ids.push_back(i); } - insert_statement.plan->children.push_back(move(get)); - result.plan = move(insert_statement.plan); + insert_statement.plan->children.push_back(std::move(get)); + result.plan = std::move(insert_statement.plan); return result; } @@ -201439,11 +212937,12 @@ BoundStatement Binder::Bind(CopyStatement &stmt) { // copy table into file without a query // generate SELECT * FROM table; auto ref = make_unique(); + ref->catalog_name = stmt.info->catalog; ref->schema_name = stmt.info->schema; ref->table_name = stmt.info->table; auto statement = make_unique(); - statement->from_table = move(ref); + statement->from_table = std::move(ref); if (!stmt.info->select_list.empty()) { for (auto &name : stmt.info->select_list) { statement->select_list.push_back(make_unique(name)); @@ -201451,7 +212950,7 @@ BoundStatement Binder::Bind(CopyStatement &stmt) { } else { statement->select_list.push_back(make_unique()); } - stmt.select_statement = move(statement); + stmt.select_statement = std::move(statement); } properties.allow_stream_result = false; properties.return_type = StatementReturnType::CHANGED_ROWS; @@ -201478,6 +212977,11 @@ BoundStatement Binder::Bind(CopyStatement &stmt) { + + + + + //===----------------------------------------------------------------------===// // DuckDB @@ -201531,7 +213035,7 @@ namespace duckdb { class CatalogEntry; struct BoundCreateFunctionInfo { - explicit BoundCreateFunctionInfo(unique_ptr base) : base(move(base)) { + explicit BoundCreateFunctionInfo(unique_ptr base) : base(std::move(base)) { } //! The schema to create the table in @@ -201556,31 +213060,83 @@ struct BoundCreateFunctionInfo { + + + namespace duckdb { -SchemaCatalogEntry *Binder::BindSchema(CreateInfo &info) { - if (info.schema.empty()) { - info.schema = info.temporary ? TEMP_SCHEMA : ClientData::Get(context).catalog_search_path->GetDefault(); +void Binder::BindSchemaOrCatalog(ClientContext &context, string &catalog, string &schema) { + if (catalog.empty() && !schema.empty()) { + // schema is specified - but catalog is not + // try searching for the catalog instead + auto &db_manager = DatabaseManager::Get(context); + auto database = db_manager.GetDatabase(context, schema); + if (database) { + // we have a database with this name + // check if there is a schema + auto schema_obj = Catalog::GetSchema(context, INVALID_CATALOG, schema, true); + if (schema_obj) { + auto &attached = schema_obj->catalog->GetAttached(); + throw BinderException( + "Ambiguous reference to catalog or schema \"%s\" - use a fully qualified path like \"%s.%s\"", + schema, attached.GetName(), schema); + } + catalog = schema; + schema = string(); + } } +} +void Binder::BindSchemaOrCatalog(string &catalog, string &schema) { + BindSchemaOrCatalog(context, catalog, schema); +} + +SchemaCatalogEntry *Binder::BindSchema(CreateInfo &info) { + BindSchemaOrCatalog(info.catalog, info.schema); + if (IsInvalidCatalog(info.catalog) && info.temporary) { + info.catalog = TEMP_CATALOG; + } + auto &search_path = ClientData::Get(context).catalog_search_path; + if (IsInvalidCatalog(info.catalog) && IsInvalidSchema(info.schema)) { + auto &default_entry = search_path->GetDefault(); + info.catalog = default_entry.catalog; + info.schema = default_entry.schema; + } else if (IsInvalidSchema(info.schema)) { + info.schema = search_path->GetDefaultSchema(info.catalog); + } else if (IsInvalidCatalog(info.catalog)) { + info.catalog = search_path->GetDefaultCatalog(info.schema); + } + if (IsInvalidCatalog(info.catalog)) { + info.catalog = DatabaseManager::GetDefaultDatabase(context); + } if (!info.temporary) { // non-temporary create: not read only - if (info.schema == TEMP_SCHEMA) { - throw ParserException("Only TEMPORARY table names can use the \"temp\" schema"); + if (info.catalog == TEMP_CATALOG) { + throw ParserException("Only TEMPORARY table names can use the \"%s\" catalog", TEMP_CATALOG); } - properties.read_only = false; } else { - if (info.schema != TEMP_SCHEMA) { - throw ParserException("TEMPORARY table names can *only* use the \"%s\" schema", TEMP_SCHEMA); + if (info.catalog != TEMP_CATALOG) { + throw ParserException("TEMPORARY table names can *only* use the \"%s\" catalog", TEMP_CATALOG); } } // fetch the schema in which we want to create the object - auto schema_obj = Catalog::GetCatalog(context).GetSchema(context, info.schema); + auto schema_obj = Catalog::GetSchema(context, info.catalog, info.schema); D_ASSERT(schema_obj->type == CatalogType::SCHEMA_ENTRY); info.schema = schema_obj->name; + if (!info.temporary) { + properties.modified_databases.insert(schema_obj->catalog->GetName()); + } return schema_obj; } +SchemaCatalogEntry *Binder::BindCreateSchema(CreateInfo &info) { + auto schema = BindSchema(info); + if (schema->catalog->IsSystemCatalog()) { + throw BinderException("Cannot create entry in system catalog"); + } + return schema; +} + void Binder::BindCreateViewInfo(CreateViewInfo &base) { // bind the view as if it were a query so we can catch errors // note that we bind the original, and replace the original with a copy @@ -201589,17 +213145,45 @@ void Binder::BindCreateViewInfo(CreateViewInfo &base) { auto copy = base.query->Copy(); auto query_node = view_binder->Bind(*base.query); - base.query = unique_ptr_cast(move(copy)); + base.query = unique_ptr_cast(std::move(copy)); if (base.aliases.size() > query_node.names.size()) { throw BinderException("More VIEW aliases than columns in query result"); } // fill up the aliases with the remaining names of the bound query + base.aliases.reserve(query_node.names.size()); for (idx_t i = base.aliases.size(); i < query_node.names.size(); i++) { base.aliases.push_back(query_node.names[i]); } base.types = query_node.types; } +static void QualifyFunctionNames(ClientContext &context, unique_ptr &expr) { + switch (expr->GetExpressionClass()) { + case ExpressionClass::FUNCTION: { + auto &func = (FunctionExpression &)*expr; + auto function = (StandardEntry *)Catalog::GetEntry(context, CatalogType::SCALAR_FUNCTION_ENTRY, func.catalog, + func.schema, func.function_name, true); + if (function) { + func.catalog = function->catalog->GetName(); + func.schema = function->schema->name; + } + break; + } + case ExpressionClass::SUBQUERY: { + // replacing parameters within a subquery is slightly different + auto &sq = ((SubqueryExpression &)*expr).subquery; + ParsedExpressionIterator::EnumerateQueryNodeChildren( + *sq->node, [&](unique_ptr &child) { QualifyFunctionNames(context, child); }); + break; + } + default: // fall through + break; + } + // unfold child expressions + ParsedExpressionIterator::EnumerateChildren( + *expr, [&](unique_ptr &child) { QualifyFunctionNames(context, child); }); +} + SchemaCatalogEntry *Binder::BindCreateFunctionInfo(CreateInfo &info) { auto &base = (CreateMacroInfo &)info; auto &scalar_function = (ScalarMacroFunction &)*base.function; @@ -201629,6 +213213,7 @@ SchemaCatalogEntry *Binder::BindCreateFunctionInfo(CreateInfo &info) { auto this_macro_binding = make_unique(dummy_types, dummy_names, base.name); macro_binding = this_macro_binding.get(); ExpressionBinder::QualifyColumnNames(*this, scalar_function.expression); + QualifyFunctionNames(context, scalar_function.expression); // create a copy of the expression because we do not want to alter the original auto expression = scalar_function.expression->Copy(); @@ -201644,45 +213229,66 @@ SchemaCatalogEntry *Binder::BindCreateFunctionInfo(CreateInfo &info) { throw BinderException(error); } - return BindSchema(info); + return BindCreateSchema(info); } -void Binder::BindLogicalType(ClientContext &context, LogicalType &type, const string &schema) { - if (type.id() == LogicalTypeId::LIST) { +void Binder::BindLogicalType(ClientContext &context, LogicalType &type, Catalog *catalog, const string &schema) { + if (type.id() == LogicalTypeId::LIST || type.id() == LogicalTypeId::MAP) { auto child_type = ListType::GetChildType(type); - BindLogicalType(context, child_type, schema); + BindLogicalType(context, child_type, catalog, schema); auto alias = type.GetAlias(); - type = LogicalType::LIST(child_type); + if (type.id() == LogicalTypeId::LIST) { + type = LogicalType::LIST(child_type); + } else { + D_ASSERT(child_type.id() == LogicalTypeId::STRUCT); // map must be list of structs + type = LogicalType::MAP(child_type); + } + type.SetAlias(alias); - } else if (type.id() == LogicalTypeId::STRUCT || type.id() == LogicalTypeId::MAP) { + } else if (type.id() == LogicalTypeId::STRUCT) { auto child_types = StructType::GetChildTypes(type); for (auto &child_type : child_types) { - BindLogicalType(context, child_type.second, schema); + BindLogicalType(context, child_type.second, catalog, schema); } - // Generate new Struct/Map Type + // Generate new Struct Type auto alias = type.GetAlias(); - if (type.id() == LogicalTypeId::STRUCT) { - type = LogicalType::STRUCT(child_types); - } else { - type = LogicalType::MAP(child_types); - } + type = LogicalType::STRUCT(child_types); type.SetAlias(alias); } else if (type.id() == LogicalTypeId::UNION) { auto member_types = UnionType::CopyMemberTypes(type); for (auto &member_type : member_types) { - BindLogicalType(context, member_type.second, schema); + BindLogicalType(context, member_type.second, catalog, schema); } // Generate new Union Type auto alias = type.GetAlias(); type = LogicalType::UNION(member_types); type.SetAlias(alias); } else if (type.id() == LogicalTypeId::USER) { - auto &catalog = Catalog::GetCatalog(context); - type = catalog.GetType(context, schema, UserType::GetTypeName(type)); + auto &user_type_name = UserType::GetTypeName(type); + if (catalog) { + type = catalog->GetType(context, schema, user_type_name, true); + if (type.id() == LogicalTypeId::INVALID) { + // look in the system catalog if the type was not found + type = Catalog::GetType(context, SYSTEM_CATALOG, schema, user_type_name); + } + } else { + type = Catalog::GetType(context, INVALID_CATALOG, schema, user_type_name); + } } else if (type.id() == LogicalTypeId::ENUM) { auto &enum_type_name = EnumType::GetTypeName(type); - auto enum_type_catalog = (TypeCatalogEntry *)context.db->GetCatalog().GetEntry(context, CatalogType::TYPE_ENTRY, - schema, enum_type_name, true); + TypeCatalogEntry *enum_type_catalog; + if (catalog) { + enum_type_catalog = catalog->GetEntry(context, schema, enum_type_name, true); + if (!enum_type_catalog) { + // look in the system catalog if the type was not found + enum_type_catalog = + Catalog::GetEntry(context, SYSTEM_CATALOG, schema, enum_type_name, true); + } + } else { + enum_type_catalog = + Catalog::GetEntry(context, INVALID_CATALOG, schema, enum_type_name, true); + } + LogicalType::SetCatalog(type, enum_type_catalog); } } @@ -201853,6 +213459,35 @@ static bool AnyConstraintReferencesGeneratedColumn(CreateTableInfo &table_info) return false; } +unique_ptr DuckCatalog::BindCreateIndex(Binder &binder, CreateStatement &stmt, + TableCatalogEntry &table, unique_ptr plan) { + D_ASSERT(plan->type == LogicalOperatorType::LOGICAL_GET); + auto &base = (CreateIndexInfo &)*stmt.info; + + auto &get = (LogicalGet &)*plan; + // bind the index expressions + vector> expressions; + IndexBinder index_binder(binder, binder.context); + for (auto &expr : base.expressions) { + expressions.push_back(index_binder.Bind(expr)); + } + + auto create_index_info = unique_ptr_cast(std::move(stmt.info)); + for (auto &column_id : get.column_ids) { + if (column_id == COLUMN_IDENTIFIER_ROW_ID) { + throw BinderException("Cannot create an index on the rowid!"); + } + create_index_info->scan_types.push_back(get.returned_types[column_id]); + } + create_index_info->scan_types.emplace_back(LogicalType::ROW_TYPE); + create_index_info->names = get.names; + create_index_info->column_ids = get.column_ids; + + // the logical CREATE INDEX also needs all fields to scan the referenced table + return make_unique(std::move(get.bind_data), std::move(create_index_info), + std::move(expressions), table, std::move(get.function)); +} + BoundStatement Binder::Bind(CreateStatement &stmt) { BoundStatement result; result.names = {"Count"}; @@ -201862,29 +213497,33 @@ BoundStatement Binder::Bind(CreateStatement &stmt) { auto catalog_type = stmt.info->type; switch (catalog_type) { case CatalogType::SCHEMA_ENTRY: - result.plan = make_unique(LogicalOperatorType::LOGICAL_CREATE_SCHEMA, move(stmt.info)); + result.plan = make_unique(LogicalOperatorType::LOGICAL_CREATE_SCHEMA, std::move(stmt.info)); break; case CatalogType::VIEW_ENTRY: { auto &base = (CreateViewInfo &)*stmt.info; // bind the schema - auto schema = BindSchema(*stmt.info); + auto schema = BindCreateSchema(*stmt.info); BindCreateViewInfo(base); - result.plan = make_unique(LogicalOperatorType::LOGICAL_CREATE_VIEW, move(stmt.info), schema); + result.plan = + make_unique(LogicalOperatorType::LOGICAL_CREATE_VIEW, std::move(stmt.info), schema); break; } case CatalogType::SEQUENCE_ENTRY: { - auto schema = BindSchema(*stmt.info); - result.plan = make_unique(LogicalOperatorType::LOGICAL_CREATE_SEQUENCE, move(stmt.info), schema); + auto schema = BindCreateSchema(*stmt.info); + result.plan = + make_unique(LogicalOperatorType::LOGICAL_CREATE_SEQUENCE, std::move(stmt.info), schema); break; } case CatalogType::TABLE_MACRO_ENTRY: { - auto schema = BindSchema(*stmt.info); - result.plan = make_unique(LogicalOperatorType::LOGICAL_CREATE_MACRO, move(stmt.info), schema); + auto schema = BindCreateSchema(*stmt.info); + result.plan = + make_unique(LogicalOperatorType::LOGICAL_CREATE_MACRO, std::move(stmt.info), schema); break; } case CatalogType::MACRO_ENTRY: { auto schema = BindCreateFunctionInfo(*stmt.info); - result.plan = make_unique(LogicalOperatorType::LOGICAL_CREATE_MACRO, move(stmt.info), schema); + result.plan = + make_unique(LogicalOperatorType::LOGICAL_CREATE_MACRO, std::move(stmt.info), schema); break; } case CatalogType::INDEX_ENTRY: { @@ -201893,46 +213532,24 @@ BoundStatement Binder::Bind(CreateStatement &stmt) { // visit the table reference auto bound_table = Bind(*base.table); if (bound_table->type != TableReferenceType::BASE_TABLE) { - throw BinderException("Can only delete from base table!"); + throw BinderException("Can only create an index over a base table!"); } auto &table_binding = (BoundBaseTableRef &)*bound_table; auto table = table_binding.table; - - // bind the index expressions - vector> expressions; - IndexBinder binder(*this, context); - for (auto &expr : base.expressions) { - expressions.push_back(binder.Bind(expr)); + if (table->temporary) { + stmt.info->temporary = true; } - + // create a plan over the bound table auto plan = CreatePlan(*bound_table); if (plan->type != LogicalOperatorType::LOGICAL_GET) { throw BinderException("Cannot create index on a view!"); } - auto &get = (LogicalGet &)*plan; - for (auto &column_id : get.column_ids) { - if (column_id == COLUMN_IDENTIFIER_ROW_ID) { - throw BinderException("Cannot create an index on the rowid!"); - } - } - - auto create_index_info = unique_ptr_cast(move(stmt.info)); - for (auto &index : get.column_ids) { - create_index_info->scan_types.push_back(get.returned_types[index]); - } - create_index_info->scan_types.emplace_back(LogicalType::ROW_TYPE); - create_index_info->names = get.names; - create_index_info->column_ids = get.column_ids; - - // the logical CREATE INDEX also needs all fields to scan the referenced table - result.plan = make_unique(move(get.bind_data), move(create_index_info), move(expressions), - *table, move(get.function)); + result.plan = table->catalog->BindCreateIndex(*this, stmt, *table, std::move(plan)); break; } case CatalogType::TABLE_ENTRY: { auto &create_info = (CreateTableInfo &)*stmt.info; - auto &catalog = Catalog::GetCatalog(context); // If there is a foreign key constraint, resolve primary key column's index from primary key column's name unordered_set fk_schemas; for (idx_t i = 0; i < create_info.constraints.size(); i++) { @@ -201955,13 +213572,16 @@ BoundStatement Binder::Bind(CreateStatement &stmt) { CheckForeignKeyTypes(create_info.columns, create_info.columns, fk); } else { // have to resolve referenced table - auto pk_table_entry_ptr = catalog.GetEntry(context, fk.info.schema, fk.info.table); + auto pk_table_entry_ptr = + Catalog::GetEntry(context, INVALID_CATALOG, fk.info.schema, fk.info.table); fk_schemas.insert(pk_table_entry_ptr->schema); - FindMatchingPrimaryKeyColumns(pk_table_entry_ptr->columns, pk_table_entry_ptr->constraints, fk); - FindForeignKeyIndexes(pk_table_entry_ptr->columns, fk.pk_columns, fk.info.pk_keys); - CheckForeignKeyTypes(pk_table_entry_ptr->columns, create_info.columns, fk); - auto index = pk_table_entry_ptr->storage->info->indexes.FindForeignKeyIndex( - fk.info.pk_keys, ForeignKeyType::FK_TYPE_PRIMARY_KEY_TABLE); + FindMatchingPrimaryKeyColumns(pk_table_entry_ptr->GetColumns(), pk_table_entry_ptr->GetConstraints(), + fk); + FindForeignKeyIndexes(pk_table_entry_ptr->GetColumns(), fk.pk_columns, fk.info.pk_keys); + CheckForeignKeyTypes(pk_table_entry_ptr->GetColumns(), create_info.columns, fk); + auto &storage = pk_table_entry_ptr->GetStorage(); + auto index = storage.info->indexes.FindForeignKeyIndex(fk.info.pk_keys, + ForeignKeyType::FK_TYPE_PRIMARY_KEY_TABLE); if (!index) { auto fk_column_names = StringUtil::Join(fk.pk_columns, ","); throw BinderException("Failed to create foreign key on %s(%s): no UNIQUE or PRIMARY KEY constraint " @@ -201976,29 +213596,30 @@ BoundStatement Binder::Bind(CreateStatement &stmt) { if (AnyConstraintReferencesGeneratedColumn(create_info)) { throw BinderException("Constraints on generated columns are not supported yet"); } - auto bound_info = BindCreateTableInfo(move(stmt.info)); - auto root = move(bound_info->query); + auto bound_info = BindCreateTableInfo(std::move(stmt.info)); + auto root = std::move(bound_info->query); for (auto &fk_schema : fk_schemas) { if (fk_schema != bound_info->schema) { - throw BinderException("Creating foreign keys across different schemas is not supported"); + throw BinderException("Creating foreign keys across different schemas or catalogs is not supported"); } } // create the logical operator auto &schema = bound_info->schema; - auto create_table = make_unique(schema, move(bound_info)); + auto create_table = make_unique(schema, std::move(bound_info)); if (root) { // CREATE TABLE AS properties.return_type = StatementReturnType::CHANGED_ROWS; - create_table->children.push_back(move(root)); + create_table->children.push_back(std::move(root)); } - result.plan = move(create_table); + result.plan = std::move(create_table); break; } case CatalogType::TYPE_ENTRY: { - auto schema = BindSchema(*stmt.info); + auto schema = BindCreateSchema(*stmt.info); auto &create_type_info = (CreateTypeInfo &)(*stmt.info); - result.plan = make_unique(LogicalOperatorType::LOGICAL_CREATE_TYPE, move(stmt.info), schema); + result.plan = + make_unique(LogicalOperatorType::LOGICAL_CREATE_TYPE, std::move(stmt.info), schema); if (create_type_info.query) { // CREATE TYPE mood AS ENUM (SELECT 'happy') auto &select_stmt = (SelectStatement &)*create_type_info.query; @@ -202022,11 +213643,11 @@ BoundStatement Binder::Bind(CreateStatement &stmt) { if (need_to_add) { auto distinct_modifier = make_unique(); distinct_modifier->distinct_on_targets.push_back(make_unique(Value::INTEGER(1))); - query_node.modifiers.emplace(query_node.modifiers.begin(), move(distinct_modifier)); + query_node.modifiers.emplace(query_node.modifiers.begin(), std::move(distinct_modifier)); } auto query_obj = Bind(*create_type_info.query); - auto query = move(query_obj.plan); + auto query = std::move(query_obj.plan); auto &sql_types = query_obj.types; if (sql_types.size() != 1 || sql_types[0].id() != LogicalType::VARCHAR) { @@ -202034,7 +213655,41 @@ BoundStatement Binder::Bind(CreateStatement &stmt) { throw BinderException("The query must return one varchar column"); } - result.plan->AddChild(move(query)); + result.plan->AddChild(std::move(query)); + } else if (create_type_info.type.id() == LogicalTypeId::USER) { + // two cases: + // 1: create a type with a non-existant type as source, catalog.GetType(...) will throw exception. + // 2: create a type alias with a custom type. + // eg. CREATE TYPE a AS INT; CREATE TYPE b AS a; + // We set b to be an alias for the underlying type of a + auto inner_type = Catalog::GetType(context, schema->catalog->GetName(), schema->name, + UserType::GetTypeName(create_type_info.type)); + // clear to nullptr, we don't need this + LogicalType::SetCatalog(inner_type, nullptr); + inner_type.SetAlias(create_type_info.name); + create_type_info.type = inner_type; + } + break; + } + case CatalogType::DATABASE_ENTRY: { + // not supported in DuckDB yet but allow extensions to intercept and implement this functionality + auto &base = (CreateDatabaseInfo &)*stmt.info; + string extension_name = base.extension_name; + string database_name = base.name; + string source_path = base.path; + + auto &config = DBConfig::GetConfig(context); + for (auto &extension : config.create_database_extensions) { + auto create_database_function_ref = + extension.function(context, extension_name, database_name, source_path, extension.data.get()); + if (create_database_function_ref) { + auto bound_create_database_func = Bind(*create_database_function_ref); + result.plan = CreatePlan(*bound_create_database_func); + break; + } + } + if (!result.plan) { + throw NotImplementedException("CREATE DATABASE not supported in DuckDB yet"); } break; } @@ -202130,9 +213785,9 @@ static void BindCheckConstraint(Binder &binder, BoundCreateTableInfo &info, cons auto unbound_expression = check.expression->Copy(); // now bind the constraint and create a new BoundCheckConstraint bound_constraint->expression = check_binder.Bind(check.expression); - info.bound_constraints.push_back(move(bound_constraint)); + info.bound_constraints.push_back(std::move(bound_constraint)); // move the unbound constraint back into the original check expression - check.expression = move(unbound_expression); + check.expression = std::move(unbound_expression); } static void BindConstraints(Binder &binder, BoundCreateTableInfo &info) { @@ -202195,7 +213850,7 @@ static void BindConstraints(Binder &binder, BoundCreateTableInfo &info) { primary_keys = keys; } info.bound_constraints.push_back( - make_unique(move(keys), move(key_set), unique.is_primary_key)); + make_unique(std::move(keys), std::move(key_set), unique.is_primary_key)); break; } case ConstraintType::FOREIGN_KEY: { @@ -202211,7 +213866,7 @@ static void BindConstraints(Binder &binder, BoundCreateTableInfo &info) { fk_key_set.insert(fk.info.fk_keys[i]); } info.bound_constraints.push_back( - make_unique(fk.info, move(pk_key_set), move(fk_key_set))); + make_unique(fk.info, std::move(pk_key_set), std::move(fk_key_set))); break; } default: @@ -202287,7 +213942,7 @@ void Binder::BindGeneratedColumns(BoundCreateTableInfo &info) { } } -void Binder::BindDefaultValues(ColumnList &columns, vector> &bound_defaults) { +void Binder::BindDefaultValues(const ColumnList &columns, vector> &bound_defaults) { for (auto &column : columns.Physical()) { unique_ptr bound_default; if (column.DefaultValue()) { @@ -202301,11 +213956,11 @@ void Binder::BindDefaultValues(ColumnList &columns, vector(Value(column.Type())); } - bound_defaults.push_back(move(bound_default)); + bound_defaults.push_back(std::move(bound_default)); } } -static void ExtractExpressionDependencies(Expression &expr, unordered_set &dependencies) { +static void ExtractExpressionDependencies(Expression &expr, DependencyList &dependencies) { if (expr.type == ExpressionType::BOUND_FUNCTION) { auto &function = (BoundFunctionExpression &)expr; if (function.function.dependency) { @@ -202329,16 +213984,14 @@ static void ExtractDependencies(BoundCreateTableInfo &info) { } } } - -unique_ptr Binder::BindCreateTableInfo(unique_ptr info) { +unique_ptr Binder::BindCreateTableInfo(unique_ptr info, SchemaCatalogEntry *schema) { auto &base = (CreateTableInfo &)*info; - - auto result = make_unique(move(info)); - result->schema = BindSchema(*result->base); + auto result = make_unique(std::move(info)); + result->schema = schema; if (base.query) { // construct the result object auto query_obj = Bind(*base.query); - result->query = move(query_obj.plan); + result->query = std::move(query_obj.plan); // construct the set of columns based on the names and types of the query auto &names = query_obj.names; @@ -202372,18 +214025,24 @@ unique_ptr Binder::BindCreateTableInfo(unique_ptrschema->catalog); // We add a catalog dependency auto type_dependency = LogicalType::GetCatalog(column.Type()); if (type_dependency) { // Only if the USER comes from a create type - result->dependencies.insert(type_dependency); + result->dependencies.AddDependency(type_dependency); } } properties.allow_stream_result = false; return result; } +unique_ptr Binder::BindCreateTableInfo(unique_ptr info) { + auto &base = (CreateTableInfo &)*info; + auto schema = BindCreateSchema(base); + return BindCreateTableInfo(std::move(info), schema); +} + } // namespace duckdb @@ -202410,10 +214069,6 @@ class ReturningBinder : public ExpressionBinder { protected: BindResult BindExpression(unique_ptr *expr_ptr, idx_t depth, bool root_expression = false) override; - - // check certain column ref Names to make sure they are supported in the returning statement - // (i.e rowid) - BindResult BindColumnRef(unique_ptr *expr_ptr, idx_t depth); }; } // namespace duckdb @@ -202425,6 +214080,7 @@ class ReturningBinder : public ExpressionBinder { + namespace duckdb { BoundStatement Binder::Bind(DeleteStatement &stmt) { @@ -202444,7 +214100,7 @@ BoundStatement Binder::Bind(DeleteStatement &stmt) { if (!table->temporary) { // delete from persistent table: not read only! - properties.read_only = false; + properties.modified_databases.insert(table->catalog->GetName()); } // Add CTEs as bindable @@ -202460,14 +214116,14 @@ BoundStatement Binder::Bind(DeleteStatement &stmt) { auto op = CreatePlan(*bound_node); if (child_operator) { // already bound a child: create a cross product to unify the two - child_operator = LogicalCrossProduct::Create(move(child_operator), move(op)); + child_operator = LogicalCrossProduct::Create(std::move(child_operator), std::move(op)); } else { - child_operator = move(op); + child_operator = std::move(op); } - bind_context.AddContext(move(using_binder->bind_context)); + bind_context.AddContext(std::move(using_binder->bind_context)); } if (child_operator) { - root = LogicalCrossProduct::Create(move(root), move(child_operator)); + root = LogicalCrossProduct::Create(std::move(root), std::move(child_operator)); } } @@ -202478,13 +214134,13 @@ BoundStatement Binder::Bind(DeleteStatement &stmt) { condition = binder.Bind(stmt.condition); PlanSubqueries(&condition, &root); - auto filter = make_unique(move(condition)); - filter->AddChild(move(root)); - root = move(filter); + auto filter = make_unique(std::move(condition)); + filter->AddChild(std::move(root)); + root = std::move(filter); } // create the delete node auto del = make_unique(table, GenerateTableIndex()); - del->AddChild(move(root)); + del->AddChild(std::move(root)); // set up the delete expression del->expressions.push_back(make_unique( @@ -202497,11 +214153,11 @@ BoundStatement Binder::Bind(DeleteStatement &stmt) { auto update_table_index = GenerateTableIndex(); del->table_index = update_table_index; - unique_ptr del_as_logicaloperator = move(del); - return BindReturning(move(stmt.returning_list), table, update_table_index, move(del_as_logicaloperator), - move(result)); + unique_ptr del_as_logicaloperator = std::move(del); + return BindReturning(std::move(stmt.returning_list), table, update_table_index, + std::move(del_as_logicaloperator), std::move(result)); } - result.plan = move(del); + result.plan = std::move(del); result.names = {"Count"}; result.types = {LogicalType::BIGINT}; properties.allow_stream_result = false; @@ -202529,10 +214185,12 @@ BoundStatement Binder::Bind(DropStatement &stmt) { // it also does not require a valid transaction properties.requires_valid_transaction = false; break; - case CatalogType::SCHEMA_ENTRY: + case CatalogType::SCHEMA_ENTRY: { // dropping a schema is never read-only because there are no temporary schemas - properties.read_only = false; + auto &catalog = Catalog::GetCatalog(context, stmt.info->catalog); + properties.modified_databases.insert(catalog.GetName()); break; + } case CatalogType::VIEW_ENTRY: case CatalogType::SEQUENCE_ENTRY: case CatalogType::MACRO_ENTRY: @@ -202540,22 +214198,28 @@ BoundStatement Binder::Bind(DropStatement &stmt) { case CatalogType::INDEX_ENTRY: case CatalogType::TABLE_ENTRY: case CatalogType::TYPE_ENTRY: { - auto entry = (StandardEntry *)Catalog::GetCatalog(context).GetEntry(context, stmt.info->type, stmt.info->schema, - stmt.info->name, true); + BindSchemaOrCatalog(stmt.info->catalog, stmt.info->schema); + auto entry = (StandardEntry *)Catalog::GetEntry(context, stmt.info->type, stmt.info->catalog, stmt.info->schema, + stmt.info->name, true); if (!entry) { break; } + stmt.info->catalog = entry->catalog->GetName(); if (!entry->temporary) { // we can only drop temporary tables in read-only mode - properties.read_only = false; + properties.modified_databases.insert(stmt.info->catalog); } stmt.info->schema = entry->schema->name; break; } + case CatalogType::DATABASE_ENTRY: + // attaching and detaching is read-only + stmt.info->catalog = SYSTEM_CATALOG; + break; default: throw BinderException("Unknown catalog type for drop statement!"); } - result.plan = make_unique(LogicalOperatorType::LOGICAL_DROP, move(stmt.info)); + result.plan = make_unique(LogicalOperatorType::LOGICAL_DROP, std::move(stmt.info)); result.names = {"Success"}; result.types = {LogicalType::BOOLEAN}; properties.allow_stream_result = false; @@ -202599,7 +214263,7 @@ BoundStatement Binder::Bind(ExecuteStatement &stmt) { auto bound_expr = cbinder.Bind(stmt.values[i]); Value value = ExpressionExecutor::EvaluateScalar(context, *bound_expr, true); - bind_values.push_back(move(value)); + bind_values.push_back(std::move(value)); } unique_ptr rebound_plan; if (prepared->RequireRebind(context, bind_values)) { @@ -202609,7 +214273,7 @@ BoundStatement Binder::Bind(ExecuteStatement &stmt) { prepared_planner.parameter_data.emplace_back(bind_values[i]); } prepared = prepared_planner.PrepareSQLStatement(entry->second->unbound_statement->Copy()); - rebound_plan = move(prepared_planner.plan); + rebound_plan = std::move(prepared_planner.plan); D_ASSERT(prepared->properties.bound_all_parameters); this->bound_tables = prepared_planner.binder->bound_tables; } @@ -202620,13 +214284,13 @@ BoundStatement Binder::Bind(ExecuteStatement &stmt) { result.names = prepared->names; result.types = prepared->types; - prepared->Bind(move(bind_values)); + prepared->Bind(std::move(bind_values)); if (rebound_plan) { - auto execute_plan = make_unique(move(prepared)); - execute_plan->children.push_back(move(rebound_plan)); - result.plan = move(execute_plan); + auto execute_plan = make_unique(std::move(prepared)); + execute_plan->children.push_back(std::move(rebound_plan)); + result.plan = std::move(execute_plan); } else { - result.plan = make_unique(move(prepared)); + result.plan = make_unique(std::move(prepared)); } return result; } @@ -202645,10 +214309,10 @@ BoundStatement Binder::Bind(ExplainStatement &stmt) { auto plan = Bind(*stmt.stmt); // get the unoptimized logical plan, and create the explain statement auto logical_plan_unopt = plan.plan->ToString(); - auto explain = make_unique(move(plan.plan), stmt.explain_type); + auto explain = make_unique(std::move(plan.plan), stmt.explain_type); explain->logical_plan_unopt = logical_plan_unopt; - result.plan = move(explain); + result.plan = std::move(explain); result.names = {"explain_key", "explain_value"}; result.types = {LogicalType::VARCHAR, LogicalType::VARCHAR}; properties.return_type = StatementReturnType::QUERY_RESULT; @@ -202670,6 +214334,7 @@ BoundStatement Binder::Bind(ExplainStatement &stmt) { + #include namespace duckdb { @@ -202712,8 +214377,9 @@ void ScanForeignKeyTable(vector &ordered, vectorconstraints.size(); j++) { - auto &cond = table_entry->constraints[j]; + auto &constraints = table_entry->GetConstraints(); + for (idx_t j = 0; j < constraints.size(); j++) { + auto &cond = constraints[j]; if (cond->type == ConstraintType::FOREIGN_KEY) { auto &fk = (ForeignKeyConstraint &)*cond; if ((move_only_pk_table && fk.info.type == ForeignKeyType::FK_TYPE_FOREIGN_KEY_TABLE) || @@ -202743,6 +214409,15 @@ void ReorderTableEntries(vector &tables) { tables = ordered; } +string CreateFileName(const string &id_suffix, TableCatalogEntry *table, const string &extension) { + auto name = SanitizeExportIdentifier(table->name); + if (table->schema->name == DEFAULT_SCHEMA) { + return StringUtil::Format("%s%s.%s", name, id_suffix, extension); + } + auto schema = SanitizeExportIdentifier(table->schema->name); + return StringUtil::Format("%s_%s%s.%s", schema, name, id_suffix, extension); +} + BoundStatement Binder::Bind(ExportStatement &stmt) { // COPY TO a file auto &config = DBConfig::GetConfig(context); @@ -202754,15 +214429,16 @@ BoundStatement Binder::Bind(ExportStatement &stmt) { result.names = {"Success"}; // lookup the format in the catalog - auto &catalog = Catalog::GetCatalog(context); - auto copy_function = catalog.GetEntry(context, DEFAULT_SCHEMA, stmt.info->format); - if (!copy_function->function.copy_to_bind) { + auto copy_function = + Catalog::GetEntry(context, INVALID_CATALOG, DEFAULT_SCHEMA, stmt.info->format); + if (!copy_function->function.copy_to_bind && !copy_function->function.plan) { throw NotImplementedException("COPY TO is not supported for FORMAT \"%s\"", stmt.info->format); } // gather a list of all the tables + string catalog = stmt.database.empty() ? INVALID_CATALOG : stmt.database; vector tables; - auto schemas = catalog.schemas->GetEntries(context); + auto schemas = Catalog::GetSchemas(context, catalog); for (auto &schema : schemas) { schema->Scan(context, CatalogType::TABLE_ENTRY, [&](CatalogEntry *entry) { if (entry->type == CatalogType::TABLE_ENTRY) { @@ -202792,35 +214468,31 @@ BoundStatement Binder::Bind(ExportStatement &stmt) { idx_t id = 0; while (true) { string id_suffix = id == 0 ? string() : "_" + to_string(id); - if (table->schema->name == DEFAULT_SCHEMA) { - info->file_path = fs.JoinPath(stmt.info->file_path, - StringUtil::Format("%s%s.%s", SanitizeExportIdentifier(table->name), - id_suffix, copy_function->function.extension)); - } else { - info->file_path = - fs.JoinPath(stmt.info->file_path, - StringUtil::Format("%s_%s%s.%s", SanitizeExportIdentifier(table->schema->name), - SanitizeExportIdentifier(table->name), id_suffix, - copy_function->function.extension)); - } - if (table_name_index.find(info->file_path) == table_name_index.end()) { + auto name = CreateFileName(id_suffix, table, copy_function->function.extension); + auto directory = stmt.info->file_path; + auto full_path = fs.JoinPath(directory, name); + info->file_path = full_path; + auto insert_result = table_name_index.insert(info->file_path); + if (insert_result.second == true) { // this name was not yet taken: take it - table_name_index.insert(info->file_path); break; } id++; } info->is_from = false; + info->catalog = catalog; info->schema = table->schema->name; info->table = table->name; // We can not export generated columns - for (auto &col : table->columns.Physical()) { + for (auto &col : table->GetColumns().Physical()) { info->select_list.push_back(col.GetName()); } + exported_data.database_name = catalog; exported_data.table_name = info->table; exported_data.schema_name = info->schema; + exported_data.file_path = info->file_path; ExportedTableInfo table_info; @@ -202831,18 +214503,18 @@ BoundStatement Binder::Bind(ExportStatement &stmt) { // generate the copy statement and bind it CopyStatement copy_stmt; - copy_stmt.info = move(info); + copy_stmt.info = std::move(info); auto copy_binder = Binder::CreateBinder(context, this); auto bound_statement = copy_binder->Bind(copy_stmt); if (child_operator) { // use UNION ALL to combine the individual copy statements into a single node auto copy_union = - make_unique(GenerateTableIndex(), 1, move(child_operator), - move(bound_statement.plan), LogicalOperatorType::LOGICAL_UNION); - child_operator = move(copy_union); + make_unique(GenerateTableIndex(), 1, std::move(child_operator), + std::move(bound_statement.plan), LogicalOperatorType::LOGICAL_UNION); + child_operator = std::move(copy_union); } else { - child_operator = move(bound_statement.plan); + child_operator = std::move(bound_statement.plan); } } @@ -202853,13 +214525,13 @@ BoundStatement Binder::Bind(ExportStatement &stmt) { } // create the export node - auto export_node = make_unique(copy_function->function, move(stmt.info), exported_tables); + auto export_node = make_unique(copy_function->function, std::move(stmt.info), exported_tables); if (child_operator) { - export_node->children.push_back(move(child_operator)); + export_node->children.push_back(std::move(child_operator)); } - result.plan = move(export_node); + result.plan = std::move(export_node); properties.allow_stream_result = false; properties.return_type = StatementReturnType::NOTHING; return result; @@ -202877,14 +214549,15 @@ BoundStatement Binder::Bind(ExtensionStatement &stmt) { // perform the planning of the function D_ASSERT(stmt.extension.plan_function); - auto parse_result = stmt.extension.plan_function(stmt.extension.parser_info.get(), context, move(stmt.parse_data)); + auto parse_result = + stmt.extension.plan_function(stmt.extension.parser_info.get(), context, std::move(stmt.parse_data)); - properties.read_only = parse_result.read_only; + properties.modified_databases = parse_result.modified_databases; properties.requires_valid_transaction = parse_result.requires_valid_transaction; properties.return_type = parse_result.return_type; // create the plan as a scan of the given table function - result.plan = BindTableFunction(parse_result.function, move(parse_result.parameters)); + result.plan = BindTableFunction(parse_result.function, std::move(parse_result.parameters)); D_ASSERT(result.plan->type == LogicalOperatorType::LOGICAL_GET); auto &get = (LogicalGet &)*result.plan; result.names = get.names; @@ -202938,6 +214611,68 @@ class InsertBinder : public ExpressionBinder { + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/expression_binder/update_binder.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +//! The UPDATE binder is responsible for binding an expression within an UPDATE statement +class UpdateBinder : public ExpressionBinder { +public: + UpdateBinder(Binder &binder, ClientContext &context); + +protected: + BindResult BindExpression(unique_ptr *expr_ptr, idx_t depth, + bool root_expression = false) override; + + string UnsupportedAggregateMessage() override; +}; + +} // namespace duckdb + + + + + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/tableref/bound_dummytableref.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +//! Represents a cross product +class BoundEmptyTableRef : public BoundTableRef { +public: + explicit BoundEmptyTableRef(idx_t bind_index) : BoundTableRef(TableReferenceType::EMPTY), bind_index(bind_index) { + } + idx_t bind_index; +}; +} // namespace duckdb + + + namespace duckdb { static void CheckInsertColumnCountMismatch(int64_t expected_columns, int64_t result_columns, bool columns_provided, @@ -202951,20 +214686,349 @@ static void CheckInsertColumnCountMismatch(int64_t expected_columns, int64_t res } } +unique_ptr ExpandDefaultExpression(const ColumnDefinition &column) { + if (column.DefaultValue()) { + return column.DefaultValue()->Copy(); + } else { + return make_unique(Value(column.Type())); + } +} + +void ReplaceDefaultExpression(unique_ptr &expr, const ColumnDefinition &column) { + D_ASSERT(expr->type == ExpressionType::VALUE_DEFAULT); + expr = ExpandDefaultExpression(column); +} + +void QualifyColumnReferences(unique_ptr &expr, const string &table_name) { + // To avoid ambiguity with 'excluded', we explicitly qualify all column references + if (expr->type == ExpressionType::COLUMN_REF) { + auto &column_ref = (ColumnRefExpression &)*expr; + if (column_ref.IsQualified()) { + return; + } + auto column_name = column_ref.GetColumnName(); + expr = make_unique(column_name, table_name); + } + ParsedExpressionIterator::EnumerateChildren( + *expr, [&](unique_ptr &child) { QualifyColumnReferences(child, table_name); }); +} + +// Replace binding.table_index with 'dest' if it's 'source' +void ReplaceColumnBindings(Expression &expr, idx_t source, idx_t dest) { + if (expr.type == ExpressionType::BOUND_COLUMN_REF) { + auto &bound_columnref = (BoundColumnRefExpression &)expr; + if (bound_columnref.binding.table_index == source) { + bound_columnref.binding.table_index = dest; + } + } + ExpressionIterator::EnumerateChildren( + expr, [&](unique_ptr &child) { ReplaceColumnBindings(*child, source, dest); }); +} + +void Binder::BindDoUpdateSetExpressions(const string &table_alias, LogicalInsert *insert, UpdateSetInfo &set_info, + TableCatalogEntry &table) { + D_ASSERT(insert->children.size() == 1); + D_ASSERT(insert->children[0]->type == LogicalOperatorType::LOGICAL_PROJECTION); + + vector logical_column_ids; + vector column_names; + D_ASSERT(set_info.columns.size() == set_info.expressions.size()); + + for (idx_t i = 0; i < set_info.columns.size(); i++) { + auto &colname = set_info.columns[i]; + auto &expr = set_info.expressions[i]; + if (!table.ColumnExists(colname)) { + throw BinderException("Referenced update column %s not found in table!", colname); + } + auto &column = table.GetColumn(colname); + if (column.Generated()) { + throw BinderException("Cant update column \"%s\" because it is a generated column!", column.Name()); + } + if (std::find(insert->set_columns.begin(), insert->set_columns.end(), column.Physical()) != + insert->set_columns.end()) { + throw BinderException("Multiple assignments to same column \"%s\"", colname); + } + insert->set_columns.push_back(column.Physical()); + logical_column_ids.push_back(column.Oid()); + insert->set_types.push_back(column.Type()); + column_names.push_back(colname); + if (expr->type == ExpressionType::VALUE_DEFAULT) { + expr = ExpandDefaultExpression(column); + } + UpdateBinder binder(*this, context); + binder.target_type = column.Type(); + + // Avoid ambiguity issues + QualifyColumnReferences(expr, table_alias); + + auto bound_expr = binder.Bind(expr); + D_ASSERT(bound_expr); + if (bound_expr->expression_class == ExpressionClass::BOUND_SUBQUERY) { + throw BinderException("Expression in the DO UPDATE SET clause can not be a subquery"); + } + + insert->expressions.push_back(std::move(bound_expr)); + } + + // Figure out which columns are indexed on + unordered_set indexed_columns; + auto &indexes = table.GetStorage().info->indexes.Indexes(); + for (auto &index : indexes) { + for (auto &column_id : index->column_id_set) { + indexed_columns.insert(column_id); + } + } + + // Verify that none of the columns that are targeted with a SET expression are indexed on + for (idx_t i = 0; i < logical_column_ids.size(); i++) { + auto &column = logical_column_ids[i]; + if (indexed_columns.count(column)) { + throw BinderException("Can not assign to column '%s' because it has a UNIQUE/PRIMARY KEY constraint", + column_names[i]); + } + } +} + +unique_ptr CreateSetInfoForReplace(TableCatalogEntry &table, InsertStatement &insert) { + auto set_info = make_unique(); + + auto &columns = set_info->columns; + // Figure out which columns are indexed on + + unordered_set indexed_columns; + auto &indexes = table.GetStorage().info->indexes.Indexes(); + for (auto &index : indexes) { + for (auto &column_id : index->column_id_set) { + indexed_columns.insert(column_id); + } + } + + auto &column_list = table.GetColumns(); + if (insert.columns.empty()) { + for (auto &column : column_list.Physical()) { + auto &name = column.Name(); + // FIXME: can these column names be aliased somehow? + if (indexed_columns.count(column.Oid())) { + continue; + } + columns.push_back(name); + } + } else { + // a list of columns was explicitly supplied, only update those + for (auto &name : insert.columns) { + auto &column = column_list.GetColumn(name); + if (indexed_columns.count(column.Oid())) { + continue; + } + columns.push_back(name); + } + } + + // Create 'excluded' qualified column references of these columns + for (auto &column : columns) { + set_info->expressions.push_back(make_unique(column, "excluded")); + } + + return set_info; +} + +void Binder::BindOnConflictClause(LogicalInsert &insert, TableCatalogEntry &table, InsertStatement &stmt) { + if (!stmt.on_conflict_info) { + insert.action_type = OnConflictAction::THROW; + return; + } + if (!table.IsDuckTable()) { + throw BinderException("ON CONFLICT clause is not yet supported for non-DuckDB tables"); + } + D_ASSERT(stmt.table_ref->type == TableReferenceType::BASE_TABLE); + + // visit the table reference + auto bound_table = Bind(*stmt.table_ref); + if (bound_table->type != TableReferenceType::BASE_TABLE) { + throw BinderException("Can only update base table!"); + } + + auto &table_ref = (BaseTableRef &)*stmt.table_ref; + const string &table_alias = !table_ref.alias.empty() ? table_ref.alias : table_ref.table_name; + + auto &on_conflict = *stmt.on_conflict_info; + D_ASSERT(on_conflict.action_type != OnConflictAction::THROW); + insert.action_type = on_conflict.action_type; + + auto &columns = table.GetColumns(); + if (!on_conflict.indexed_columns.empty()) { + // Bind the ON CONFLICT () + + // create a mapping of (list index) -> (column index) + case_insensitive_map_t specified_columns; + for (idx_t i = 0; i < on_conflict.indexed_columns.size(); i++) { + specified_columns[on_conflict.indexed_columns[i]] = i; + auto column_index = table.GetColumnIndex(on_conflict.indexed_columns[i]); + if (column_index.index == COLUMN_IDENTIFIER_ROW_ID) { + throw BinderException("Cannot specify ROWID as ON CONFLICT target"); + } + auto &col = columns.GetColumn(column_index); + if (col.Generated()) { + throw BinderException("Cannot specify a generated column as ON CONFLICT target"); + } + } + for (auto &col : columns.Physical()) { + auto entry = specified_columns.find(col.Name()); + if (entry != specified_columns.end()) { + // column was specified, set to the index + insert.on_conflict_filter.insert(col.Oid()); + } + } + auto &indexes = table.GetStorage().info->indexes; + bool index_references_columns = false; + indexes.Scan([&](Index &index) { + if (!index.IsUnique()) { + return false; + } + bool index_matches = insert.on_conflict_filter == index.column_id_set; + if (index_matches) { + index_references_columns = true; + } + return index_matches; + }); + if (!index_references_columns) { + // Same as before, this is essentially a no-op, turning this into a DO THROW instead + // But since this makes no logical sense, it's probably better to throw an error + throw BinderException( + "The specified columns as conflict target are not referenced by a UNIQUE/PRIMARY KEY CONSTRAINT"); + } + } else { + // When omitting the conflict target, the ON CONFLICT applies to every UNIQUE/PRIMARY KEY on the table + + // We check if there are any constraints on the table, if there aren't we throw an error. + auto &indexes = table.GetStorage().info->indexes; + idx_t found_matching_indexes = 0; + indexes.Scan([&](Index &index) { + if (!index.IsUnique()) { + return false; + } + // does this work with multi-column indexes? + auto &indexed_columns = index.column_id_set; + for (auto &column : table.GetColumns().Physical()) { + if (indexed_columns.count(column.Physical().index)) { + found_matching_indexes++; + } + } + return false; + }); + if (!found_matching_indexes) { + throw BinderException( + "There are no UNIQUE/PRIMARY KEY Indexes that refer to this table, ON CONFLICT is a no-op"); + } + if (insert.action_type != OnConflictAction::NOTHING && found_matching_indexes != 1) { + // When no conflict target is provided, and the action type is UPDATE, + // we only allow the operation when only a single Index exists + throw BinderException("Conflict target has to be provided for a DO UPDATE operation when the table has " + "multiple UNIQUE/PRIMARY KEY constraints"); + } + } + + // add the 'excluded' dummy table binding + AddTableName("excluded"); + // add a bind context entry for it + auto excluded_index = GenerateTableIndex(); + insert.excluded_table_index = excluded_index; + auto table_column_names = columns.GetColumnNames(); + auto table_column_types = columns.GetColumnTypes(); + bind_context.AddGenericBinding(excluded_index, "excluded", table_column_names, table_column_types); + + if (on_conflict.condition) { + // Avoid ambiguity between binding and 'excluded' + QualifyColumnReferences(on_conflict.condition, table_alias); + // Bind the ON CONFLICT ... WHERE clause + WhereBinder where_binder(*this, context); + auto condition = where_binder.Bind(on_conflict.condition); + if (condition && condition->expression_class == ExpressionClass::BOUND_SUBQUERY) { + throw BinderException("conflict_target WHERE clause can not be a subquery"); + } + insert.on_conflict_condition = std::move(condition); + } + + auto projection_index = insert.children[0]->GetTableIndex()[0]; + + string unused; + auto original_binding = bind_context.GetBinding(table_alias, unused); + D_ASSERT(original_binding); + + auto table_index = original_binding->index; + + // Replace any column bindings to refer to the projection table_index, rather than the source table + if (insert.on_conflict_condition) { + ReplaceColumnBindings(*insert.on_conflict_condition, table_index, projection_index); + } + + if (insert.action_type == OnConflictAction::NOTHING) { + if (!insert.on_conflict_condition) { + return; + } + // Get the column_ids we need to fetch later on from the conflicting tuples + // of the original table, to execute the expressions + D_ASSERT(original_binding->binding_type == BindingType::TABLE); + auto table_binding = (TableBinding *)original_binding; + insert.columns_to_fetch = table_binding->GetBoundColumnIds(); + return; + } + if (insert.action_type == OnConflictAction::REPLACE) { + D_ASSERT(on_conflict.set_info == nullptr); + on_conflict.set_info = CreateSetInfoForReplace(table, stmt); + insert.action_type = OnConflictAction::UPDATE; + } + + D_ASSERT(on_conflict.set_info); + auto &set_info = *on_conflict.set_info; + D_ASSERT(!set_info.columns.empty()); + D_ASSERT(set_info.columns.size() == set_info.expressions.size()); + + if (set_info.condition) { + // Avoid ambiguity between binding and 'excluded' + QualifyColumnReferences(set_info.condition, table_alias); + // Bind the SET ... WHERE clause + WhereBinder where_binder(*this, context); + auto condition = where_binder.Bind(set_info.condition); + if (condition && condition->expression_class == ExpressionClass::BOUND_SUBQUERY) { + throw BinderException("conflict_target WHERE clause can not be a subquery"); + } + insert.do_update_condition = std::move(condition); + } + + BindDoUpdateSetExpressions(table_alias, &insert, set_info, table); + + // Get the column_ids we need to fetch later on from the conflicting tuples + // of the original table, to execute the expressions + D_ASSERT(original_binding->binding_type == BindingType::TABLE); + auto table_binding = (TableBinding *)original_binding; + insert.columns_to_fetch = table_binding->GetBoundColumnIds(); + + // Replace the column bindings to refer to the child operator + for (auto &expr : insert.expressions) { + // Change the non-excluded column references to refer to the projection index + ReplaceColumnBindings(*expr, table_index, projection_index); + } + // Do the same for the (optional) DO UPDATE condition + if (insert.do_update_condition) { + ReplaceColumnBindings(*insert.do_update_condition, table_index, projection_index); + } +} + BoundStatement Binder::Bind(InsertStatement &stmt) { BoundStatement result; result.names = {"Count"}; result.types = {LogicalType::BIGINT}; - auto table = Catalog::GetCatalog(context).GetEntry(context, stmt.schema, stmt.table); + BindSchemaOrCatalog(stmt.catalog, stmt.schema); + auto table = Catalog::GetEntry(context, stmt.catalog, stmt.schema, stmt.table); D_ASSERT(table); if (!table->temporary) { // inserting into a non-temporary table: alters underlying database - properties.read_only = false; + properties.modified_databases.insert(table->catalog->GetName()); } auto insert = make_unique(table, GenerateTableIndex()); - // Add CTEs as bindable AddCTEMap(stmt.cte_map); @@ -202980,14 +215044,14 @@ BoundStatement Binder::Bind(InsertStatement &stmt) { if (column_index.index == COLUMN_IDENTIFIER_ROW_ID) { throw BinderException("Cannot explicitly insert values into rowid column"); } - auto &col = table->columns.GetColumn(column_index); + auto &col = table->GetColumn(column_index); if (col.Generated()) { throw BinderException("Cannot insert into a generated column"); } insert->expected_types.push_back(col.Type()); named_column_map.push_back(column_index); } - for (auto &col : table->columns.Physical()) { + for (auto &col : table->GetColumns().Physical()) { auto entry = column_name_map.find(col.Name()); if (entry == column_name_map.end()) { // column not specified, set index to DConstants::INVALID_INDEX @@ -202998,21 +215062,23 @@ BoundStatement Binder::Bind(InsertStatement &stmt) { } } } else { - for (auto &col : table->columns.Physical()) { + // No columns specified, assume insertion into all columns + // Intentionally don't populate 'column_index_map' as an indication of this + for (auto &col : table->GetColumns().Physical()) { named_column_map.push_back(col.Logical()); insert->expected_types.push_back(col.Type()); } } // bind the default values - BindDefaultValues(table->columns, insert->bound_defaults); + BindDefaultValues(table->GetColumns(), insert->bound_defaults); if (!stmt.select_statement) { - result.plan = move(insert); + result.plan = std::move(insert); return result; } // Exclude the generated columns from this amount - idx_t expected_columns = stmt.columns.empty() ? table->columns.PhysicalColumnCount() : stmt.columns.size(); + idx_t expected_columns = stmt.columns.empty() ? table->GetColumns().PhysicalColumnCount() : stmt.columns.size(); // special case: check if we are inserting from a VALUES statement auto values_list = stmt.GetValuesList(); @@ -203027,10 +215093,11 @@ BoundStatement Binder::Bind(InsertStatement &stmt) { // VALUES list! for (idx_t col_idx = 0; col_idx < expected_columns; col_idx++) { - auto table_col_idx = named_column_map[col_idx]; + D_ASSERT(named_column_map.size() >= col_idx); + auto &table_col_idx = named_column_map[col_idx]; // set the expected types as the types for the INSERT statement - auto &column = table->columns.GetColumn(table_col_idx); + auto &column = table->GetColumn(table_col_idx); expr_list.expected_types[col_idx] = column.Type(); expr_list.expected_names[col_idx] = column.Name(); @@ -203038,11 +215105,7 @@ BoundStatement Binder::Bind(InsertStatement &stmt) { for (idx_t list_idx = 0; list_idx < expr_list.values.size(); list_idx++) { if (expr_list.values[list_idx][col_idx]->type == ExpressionType::VALUE_DEFAULT) { // DEFAULT value! replace the entry - if (column.DefaultValue()) { - expr_list.values[list_idx][col_idx] = column.DefaultValue()->Copy(); - } else { - expr_list.values[list_idx][col_idx] = make_unique(Value(column.Type())); - } + ReplaceDefaultExpression(expr_list.values[list_idx][col_idx], column); } } } @@ -203056,9 +215119,10 @@ BoundStatement Binder::Bind(InsertStatement &stmt) { CheckInsertColumnCountMismatch(expected_columns, root_select.types.size(), !stmt.columns.empty(), table->name.c_str()); - auto root = CastLogicalOperatorToTypes(root_select.types, insert->expected_types, move(root_select.plan)); + auto root = CastLogicalOperatorToTypes(root_select.types, insert->expected_types, std::move(root_select.plan)); + insert->AddChild(std::move(root)); - insert->AddChild(move(root)); + BindOnConflictClause(*insert, *table, stmt); if (!stmt.returning_list.empty()) { insert->return_chunk = true; @@ -203066,14 +215130,14 @@ BoundStatement Binder::Bind(InsertStatement &stmt) { result.names.clear(); auto insert_table_index = GenerateTableIndex(); insert->table_index = insert_table_index; - unique_ptr index_as_logicaloperator = move(insert); + unique_ptr index_as_logicaloperator = std::move(insert); - return BindReturning(move(stmt.returning_list), table, insert_table_index, move(index_as_logicaloperator), - move(result)); + return BindReturning(std::move(stmt.returning_list), table, insert_table_index, + std::move(index_as_logicaloperator), std::move(result)); } D_ASSERT(result.types.size() == result.names.size()); - result.plan = move(insert); + result.plan = std::move(insert); properties.allow_stream_result = false; properties.return_type = StatementReturnType::CHANGED_ROWS; return result; @@ -203092,7 +215156,7 @@ BoundStatement Binder::Bind(LoadStatement &stmt) { result.types = {LogicalType::BOOLEAN}; result.names = {"Success"}; - result.plan = make_unique(LogicalOperatorType::LOGICAL_LOAD, move(stmt.info)); + result.plan = make_unique(LogicalOperatorType::LOGICAL_LOAD, std::move(stmt.info)); properties.allow_stream_result = false; properties.return_type = StatementReturnType::NOTHING; return result; @@ -203111,7 +215175,7 @@ BoundStatement Binder::Bind(LogicalPlanStatement &stmt) { for (idx_t i = 0; i < result.types.size(); i++) { result.names.push_back(StringUtil::Format("col%d", i)); } - result.plan = move(stmt.plan); + result.plan = std::move(stmt.plan); properties.allow_stream_result = true; properties.return_type = StatementReturnType::QUERY_RESULT; // TODO could also be something else @@ -203129,9 +215193,9 @@ BoundStatement Binder::Bind(LogicalPlanStatement &stmt) { namespace duckdb { BoundStatement Binder::Bind(PragmaStatement &stmt) { - auto &catalog = Catalog::GetCatalog(context); // bind the pragma function - auto entry = catalog.GetEntry(context, DEFAULT_SCHEMA, stmt.info->name, false); + auto entry = + Catalog::GetEntry(context, INVALID_CATALOG, DEFAULT_SCHEMA, stmt.info->name, false); string error; FunctionBinder function_binder(context); idx_t bound_idx = function_binder.BindFunction(entry->name, entry->functions, *stmt.info, error); @@ -203166,12 +215230,10 @@ namespace duckdb { BoundStatement Binder::Bind(PrepareStatement &stmt) { Planner prepared_planner(context); - auto prepared_data = prepared_planner.PrepareSQLStatement(move(stmt.statement)); + auto prepared_data = prepared_planner.PrepareSQLStatement(std::move(stmt.statement)); this->bound_tables = prepared_planner.binder->bound_tables; - auto prepare = make_unique(stmt.name, move(prepared_data), move(prepared_planner.plan)); - // we can prepare in read-only mode: prepared statements are not written to the catalog - properties.read_only = true; + auto prepare = make_unique(stmt.name, std::move(prepared_data), std::move(prepared_planner.plan)); // we can always prepare, even if the transaction has been invalidated // this is required because most clients ALWAYS invoke prepared statements properties.requires_valid_transaction = false; @@ -203183,7 +215245,7 @@ BoundStatement Binder::Bind(PrepareStatement &stmt) { BoundStatement result; result.names = {"Success"}; result.types = {LogicalType::BOOLEAN}; - result.plan = move(prepare); + result.plan = std::move(prepare); return result; } @@ -203218,11 +215280,12 @@ BoundStatement Binder::Bind(SelectStatement &stmt) { + #include namespace duckdb { -BoundStatement Binder::Bind(SetStatement &stmt) { +BoundStatement Binder::Bind(SetVariableStatement &stmt) { BoundStatement result; result.types = {LogicalType::BOOLEAN}; result.names = {"Success"}; @@ -203232,6 +215295,31 @@ BoundStatement Binder::Bind(SetStatement &stmt) { return result; } +BoundStatement Binder::Bind(ResetVariableStatement &stmt) { + BoundStatement result; + result.types = {LogicalType::BOOLEAN}; + result.names = {"Success"}; + + result.plan = make_unique(stmt.name, stmt.scope); + properties.return_type = StatementReturnType::NOTHING; + return result; +} + +BoundStatement Binder::Bind(SetStatement &stmt) { + switch (stmt.set_type) { + case SetType::SET: { + auto &set_stmt = (SetVariableStatement &)stmt; + return Bind(set_stmt); + } + case SetType::RESET: { + auto &set_stmt = (ResetVariableStatement &)stmt; + return Bind(set_stmt); + } + default: + throw NotImplementedException("Type not implemented for SetType"); + } +} + } // namespace duckdb @@ -203249,11 +215337,11 @@ BoundStatement Binder::Bind(ShowStatement &stmt) { stmt.info->types = plan.types; stmt.info->aliases = plan.names; - auto show = make_unique(move(plan.plan)); + auto show = make_unique(std::move(plan.plan)); show->types_select = plan.types; show->aliases = plan.names; - result.plan = move(show); + result.plan = std::move(show); result.names = {"column_name", "column_type", "null", "key", "default", "extra"}; result.types = {LogicalType::VARCHAR, LogicalType::VARCHAR, LogicalType::VARCHAR, @@ -203271,6 +215359,7 @@ BoundStatement Binder::Bind(ShowStatement &stmt) { + //! This file contains the binder definitions for statements that do not need to be bound at all and only require a //! straightforward conversion @@ -203280,14 +215369,18 @@ BoundStatement Binder::Bind(AlterStatement &stmt) { BoundStatement result; result.names = {"Success"}; result.types = {LogicalType::BOOLEAN}; - Catalog &catalog = Catalog::GetCatalog(context); - auto entry = catalog.GetEntry(context, stmt.info->GetCatalogType(), stmt.info->schema, stmt.info->name, - stmt.info->if_exists); - if (entry && !entry->temporary) { - // we can only alter temporary tables/views in read-only mode - properties.read_only = false; - } - result.plan = make_unique(LogicalOperatorType::LOGICAL_ALTER, move(stmt.info)); + BindSchemaOrCatalog(stmt.info->catalog, stmt.info->schema); + auto entry = Catalog::GetEntry(context, stmt.info->GetCatalogType(), stmt.info->catalog, stmt.info->schema, + stmt.info->name, stmt.info->if_exists); + if (entry) { + if (!entry->temporary) { + // we can only alter temporary tables/views in read-only mode + properties.modified_databases.insert(entry->catalog->GetName()); + } + stmt.info->catalog = entry->catalog->GetName(); + stmt.info->schema = ((StandardEntry *)entry)->schema->name; + } + result.plan = make_unique(LogicalOperatorType::LOGICAL_ALTER, std::move(stmt.info)); properties.return_type = StatementReturnType::NOTHING; return result; } @@ -203299,7 +215392,7 @@ BoundStatement Binder::Bind(TransactionStatement &stmt) { BoundStatement result; result.names = {"Success"}; result.types = {LogicalType::BOOLEAN}; - result.plan = make_unique(LogicalOperatorType::LOGICAL_TRANSACTION, move(stmt.info)); + result.plan = make_unique(LogicalOperatorType::LOGICAL_TRANSACTION, std::move(stmt.info)); properties.return_type = StatementReturnType::NOTHING; return result; } @@ -203318,58 +215411,60 @@ namespace duckdb { static unique_ptr SummarizeWrapUnnest(vector> &children, const string &alias) { - auto list_function = make_unique("list_value", move(children)); + auto list_function = make_unique("list_value", std::move(children)); vector> unnest_children; - unnest_children.push_back(move(list_function)); - auto unnest_function = make_unique("unnest", move(unnest_children)); + unnest_children.push_back(std::move(list_function)); + auto unnest_function = make_unique("unnest", std::move(unnest_children)); unnest_function->alias = alias; - return move(unnest_function); + return std::move(unnest_function); } static unique_ptr SummarizeCreateAggregate(const string &aggregate, string column_name) { vector> children; - children.push_back(make_unique(move(column_name))); - auto aggregate_function = make_unique(aggregate, move(children)); - auto cast_function = make_unique(LogicalType::VARCHAR, move(aggregate_function)); - return move(cast_function); + children.push_back(make_unique(std::move(column_name))); + auto aggregate_function = make_unique(aggregate, std::move(children)); + auto cast_function = make_unique(LogicalType::VARCHAR, std::move(aggregate_function)); + return std::move(cast_function); } static unique_ptr SummarizeCreateAggregate(const string &aggregate, string column_name, const Value &modifier) { vector> children; - children.push_back(make_unique(move(column_name))); + children.push_back(make_unique(std::move(column_name))); children.push_back(make_unique(modifier)); - auto aggregate_function = make_unique(aggregate, move(children)); - auto cast_function = make_unique(LogicalType::VARCHAR, move(aggregate_function)); - return move(cast_function); + auto aggregate_function = make_unique(aggregate, std::move(children)); + auto cast_function = make_unique(LogicalType::VARCHAR, std::move(aggregate_function)); + return std::move(cast_function); } static unique_ptr SummarizeCreateCountStar() { vector> children; - auto aggregate_function = make_unique("count_star", move(children)); - return move(aggregate_function); + auto aggregate_function = make_unique("count_star", std::move(children)); + return std::move(aggregate_function); } static unique_ptr SummarizeCreateBinaryFunction(const string &op, unique_ptr left, unique_ptr right) { vector> children; - children.push_back(move(left)); - children.push_back(move(right)); - auto binary_function = make_unique(op, move(children)); - return move(binary_function); + children.push_back(std::move(left)); + children.push_back(std::move(right)); + auto binary_function = make_unique(op, std::move(children)); + return std::move(binary_function); } static unique_ptr SummarizeCreateNullPercentage(string column_name) { auto count_star = make_unique(LogicalType::DOUBLE, SummarizeCreateCountStar()); - auto count = make_unique(LogicalType::DOUBLE, SummarizeCreateAggregate("count", move(column_name))); - auto null_percentage = SummarizeCreateBinaryFunction("/", move(count), move(count_star)); - auto negate_x = - SummarizeCreateBinaryFunction("-", make_unique(Value::DOUBLE(1)), move(null_percentage)); + auto count = + make_unique(LogicalType::DOUBLE, SummarizeCreateAggregate("count", std::move(column_name))); + auto null_percentage = SummarizeCreateBinaryFunction("/", std::move(count), std::move(count_star)); + auto negate_x = SummarizeCreateBinaryFunction("-", make_unique(Value::DOUBLE(1)), + std::move(null_percentage)); auto percentage_x = - SummarizeCreateBinaryFunction("*", move(negate_x), make_unique(Value::DOUBLE(100))); - auto round_x = - SummarizeCreateBinaryFunction("round", move(percentage_x), make_unique(Value::INTEGER(2))); - auto concat_x = SummarizeCreateBinaryFunction("concat", move(round_x), make_unique(Value("%"))); + SummarizeCreateBinaryFunction("*", std::move(negate_x), make_unique(Value::DOUBLE(100))); + auto round_x = SummarizeCreateBinaryFunction("round", std::move(percentage_x), + make_unique(Value::INTEGER(2))); + auto concat_x = + SummarizeCreateBinaryFunction("concat", std::move(round_x), make_unique(Value("%"))); return concat_x; } @@ -203394,7 +215489,7 @@ BoundStatement Binder::BindSummarize(ShowStatement &stmt) { vector> count_children; vector> null_percentage_children; auto select = make_unique(); - select->node = move(query_copy); + select->node = std::move(query_copy); for (idx_t i = 0; i < plan.names.size(); i++) { name_children.push_back(make_unique(Value(plan.names[i]))); type_children.push_back(make_unique(Value(plan.types[i].ToString()))); @@ -203417,7 +215512,7 @@ BoundStatement Binder::BindSummarize(ShowStatement &stmt) { count_children.push_back(SummarizeCreateCountStar()); null_percentage_children.push_back(SummarizeCreateNullPercentage(plan.names[i])); } - auto subquery_ref = make_unique(move(select), "summarize_tbl"); + auto subquery_ref = make_unique(std::move(select), "summarize_tbl"); subquery_ref->column_name_alias = plan.names; auto select_node = make_unique(); @@ -203433,7 +215528,7 @@ BoundStatement Binder::BindSummarize(ShowStatement &stmt) { select_node->select_list.push_back(SummarizeWrapUnnest(q75_children, "q75")); select_node->select_list.push_back(SummarizeWrapUnnest(count_children, "count")); select_node->select_list.push_back(SummarizeWrapUnnest(null_percentage_children, "null_percentage")); - select_node->from_table = move(subquery_ref); + select_node->from_table = std::move(subquery_ref); properties.return_type = StatementReturnType::QUERY_RESULT; return Bind(*select_node); @@ -203443,14 +215538,10 @@ BoundStatement Binder::BindSummarize(ShowStatement &stmt) { - - - - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/planner/expression_binder/update_binder.hpp +// duckdb/planner/tableref/bound_joinref.hpp // // //===----------------------------------------------------------------------===// @@ -203459,20 +215550,38 @@ BoundStatement Binder::BindSummarize(ShowStatement &stmt) { + + + + namespace duckdb { -//! The UPDATE binder is responsible for binding an expression within an UPDATE statement -class UpdateBinder : public ExpressionBinder { +//! Represents a join +class BoundJoinRef : public BoundTableRef { public: - UpdateBinder(Binder &binder, ClientContext &context); - -protected: - BindResult BindExpression(unique_ptr *expr_ptr, idx_t depth, - bool root_expression = false) override; + explicit BoundJoinRef(JoinRefType ref_type) + : BoundTableRef(TableReferenceType::JOIN), type(JoinType::INNER), ref_type(ref_type), lateral(false) { + } - string UnsupportedAggregateMessage() override; + //! The binder used to bind the LHS of the join + shared_ptr left_binder; + //! The binder used to bind the RHS of the join + shared_ptr right_binder; + //! The left hand side of the join + unique_ptr left; + //! The right hand side of the join + unique_ptr right; + //! The join condition + unique_ptr condition; + //! The join type + JoinType type; + //! Join condition type + JoinRefType ref_type; + //! Whether or not this is a lateral join + bool lateral; + //! The correlated columns of the right-side with the left-side + vector correlated_columns; }; - } // namespace duckdb @@ -203481,38 +215590,12 @@ class UpdateBinder : public ExpressionBinder { -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/tableref/bound_crossproductref.hpp -// -// -//===----------------------------------------------------------------------===// -namespace duckdb { - -//! Represents a cross product -class BoundCrossProductRef : public BoundTableRef { -public: - BoundCrossProductRef() : BoundTableRef(TableReferenceType::CROSS_PRODUCT) { - } - - //! The binder used to bind the LHS of the cross product - shared_ptr left_binder; - //! The binder used to bind the RHS of the cross product - shared_ptr right_binder; - //! The left hand side of the cross product - unique_ptr left; - //! The right hand side of the cross product - unique_ptr right; -}; -} // namespace duckdb - #include @@ -203542,7 +215625,7 @@ static void BindExtraColumns(TableCatalogEntry &table, LogicalGet &get, LogicalP continue; } // column is not projected yet: project it by adding the clause "i=i" to the set of updated columns - auto &column = table.columns.GetColumn(check_column_id); + auto &column = table.GetColumns().GetColumn(check_column_id); update.expressions.push_back(make_unique( column.Type(), ColumnBinding(proj.table_index, proj.expressions.size()))); proj.expressions.push_back(make_unique( @@ -203576,21 +215659,25 @@ static bool TypeSupportsRegularUpdate(const LogicalType &type) { static void BindUpdateConstraints(TableCatalogEntry &table, LogicalGet &get, LogicalProjection &proj, LogicalUpdate &update) { + if (!table.IsDuckTable()) { + return; + } // check the constraints and indexes of the table to see if we need to project any additional columns // we do this for indexes with multiple columns and CHECK constraints in the UPDATE clause // suppose we have a constraint CHECK(i + j < 10); now we need both i and j to check the constraint // if we are only updating one of the two columns we add the other one to the UPDATE set // with a "useless" update (i.e. i=i) so we can verify that the CHECK constraint is not violated - for (auto &constraint : table.bound_constraints) { + for (auto &constraint : table.GetBoundConstraints()) { if (constraint->type == ConstraintType::CHECK) { auto &check = *reinterpret_cast(constraint.get()); // check constraint! check if we need to add any extra columns to the UPDATE clause BindExtraColumns(table, get, proj, update, check.bound_columns); } } + auto &storage = table.GetStorage(); if (update.return_chunk) { physical_index_set_t all_columns; - for (idx_t i = 0; i < table.storage->column_definitions.size(); i++) { + for (idx_t i = 0; i < storage.column_definitions.size(); i++) { all_columns.insert(PhysicalIndex(i)); } BindExtraColumns(table, get, proj, update, all_columns); @@ -203600,7 +215687,7 @@ static void BindUpdateConstraints(TableCatalogEntry &table, LogicalGet &get, Log // If the returning keyword is used, we need access to the whole row in case the user requests it. // Therefore switch the update to a delete and insert. update.update_is_del_and_insert = false; - table.storage->info->indexes.Scan([&](Index &index) { + storage.info->indexes.Scan([&](Index &index) { if (index.IndexIsUpdated(update.columns)) { update.update_is_del_and_insert = true; return true; @@ -203610,7 +215697,7 @@ static void BindUpdateConstraints(TableCatalogEntry &table, LogicalGet &get, Log // we also convert any updates on LIST columns into delete + insert for (auto &col_index : update.columns) { - auto &column = table.columns.GetColumn(col_index); + auto &column = table.GetColumns().GetColumn(col_index); if (!TypeSupportsRegularUpdate(column.Type())) { update.update_is_del_and_insert = true; break; @@ -203621,13 +215708,58 @@ static void BindUpdateConstraints(TableCatalogEntry &table, LogicalGet &get, Log // the update updates a column required by an index or requires returning the updated rows, // push projections for all columns physical_index_set_t all_columns; - for (idx_t i = 0; i < table.storage->column_definitions.size(); i++) { + for (idx_t i = 0; i < storage.column_definitions.size(); i++) { all_columns.insert(PhysicalIndex(i)); } BindExtraColumns(table, get, proj, update, all_columns); } } +// This creates a LogicalProjection and moves 'root' into it as a child +// unless there are no expressions to project, in which case it just returns 'root' +unique_ptr Binder::BindUpdateSet(LogicalOperator *op, unique_ptr root, + UpdateSetInfo &set_info, TableCatalogEntry *table, + vector &columns) { + auto proj_index = GenerateTableIndex(); + + vector> projection_expressions; + D_ASSERT(set_info.columns.size() == set_info.expressions.size()); + for (idx_t i = 0; i < set_info.columns.size(); i++) { + auto &colname = set_info.columns[i]; + auto &expr = set_info.expressions[i]; + if (!table->ColumnExists(colname)) { + throw BinderException("Referenced update column %s not found in table!", colname); + } + auto &column = table->GetColumn(colname); + if (column.Generated()) { + throw BinderException("Cant update column \"%s\" because it is a generated column!", column.Name()); + } + if (std::find(columns.begin(), columns.end(), column.Physical()) != columns.end()) { + throw BinderException("Multiple assignments to same column \"%s\"", colname); + } + columns.push_back(column.Physical()); + if (expr->type == ExpressionType::VALUE_DEFAULT) { + op->expressions.push_back(make_unique(column.Type())); + } else { + UpdateBinder binder(*this, context); + binder.target_type = column.Type(); + auto bound_expr = binder.Bind(expr); + PlanSubqueries(&bound_expr, &root); + + op->expressions.push_back(make_unique( + bound_expr->return_type, ColumnBinding(proj_index, projection_expressions.size()))); + projection_expressions.push_back(std::move(bound_expr)); + } + } + if (op->type != LogicalOperatorType::LOGICAL_UPDATE && projection_expressions.empty()) { + return root; + } + // now create the projection + auto proj = make_unique(proj_index, std::move(projection_expressions)); + proj->AddChild(std::move(root)); + return unique_ptr_cast(std::move(proj)); +} + BoundStatement Binder::Bind(UpdateStatement &stmt) { BoundStatement result; unique_ptr root; @@ -203645,8 +215777,8 @@ BoundStatement Binder::Bind(UpdateStatement &stmt) { AddCTEMap(stmt.cte_map); if (stmt.from_table) { - BoundCrossProductRef bound_crossproduct; - bound_crossproduct.left = move(bound_table); + BoundJoinRef bound_crossproduct(JoinRefType::CROSS); + bound_crossproduct.left = std::move(bound_table); bound_crossproduct.right = Bind(*stmt.from_table); root = CreatePlan(bound_crossproduct); get = (LogicalGet *)root->children[0].get(); @@ -203657,7 +215789,7 @@ BoundStatement Binder::Bind(UpdateStatement &stmt) { if (!table->temporary) { // update of persistent table: not read only! - properties.read_only = false; + properties.modified_databases.insert(table->catalog->GetName()); } auto update = make_unique(table); @@ -203666,80 +215798,48 @@ BoundStatement Binder::Bind(UpdateStatement &stmt) { update->return_chunk = true; } // bind the default values - BindDefaultValues(table->columns, update->bound_defaults); + BindDefaultValues(table->GetColumns(), update->bound_defaults); // project any additional columns required for the condition/expressions - if (stmt.condition) { + if (stmt.set_info->condition) { WhereBinder binder(*this, context); - auto condition = binder.Bind(stmt.condition); + auto condition = binder.Bind(stmt.set_info->condition); PlanSubqueries(&condition, &root); - auto filter = make_unique(move(condition)); - filter->AddChild(move(root)); - root = move(filter); + auto filter = make_unique(std::move(condition)); + filter->AddChild(std::move(root)); + root = std::move(filter); } - D_ASSERT(stmt.columns.size() == stmt.expressions.size()); - - auto proj_index = GenerateTableIndex(); - vector> projection_expressions; - - for (idx_t i = 0; i < stmt.columns.size(); i++) { - auto &colname = stmt.columns[i]; - auto &expr = stmt.expressions[i]; - if (!table->ColumnExists(colname)) { - throw BinderException("Referenced update column %s not found in table!", colname); - } - auto &column = table->GetColumn(colname); - if (column.Generated()) { - throw BinderException("Cant update column \"%s\" because it is a generated column!", column.Name()); - } - if (std::find(update->columns.begin(), update->columns.end(), column.Physical()) != update->columns.end()) { - throw BinderException("Multiple assignments to same column \"%s\"", colname); - } - update->columns.push_back(column.Physical()); + D_ASSERT(stmt.set_info); + D_ASSERT(stmt.set_info->columns.size() == stmt.set_info->expressions.size()); - if (expr->type == ExpressionType::VALUE_DEFAULT) { - update->expressions.push_back(make_unique(column.Type())); - } else { - UpdateBinder binder(*this, context); - binder.target_type = column.Type(); - auto bound_expr = binder.Bind(expr); - PlanSubqueries(&bound_expr, &root); - - update->expressions.push_back(make_unique( - bound_expr->return_type, ColumnBinding(proj_index, projection_expressions.size()))); - projection_expressions.push_back(move(bound_expr)); - } - } - - // now create the projection - auto proj = make_unique(proj_index, move(projection_expressions)); - proj->AddChild(move(root)); + auto proj_tmp = BindUpdateSet(update.get(), std::move(root), *stmt.set_info, table, update->columns); + D_ASSERT(proj_tmp->type == LogicalOperatorType::LOGICAL_PROJECTION); + auto proj = unique_ptr_cast(std::move(proj_tmp)); // bind any extra columns necessary for CHECK constraints or indexes BindUpdateConstraints(*table, *get, *proj, *update); - // finally add the row id column to the projection list proj->expressions.push_back(make_unique( LogicalType::ROW_TYPE, ColumnBinding(get->table_index, get->column_ids.size()))); get->column_ids.push_back(COLUMN_IDENTIFIER_ROW_ID); // set the projection as child of the update node and finalize the result - update->AddChild(move(proj)); + update->AddChild(std::move(proj)); auto update_table_index = GenerateTableIndex(); update->table_index = update_table_index; if (!stmt.returning_list.empty()) { - unique_ptr update_as_logicaloperator = move(update); + unique_ptr update_as_logicaloperator = std::move(update); - return BindReturning(move(stmt.returning_list), table, update_table_index, move(update_as_logicaloperator), - move(result)); + return BindReturning(std::move(stmt.returning_list), table, update_table_index, + std::move(update_as_logicaloperator), std::move(result)); } result.names = {"Count"}; result.types = {LogicalType::BIGINT}; - result.plan = move(update); + result.plan = std::move(update); properties.allow_stream_result = false; properties.return_type = StatementReturnType::CHANGED_ROWS; return result; @@ -203753,6 +215853,7 @@ BoundStatement Binder::Bind(UpdateStatement &stmt) { + namespace duckdb { BoundStatement Binder::Bind(VacuumStatement &stmt) { @@ -203767,7 +215868,7 @@ BoundStatement Binder::Bind(VacuumStatement &stmt) { if (bound_table->type != TableReferenceType::BASE_TABLE) { throw InvalidInputException("Can only vacuum/analyze base tables!"); } - auto ref = unique_ptr_cast(move(bound_table)); + auto ref = unique_ptr_cast(std::move(bound_table)); stmt.info->table = ref->table; auto &columns = stmt.info->columns; @@ -203799,9 +215900,9 @@ BoundStatement Binder::Bind(VacuumStatement &stmt) { if (result.HasError()) { throw BinderException(result.error); } - select_list.push_back(move(result.expression)); + select_list.push_back(std::move(result.expression)); } - stmt.info->columns = move(non_generated_column_names); + stmt.info->columns = std::move(non_generated_column_names); if (!select_list.empty()) { auto table_scan = CreatePlan(*ref); D_ASSERT(table_scan->type == LogicalOperatorType::LOGICAL_GET); @@ -203812,13 +215913,13 @@ BoundStatement Binder::Bind(VacuumStatement &stmt) { D_ASSERT(stmt.info->columns.size() == get.column_ids.size()); for (idx_t i = 0; i < get.column_ids.size(); i++) { stmt.info->column_id_map[i] = - ref->table->columns.LogicalToPhysical(LogicalIndex(get.column_ids[i])).index; + ref->table->GetColumns().LogicalToPhysical(LogicalIndex(get.column_ids[i])).index; } - auto projection = make_unique(GenerateTableIndex(), move(select_list)); - projection->children.push_back(move(table_scan)); + auto projection = make_unique(GenerateTableIndex(), std::move(select_list)); + projection->children.push_back(std::move(table_scan)); - root = move(projection); + root = std::move(projection); } else { // eg. CREATE TABLE test (x AS (1)); // ANALYZE test; @@ -203826,14 +215927,14 @@ BoundStatement Binder::Bind(VacuumStatement &stmt) { stmt.info->has_table = false; } } - auto vacuum = make_unique(LogicalOperatorType::LOGICAL_VACUUM, move(stmt.info)); + auto vacuum = make_unique(LogicalOperatorType::LOGICAL_VACUUM, std::move(stmt.info)); if (root) { - vacuum->children.push_back(move(root)); + vacuum->children.push_back(std::move(root)); } result.names = {"Success"}; result.types = {LogicalType::BOOLEAN}; - result.plan = move(vacuum); + result.plan = std::move(vacuum); properties.return_type = StatementReturnType::NOTHING; return result; } @@ -203845,6 +215946,7 @@ BoundStatement Binder::Bind(VacuumStatement &stmt) { + //===----------------------------------------------------------------------===// // DuckDB // @@ -203865,7 +215967,7 @@ namespace duckdb { class BoundSubqueryRef : public BoundTableRef { public: BoundSubqueryRef(shared_ptr binder_p, unique_ptr subquery) - : BoundTableRef(TableReferenceType::SUBQUERY), binder(move(binder_p)), subquery(move(subquery)) { + : BoundTableRef(TableReferenceType::SUBQUERY), binder(std::move(binder_p)), subquery(std::move(subquery)) { } //! The binder used to bind the subquery @@ -203912,28 +216014,6 @@ class BoundCTERef : public BoundTableRef { -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/tableref/bound_dummytableref.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { - -//! Represents a cross product -class BoundEmptyTableRef : public BoundTableRef { -public: - explicit BoundEmptyTableRef(idx_t bind_index) : BoundTableRef(TableReferenceType::EMPTY), bind_index(bind_index) { - } - idx_t bind_index; -}; -} // namespace duckdb namespace duckdb { @@ -203978,27 +216058,43 @@ unique_ptr Binder::Bind(BaseTableRef &ref) { (*cteref)++; result->types = b->types; - result->bound_columns = move(names); - return move(result); + result->bound_columns = std::move(names); + return std::move(result); } } // not a CTE // extract a table or view from the catalog - auto &catalog = Catalog::GetCatalog(context); - auto table_or_view = - catalog.GetEntry(context, CatalogType::TABLE_ENTRY, ref.schema_name, ref.table_name, true, error_context); + BindSchemaOrCatalog(ref.catalog_name, ref.schema_name); + auto table_or_view = Catalog::GetEntry(context, CatalogType::TABLE_ENTRY, ref.catalog_name, ref.schema_name, + ref.table_name, true, error_context); if (!table_or_view) { - auto table_name = ref.schema_name.empty() ? ref.table_name : (ref.schema_name + "." + ref.table_name); + string table_name = ref.catalog_name; + if (!ref.schema_name.empty()) { + table_name += (!table_name.empty() ? "." : "") + ref.schema_name; + } + table_name += (!table_name.empty() ? "." : "") + ref.table_name; // table could not be found: try to bind a replacement scan auto &config = DBConfig::GetConfig(context); - for (auto &scan : config.replacement_scans) { - auto replacement_function = scan.function(context, table_name, scan.data.get()); - if (replacement_function) { - replacement_function->alias = ref.alias.empty() ? ref.table_name : ref.alias; - replacement_function->column_name_alias = ref.column_name_alias; - return Bind(*replacement_function); + if (context.config.use_replacement_scans) { + for (auto &scan : config.replacement_scans) { + auto replacement_function = scan.function(context, table_name, scan.data.get()); + if (replacement_function) { + replacement_function->alias = ref.alias.empty() ? ref.table_name : ref.alias; + if (replacement_function->type == TableReferenceType::TABLE_FUNCTION) { + auto &table_function = (TableFunctionRef &)*replacement_function; + table_function.column_name_alias = ref.column_name_alias; + ; + } else if (replacement_function->type == TableReferenceType::SUBQUERY) { + auto &subquery = (SubqueryRef &)*replacement_function; + subquery.column_name_alias = ref.column_name_alias; + } else { + throw InternalException("Replacement scan should return either a table function or a subquery"); + } + return Bind(*replacement_function); + } } } + // we still didn't find the table if (GetBindingMode() == BindingMode::EXTRACT_NAMES) { // if we are in EXTRACT_NAMES, we create a dummy table ref @@ -204013,8 +216109,8 @@ unique_ptr Binder::Bind(BaseTableRef &ref) { return make_unique_base(table_index); } // could not find an alternative: bind again to get the error - table_or_view = Catalog::GetCatalog(context).GetEntry(context, CatalogType::TABLE_ENTRY, ref.schema_name, - ref.table_name, false, error_context); + table_or_view = Catalog::GetEntry(context, CatalogType::TABLE_ENTRY, ref.catalog_name, ref.schema_name, + ref.table_name, false, error_context); } switch (table_or_view->type) { case CatalogType::TABLE_ENTRY: { @@ -204022,8 +216118,8 @@ unique_ptr Binder::Bind(BaseTableRef &ref) { auto table_index = GenerateTableIndex(); auto table = (TableCatalogEntry *)table_or_view; - auto scan_function = TableScanFunction::GetFunction(); - auto bind_data = make_unique(table); + unique_ptr bind_data; + auto scan_function = table->GetScanFunction(context, bind_data); auto alias = ref.alias.empty() ? ref.table_name : ref.alias; // TODO: bundle the type and name vector in a struct (e.g PackedColumnMetadata) vector table_types; @@ -204032,7 +216128,7 @@ unique_ptr Binder::Bind(BaseTableRef &ref) { vector return_types; vector return_names; - for (auto &col : table->columns.Logical()) { + for (auto &col : table->GetColumns().Logical()) { table_types.push_back(col.Type()); table_names.push_back(col.Name()); return_types.push_back(col.Type()); @@ -204040,11 +216136,11 @@ unique_ptr Binder::Bind(BaseTableRef &ref) { } table_names = BindContext::AliasColumnNames(alias, table_names, ref.column_name_alias); - auto logical_get = make_unique(table_index, scan_function, move(bind_data), move(return_types), - move(return_names)); + auto logical_get = make_unique(table_index, scan_function, std::move(bind_data), + std::move(return_types), std::move(return_names)); bind_context.AddBaseTable(table_index, alias, table_names, table_types, logical_get->column_ids, logical_get->GetTable()); - return make_unique_base(table, move(logical_get)); + return make_unique_base(table, std::move(logical_get)); } case CatalogType::VIEW_ENTRY: { // the node is a view: get the query that the view represents @@ -204085,30 +216181,6 @@ unique_ptr Binder::Bind(BaseTableRef &ref) { -namespace duckdb { - -unique_ptr Binder::Bind(CrossProductRef &ref) { - auto result = make_unique(); - result->left_binder = Binder::CreateBinder(context, this); - result->right_binder = Binder::CreateBinder(context, this); - auto &left_binder = *result->left_binder; - auto &right_binder = *result->right_binder; - - result->left = left_binder.Bind(*ref.left); - result->right = right_binder.Bind(*ref.right); - - bind_context.AddContext(move(left_binder.bind_context)); - bind_context.AddContext(move(right_binder.bind_context)); - MoveCorrelatedExpressions(left_binder); - MoveCorrelatedExpressions(right_binder); - return move(result); -} - -} // namespace duckdb - - - - namespace duckdb { unique_ptr Binder::Bind(EmptyTableRef &ref) { @@ -204178,9 +216250,9 @@ unique_ptr Binder::Bind(ExpressionListRef &expr) { binder.target_type = result->types[val_idx]; } auto expr = binder.Bind(expression_list[val_idx]); - list.push_back(move(expr)); + list.push_back(std::move(expr)); } - result->values.push_back(move(list)); + result->values.push_back(std::move(list)); } if (result->types.empty() && !expr.values.empty()) { // there are no types specified @@ -204201,23 +216273,31 @@ unique_ptr Binder::Bind(ExpressionListRef &expr) { auto &list = result->values[list_idx]; for (idx_t val_idx = 0; val_idx < list.size(); val_idx++) { list[val_idx] = - BoundCastExpression::AddCastToType(context, move(list[val_idx]), result->types[val_idx]); + BoundCastExpression::AddCastToType(context, std::move(list[val_idx]), result->types[val_idx]); } } } result->bind_index = GenerateTableIndex(); bind_context.AddGenericBinding(result->bind_index, expr.alias, result->names, result->types); - return move(result); + return std::move(result); } } // namespace duckdb + + + + + + + + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/planner/tableref/bound_joinref.hpp +// duckdb/planner/expression_binder/lateral_binder.hpp // // //===----------------------------------------------------------------------===// @@ -204227,37 +216307,38 @@ unique_ptr Binder::Bind(ExpressionListRef &expr) { - - namespace duckdb { -//! Represents a join -class BoundJoinRef : public BoundTableRef { -public: - BoundJoinRef() : BoundTableRef(TableReferenceType::JOIN) { - } +class ColumnAliasBinder; - //! The binder used to bind the LHS of the join - shared_ptr left_binder; - //! The binder used to bind the RHS of the join - shared_ptr right_binder; - //! The left hand side of the join - unique_ptr left; - //! The right hand side of the join - unique_ptr right; - //! The join condition - unique_ptr condition; - //! The join type - JoinType type; -}; -} // namespace duckdb +//! The LATERAL binder is responsible for binding an expression within a LATERAL join +class LateralBinder : public ExpressionBinder { +public: + LateralBinder(Binder &binder, ClientContext &context); + //! Extract the correlated lateral join columns and remove them from the targeted binder + vector ExtractCorrelatedColumns(Binder &binder); + bool HasCorrelatedColumns() const { + return !correlated_columns.empty(); + } + static void ReduceExpressionDepth(LogicalOperator &op, const vector &info); +protected: + BindResult BindExpression(unique_ptr *expr_ptr, idx_t depth, + bool root_expression = false) override; + string UnsupportedAggregateMessage() override; +private: + BindResult BindColumnRef(unique_ptr *expr_ptr, idx_t depth, bool root_expression); + void ExtractCorrelatedColumns(Expression &expr); +private: + vector correlated_columns; +}; +} // namespace duckdb namespace duckdb { @@ -204267,7 +216348,7 @@ static unique_ptr BindColumn(Binder &binder, ClientContext &co auto expr = make_unique_base(column_name, alias); ExpressionBinder expr_binder(binder, context); auto result = expr_binder.Bind(expr); - return make_unique(move(result)); + return make_unique(std::move(result)); } static unique_ptr AddCondition(ClientContext &context, Binder &left_binder, Binder &right_binder, @@ -204276,7 +216357,7 @@ static unique_ptr AddCondition(ClientContext &context, Binder ExpressionBinder expr_binder(left_binder, context); auto left = BindColumn(left_binder, context, left_alias, column_name); auto right = BindColumn(right_binder, context, right_alias, column_name); - return make_unique(ExpressionType::COMPARE_EQUAL, move(left), move(right)); + return make_unique(ExpressionType::COMPARE_EQUAL, std::move(left), std::move(right)); } bool Binder::TryFindBinding(const string &using_column, const string &join_side, string &result) { @@ -204366,7 +216447,7 @@ static vector RemoveDuplicateUsingColumns(const vector &using_co } unique_ptr Binder::Bind(JoinRef &ref) { - auto result = make_unique(); + auto result = make_unique(ref.ref_type); result->left_binder = Binder::CreateBinder(context, this); result->right_binder = Binder::CreateBinder(context, this); auto &left_binder = *result->left_binder; @@ -204374,11 +216455,23 @@ unique_ptr Binder::Bind(JoinRef &ref) { result->type = ref.type; result->left = left_binder.Bind(*ref.left); - result->right = right_binder.Bind(*ref.right); + { + LateralBinder binder(left_binder, context); + result->right = right_binder.Bind(*ref.right); + result->lateral = binder.HasCorrelatedColumns(); + if (result->lateral) { + // lateral join: can only be an INNER or LEFT join + if (ref.type != JoinType::INNER && ref.type != JoinType::LEFT) { + throw BinderException("The combining JOIN type must be INNER or LEFT for a LATERAL reference"); + } + } + result->correlated_columns = binder.ExtractCorrelatedColumns(right_binder); + } vector> extra_conditions; vector extra_using_columns; - if (ref.is_natural) { + switch (ref.ref_type) { + case JoinRefType::NATURAL: { // natural join, figure out which column names are present in both sides of the join // first bind the left hand side and get a list of all the tables and column names case_insensitive_set_t lhs_columns; @@ -204429,10 +216522,18 @@ unique_ptr Binder::Bind(JoinRef &ref) { error_msg += "\n Right candidates: " + right_candidates; throw BinderException(FormatError(ref, error_msg)); } - } else if (!ref.using_columns.empty()) { - // USING columns - D_ASSERT(!result->condition); - extra_using_columns = ref.using_columns; + break; + } + case JoinRefType::REGULAR: + if (!ref.using_columns.empty()) { + // USING columns + D_ASSERT(!result->condition); + extra_using_columns = ref.using_columns; + } + break; + case JoinRefType::CROSS: + case JoinRefType::POSITIONAL: + break; } extra_using_columns = RemoveDuplicateUsingColumns(extra_using_columns); @@ -204477,28 +216578,27 @@ unique_ptr Binder::Bind(JoinRef &ref) { using_column); bind_context.TransferUsingBinding(right_binder.bind_context, right_using_binding, set.get(), right_binding, using_column); - AddUsingBindingSet(move(set)); + AddUsingBindingSet(std::move(set)); } } - bind_context.AddContext(move(left_binder.bind_context)); - bind_context.AddContext(move(right_binder.bind_context)); + bind_context.AddContext(std::move(left_binder.bind_context)); + bind_context.AddContext(std::move(right_binder.bind_context)); MoveCorrelatedExpressions(left_binder); MoveCorrelatedExpressions(right_binder); for (auto &condition : extra_conditions) { if (ref.condition) { - ref.condition = make_unique(ExpressionType::CONJUNCTION_AND, move(ref.condition), - move(condition)); + ref.condition = make_unique(ExpressionType::CONJUNCTION_AND, + std::move(ref.condition), std::move(condition)); } else { - ref.condition = move(condition); + ref.condition = std::move(condition); } } if (ref.condition) { WhereBinder binder(*this, context); result->condition = binder.Bind(ref.condition); } - D_ASSERT(result->condition); - return move(result); + return std::move(result); } } // namespace duckdb @@ -204557,10 +216657,10 @@ unique_ptr Binder::Bind(SubqueryRef &ref, CommonTableExpressionIn } else { alias = ref.alias; } - auto result = make_unique(move(binder), move(subquery)); + auto result = make_unique(std::move(binder), std::move(subquery)); bind_context.AddSubquery(bind_index, alias, ref, *result->subquery); MoveCorrelatedExpressions(*result->binder); - return move(result); + return std::move(result); } } // namespace duckdb @@ -204596,7 +216696,7 @@ class TableFunctionBinder : public ExpressionBinder { TableFunctionBinder(Binder &binder, ClientContext &context); protected: - BindResult BindColumnReference(ColumnRefExpression &expr); + BindResult BindColumnReference(ColumnRefExpression &expr, idx_t depth); BindResult BindExpression(unique_ptr *expr, idx_t depth, bool root_expression = false) override; string UnsupportedAggregateMessage() override; @@ -204611,6 +216711,8 @@ class TableFunctionBinder : public ExpressionBinder { + + namespace duckdb { static bool IsTableInTableOutFunction(TableFunctionCatalogEntry &table_function) { @@ -204622,20 +216724,22 @@ static bool IsTableInTableOutFunction(TableFunctionCatalogEntry &table_function) bool Binder::BindTableInTableOutFunction(vector> &expressions, unique_ptr &subquery, string &error) { auto binder = Binder::CreateBinder(this->context, this, true); + unique_ptr subquery_node; if (expressions.size() == 1 && expressions[0]->type == ExpressionType::SUBQUERY) { // general case: argument is a subquery, bind it as part of the node auto &se = (SubqueryExpression &)*expressions[0]; - auto node = binder->BindNode(*se.subquery->node); - subquery = make_unique(move(binder), move(node)); - return true; + subquery_node = std::move(se.subquery->node); + } else { + // special case: non-subquery parameter to table-in table-out function + // generate a subquery and bind that (i.e. UNNEST([1,2,3]) becomes UNNEST((SELECT [1,2,3])) + auto select_node = make_unique(); + select_node->select_list = std::move(expressions); + select_node->from_table = make_unique(); + subquery_node = std::move(select_node); } - // special case: non-subquery parameter to table-in table-out function - // generate a subquery and bind that (i.e. UNNEST([1,2,3]) becomes UNNEST((SELECT [1,2,3])) - auto select_node = make_unique(); - select_node->select_list = move(expressions); - select_node->from_table = make_unique(); - auto node = binder->BindNode(*select_node); - subquery = make_unique(move(binder), move(node)); + auto node = binder->BindNode(*subquery_node); + subquery = make_unique(std::move(binder), std::move(node)); + MoveCorrelatedExpressions(*subquery->binder); return true; } @@ -204661,7 +216765,7 @@ bool Binder::BindTableFunctionParameters(TableFunctionCatalogEntry &table_functi auto &colref = (ColumnRefExpression &)*comp.left; if (!colref.IsQualified()) { parameter_name = colref.GetColumnName(); - child = move(comp.right); + child = std::move(comp.right); } } } @@ -204673,7 +216777,7 @@ bool Binder::BindTableFunctionParameters(TableFunctionCatalogEntry &table_functi auto binder = Binder::CreateBinder(this->context, this, true); auto &se = (SubqueryExpression &)*child; auto node = binder->BindNode(*se.subquery->node); - subquery = make_unique(move(binder), move(node)); + subquery = make_unique(std::move(binder), std::move(node)); seen_subquery = true; arguments.emplace_back(LogicalTypeId::TABLE); continue; @@ -204697,9 +216801,9 @@ bool Binder::BindTableFunctionParameters(TableFunctionCatalogEntry &table_functi return false; } arguments.emplace_back(sql_type); - parameters.emplace_back(move(constant)); + parameters.emplace_back(std::move(constant)); } else { - named_parameters[parameter_name] = move(constant); + named_parameters[parameter_name] = std::move(constant); } } return true; @@ -204721,7 +216825,7 @@ Binder::BindTableFunctionInternal(TableFunction &table_function, const string &f bind_data = table_function.bind(context, bind_input, return_types, return_names); if (table_function.name == "pandas_scan" || table_function.name == "arrow_scan") { auto arrow_bind = (PyTableFunctionData *)bind_data.get(); - arrow_bind->external_dependency = move(external_dependency); + arrow_bind->external_dependency = std::move(external_dependency); } } if (return_types.size() != return_names.size()) { @@ -204742,15 +216846,21 @@ Binder::BindTableFunctionInternal(TableFunction &table_function, const string &f return_names[i] = "C" + to_string(i); } } - auto get = make_unique(bind_index, table_function, move(bind_data), return_types, return_names); + auto get = make_unique(bind_index, table_function, std::move(bind_data), return_types, return_names); get->parameters = parameters; get->named_parameters = named_parameters; get->input_table_types = input_table_types; get->input_table_names = input_table_names; + if (table_function.in_out_function && !table_function.projection_pushdown) { + get->column_ids.reserve(return_types.size()); + for (idx_t i = 0; i < return_types.size(); i++) { + get->column_ids.push_back(i); + } + } // now add the table function to the bind context so its columns can be bound bind_context.AddTableFunction(bind_index, function_name, return_names, return_types, get->column_ids, get->GetTable()); - return move(get); + return std::move(get); } unique_ptr Binder::BindTableFunction(TableFunction &function, vector parameters) { @@ -204758,8 +216868,9 @@ unique_ptr Binder::BindTableFunction(TableFunction &function, v vector input_table_types; vector input_table_names; vector column_name_aliases; - return BindTableFunctionInternal(function, function.name, move(parameters), move(named_parameters), - move(input_table_types), move(input_table_names), column_name_aliases, nullptr); + return BindTableFunctionInternal(function, function.name, std::move(parameters), std::move(named_parameters), + std::move(input_table_types), std::move(input_table_names), column_name_aliases, + nullptr); } unique_ptr Binder::Bind(TableFunctionRef &ref) { @@ -204771,10 +216882,8 @@ unique_ptr Binder::Bind(TableFunctionRef &ref) { TableFunctionCatalogEntry *function = nullptr; // fetch the function from the catalog - auto &catalog = Catalog::GetCatalog(context); - - auto func_catalog = catalog.GetEntry(context, CatalogType::TABLE_FUNCTION_ENTRY, fexpr->schema, - fexpr->function_name, false, error_context); + auto func_catalog = Catalog::GetEntry(context, CatalogType::TABLE_FUNCTION_ENTRY, fexpr->catalog, fexpr->schema, + fexpr->function_name, false, error_context); if (func_catalog->type == CatalogType::TABLE_FUNCTION_ENTRY) { function = (TableFunctionCatalogEntry *)func_catalog; @@ -204793,11 +216902,11 @@ unique_ptr Binder::Bind(TableFunctionRef &ref) { // string alias; string alias = (ref.alias.empty() ? "unnamed_query" + to_string(bind_index) : ref.alias); - auto result = make_unique(move(binder), move(query)); + auto result = make_unique(std::move(binder), std::move(query)); // remember ref here is TableFunctionRef and NOT base class bind_context.AddSubquery(bind_index, alias, ref, *result->subquery); MoveCorrelatedExpressions(*result->binder); - return move(result); + return std::move(result); } // evaluate the input parameters to the function @@ -204839,13 +216948,14 @@ unique_ptr Binder::Bind(TableFunctionRef &ref) { input_table_names = subquery->subquery->names; } auto get = BindTableFunctionInternal(table_function, ref.alias.empty() ? fexpr->function_name : ref.alias, - move(parameters), move(named_parameters), move(input_table_types), - move(input_table_names), ref.column_name_alias, move(ref.external_dependency)); + std::move(parameters), std::move(named_parameters), + std::move(input_table_types), std::move(input_table_names), + ref.column_name_alias, std::move(ref.external_dependency)); if (subquery) { get->children.push_back(Binder::CreatePlan(*subquery)); } - return make_unique_base(move(get)); + return make_unique_base(std::move(get)); } } // namespace duckdb @@ -204856,21 +216966,7 @@ unique_ptr Binder::Bind(TableFunctionRef &ref) { namespace duckdb { unique_ptr Binder::CreatePlan(BoundBaseTableRef &ref) { - return move(ref.get); -} - -} // namespace duckdb - - - - -namespace duckdb { - -unique_ptr Binder::CreatePlan(BoundCrossProductRef &expr) { - auto left = CreatePlan(*expr.left); - auto right = CreatePlan(*expr.right); - - return LogicalCrossProduct::Create(move(left), move(right)); + return std::move(ref.get); } } // namespace duckdb @@ -204924,9 +217020,9 @@ unique_ptr Binder::CreatePlan(BoundExpressionListRef &ref) { for (auto &expr : ref.values[0]) { types.push_back(expr->return_type); } - auto expr_get = make_unique(ref.bind_index, types, move(ref.values)); - expr_get->AddChild(move(root)); - return move(expr_get); + auto expr_get = make_unique(ref.bind_index, types, std::move(ref.values)); + expr_get->AddChild(std::move(root)); + return std::move(expr_get); } } // namespace duckdb @@ -204945,11 +217041,13 @@ unique_ptr Binder::CreatePlan(BoundExpressionListRef &ref) { + + namespace duckdb { //! Create a JoinCondition from a comparison -static bool CreateJoinCondition(Expression &expr, unordered_set &left_bindings, - unordered_set &right_bindings, vector &conditions) { +static bool CreateJoinCondition(Expression &expr, const unordered_set &left_bindings, + const unordered_set &right_bindings, vector &conditions) { // comparison auto &comparison = (BoundComparisonExpression &)expr; auto left_side = JoinSide::GetJoinSide(*comparison.left, left_bindings, right_bindings); @@ -204958,29 +217056,28 @@ static bool CreateJoinCondition(Expression &expr, unordered_set &left_bin // join condition can be divided in a left/right side JoinCondition condition; condition.comparison = expr.type; - auto left = move(comparison.left); - auto right = move(comparison.right); + auto left = std::move(comparison.left); + auto right = std::move(comparison.right); if (left_side == JoinSide::RIGHT) { // left = right, right = left, flip the comparison symbol and reverse sides swap(left, right); condition.comparison = FlipComparisionExpression(expr.type); } - condition.left = move(left); - condition.right = move(right); - conditions.push_back(move(condition)); + condition.left = std::move(left); + condition.right = std::move(right); + conditions.push_back(std::move(condition)); return true; } return false; } -unique_ptr LogicalComparisonJoin::CreateJoin(JoinType type, unique_ptr left_child, - unique_ptr right_child, - unordered_set &left_bindings, - unordered_set &right_bindings, - vector> &expressions) { - vector conditions; - vector> arbitrary_expressions; - // first check if we can create +void LogicalComparisonJoin::ExtractJoinConditions(JoinType type, unique_ptr &left_child, + unique_ptr &right_child, + const unordered_set &left_bindings, + const unordered_set &right_bindings, + vector> &expressions, + vector &conditions, + vector> &arbitrary_expressions) { for (auto &expr : expressions) { auto total_side = JoinSide::GetJoinSide(*expr, left_bindings, right_bindings); if (total_side != JoinSide::BOTH) { @@ -204990,12 +217087,12 @@ unique_ptr LogicalComparisonJoin::CreateJoin(JoinType type, uni if (right_child->type != LogicalOperatorType::LOGICAL_FILTER) { // not a filter yet, push a new empty filter auto filter = make_unique(); - filter->AddChild(move(right_child)); - right_child = move(filter); + filter->AddChild(std::move(right_child)); + right_child = std::move(filter); } // push the expression into the filter auto &filter = (LogicalFilter &)*right_child; - filter.expressions.push_back(move(expr)); + filter.expressions.push_back(std::move(expr)); continue; } } else if ((expr->type >= ExpressionType::COMPARE_EQUAL && @@ -205008,8 +217105,37 @@ unique_ptr LogicalComparisonJoin::CreateJoin(JoinType type, uni continue; } } - arbitrary_expressions.push_back(move(expr)); + arbitrary_expressions.push_back(std::move(expr)); } +} + +void LogicalComparisonJoin::ExtractJoinConditions(JoinType type, unique_ptr &left_child, + unique_ptr &right_child, + vector> &expressions, + vector &conditions, + vector> &arbitrary_expressions) { + unordered_set left_bindings, right_bindings; + LogicalJoin::GetTableReferences(*left_child, left_bindings); + LogicalJoin::GetTableReferences(*right_child, right_bindings); + return ExtractJoinConditions(type, left_child, right_child, left_bindings, right_bindings, expressions, conditions, + arbitrary_expressions); +} + +void LogicalComparisonJoin::ExtractJoinConditions(JoinType type, unique_ptr &left_child, + unique_ptr &right_child, + unique_ptr condition, vector &conditions, + vector> &arbitrary_expressions) { + // split the expressions by the AND clause + vector> expressions; + expressions.push_back(std::move(condition)); + LogicalFilter::SplitPredicates(expressions); + return ExtractJoinConditions(type, left_child, right_child, expressions, conditions, arbitrary_expressions); +} + +unique_ptr LogicalComparisonJoin::CreateJoin(JoinType type, unique_ptr left_child, + unique_ptr right_child, + vector conditions, + vector> arbitrary_expressions) { bool need_to_consider_arbitrary_expressions = true; if (type == JoinType::INNER) { // for inner joins we can push arbitrary expressions as a filter @@ -205027,41 +217153,41 @@ unique_ptr LogicalComparisonJoin::CreateJoin(JoinType type, uni arbitrary_expressions.push_back(make_unique(Value::BOOLEAN(true))); } for (auto &condition : conditions) { - arbitrary_expressions.push_back(JoinCondition::CreateExpression(move(condition))); + arbitrary_expressions.push_back(JoinCondition::CreateExpression(std::move(condition))); } // if we get here we could not create any JoinConditions // turn this into an arbitrary expression join auto any_join = make_unique(type); // create the condition - any_join->children.push_back(move(left_child)); - any_join->children.push_back(move(right_child)); + any_join->children.push_back(std::move(left_child)); + any_join->children.push_back(std::move(right_child)); // AND all the arbitrary expressions together // do the same with any remaining conditions - any_join->condition = move(arbitrary_expressions[0]); + any_join->condition = std::move(arbitrary_expressions[0]); for (idx_t i = 1; i < arbitrary_expressions.size(); i++) { any_join->condition = make_unique( - ExpressionType::CONJUNCTION_AND, move(any_join->condition), move(arbitrary_expressions[i])); + ExpressionType::CONJUNCTION_AND, std::move(any_join->condition), std::move(arbitrary_expressions[i])); } - return move(any_join); + return std::move(any_join); } else { // we successfully converted expressions into JoinConditions // create a LogicalComparisonJoin auto comp_join = make_unique(type); - comp_join->conditions = move(conditions); - comp_join->children.push_back(move(left_child)); - comp_join->children.push_back(move(right_child)); + comp_join->conditions = std::move(conditions); + comp_join->children.push_back(std::move(left_child)); + comp_join->children.push_back(std::move(right_child)); if (!arbitrary_expressions.empty()) { // we have some arbitrary expressions as well // add them to a filter auto filter = make_unique(); for (auto &expr : arbitrary_expressions) { - filter->expressions.push_back(move(expr)); + filter->expressions.push_back(std::move(expr)); } LogicalFilter::SplitPredicates(filter->expressions); - filter->children.push_back(move(comp_join)); - return move(filter); + filter->children.push_back(std::move(comp_join)); + return std::move(filter); } - return move(comp_join); + return std::move(comp_join); } } @@ -205081,41 +217207,64 @@ static bool HasCorrelatedColumns(Expression &expression) { return has_correlated_columns; } +unique_ptr LogicalComparisonJoin::CreateJoin(JoinType type, unique_ptr left_child, + unique_ptr right_child, + unique_ptr condition) { + vector conditions; + vector> arbitrary_expressions; + LogicalComparisonJoin::ExtractJoinConditions(type, left_child, right_child, std::move(condition), conditions, + arbitrary_expressions); + return LogicalComparisonJoin::CreateJoin(type, std::move(left_child), std::move(right_child), std::move(conditions), + std::move(arbitrary_expressions)); +} + unique_ptr Binder::CreatePlan(BoundJoinRef &ref) { auto left = CreatePlan(*ref.left); auto right = CreatePlan(*ref.right); + if (!ref.lateral && !ref.correlated_columns.empty()) { + // non-lateral join with correlated columns + // this happens if there is a join (or cross product) in a correlated subquery + // due to the lateral binder the expression depth of all correlated columns in the "ref.correlated_columns" set + // is 1 too high + // we reduce expression depth of all columns in the "ref.correlated_columns" set by 1 + LateralBinder::ReduceExpressionDepth(*right, ref.correlated_columns); + } if (ref.type == JoinType::RIGHT && ClientConfig::GetConfig(context).enable_optimizer) { // we turn any right outer joins into left outer joins for optimization purposes // they are the same but with sides flipped, so treating them the same simplifies life ref.type = JoinType::LEFT; std::swap(left, right); } + if (ref.lateral) { + // lateral join + return PlanLateralJoin(std::move(left), std::move(right), ref.correlated_columns, ref.type, + std::move(ref.condition)); + } + switch (ref.ref_type) { + case JoinRefType::CROSS: + return LogicalCrossProduct::Create(std::move(left), std::move(right)); + case JoinRefType::POSITIONAL: + return LogicalPositionalJoin::Create(std::move(left), std::move(right)); + default: + break; + } if (ref.type == JoinType::INNER && (ref.condition->HasSubquery() || HasCorrelatedColumns(*ref.condition))) { // inner join, generate a cross product + filter // this will be later turned into a proper join by the join order optimizer - auto root = LogicalCrossProduct::Create(move(left), move(right)); + auto root = LogicalCrossProduct::Create(std::move(left), std::move(right)); - auto filter = make_unique(move(ref.condition)); + auto filter = make_unique(std::move(ref.condition)); // visit the expressions in the filter for (auto &expression : filter->expressions) { PlanSubqueries(&expression, &root); } - filter->AddChild(move(root)); - return move(filter); + filter->AddChild(std::move(root)); + return std::move(filter); } - // split the expressions by the AND clause - vector> expressions; - expressions.push_back(move(ref.condition)); - LogicalFilter::SplitPredicates(expressions); - - // find the table bindings on the LHS and RHS of the join - unordered_set left_bindings, right_bindings; - LogicalJoin::GetTableReferences(*left, left_bindings); - LogicalJoin::GetTableReferences(*right, right_bindings); - // now create the join operator from the set of join conditions - auto result = LogicalComparisonJoin::CreateJoin(ref.type, move(left), move(right), left_bindings, right_bindings, - expressions); + // now create the join operator from the join condition + auto result = + LogicalComparisonJoin::CreateJoin(ref.type, std::move(left), std::move(right), std::move(ref.condition)); LogicalOperator *join; if (result->type == LogicalOperatorType::LOGICAL_FILTER) { @@ -205176,7 +217325,7 @@ unique_ptr Binder::CreatePlan(BoundSubqueryRef &ref) { namespace duckdb { unique_ptr Binder::CreatePlan(BoundTableFunction &ref) { - return move(ref.get); + return std::move(ref.get); } } // namespace duckdb @@ -205196,6 +217345,7 @@ unique_ptr Binder::CreatePlan(BoundTableFunction &ref) { + #include namespace duckdb { @@ -205205,7 +217355,7 @@ shared_ptr Binder::CreateBinder(ClientContext &context, Binder *parent, } Binder::Binder(bool, ClientContext &context, shared_ptr parent_p, bool inherit_ctes_p) - : context(context), parent(move(parent_p)), bound_tables(0), inherit_ctes(inherit_ctes_p) { + : context(context), parent(std::move(parent_p)), bound_tables(0), inherit_ctes(inherit_ctes_p) { parameters = nullptr; if (parent) { @@ -205269,6 +217419,8 @@ BoundStatement Binder::Bind(SQLStatement &statement) { return Bind((ExecuteStatement &)statement); case StatementType::LOGICAL_PLAN_STATEMENT: return Bind((LogicalPlanStatement &)statement); + case StatementType::ATTACH_STATEMENT: + return Bind((AttachStatement &)statement); default: // LCOV_EXCL_START throw NotImplementedException("Unimplemented statement type \"%s\" for Bind", StatementTypeToString(statement.type)); @@ -205332,9 +217484,6 @@ unique_ptr Binder::Bind(TableRef &ref) { case TableReferenceType::BASE_TABLE: result = Bind((BaseTableRef &)ref); break; - case TableReferenceType::CROSS_PRODUCT: - result = Bind((CrossProductRef &)ref); - break; case TableReferenceType::JOIN: result = Bind((JoinRef &)ref); break; @@ -205350,10 +217499,11 @@ unique_ptr Binder::Bind(TableRef &ref) { case TableReferenceType::EXPRESSION_LIST: result = Bind((ExpressionListRef &)ref); break; - default: + case TableReferenceType::CTE: + case TableReferenceType::INVALID: throw InternalException("Unknown table ref type"); } - result->sample = move(ref.sample); + result->sample = std::move(ref.sample); return result; } @@ -205369,9 +217519,6 @@ unique_ptr Binder::CreatePlan(BoundTableRef &ref) { case TableReferenceType::JOIN: root = CreatePlan((BoundJoinRef &)ref); break; - case TableReferenceType::CROSS_PRODUCT: - root = CreatePlan((BoundCrossProductRef &)ref); - break; case TableReferenceType::TABLE_FUNCTION: root = CreatePlan((BoundTableFunction &)ref); break; @@ -205384,12 +217531,12 @@ unique_ptr Binder::CreatePlan(BoundTableRef &ref) { case TableReferenceType::CTE: root = CreatePlan((BoundCTERef &)ref); break; - default: - throw InternalException("Unsupported bound table ref type type"); + case TableReferenceType::INVALID: + throw InternalException("Unsupported bound table ref type"); } // plan the sample clause if (ref.sample) { - root = make_unique(move(ref.sample), move(root)); + root = make_unique(std::move(ref.sample), std::move(root)); } return root; } @@ -205441,6 +217588,7 @@ void Binder::AddBoundView(ViewCatalogEntry *view) { } idx_t Binder::GenerateTableIndex() { + D_ASSERT(parent.get() != this); if (parent) { return parent->GenerateTableIndex(); } @@ -205478,10 +217626,10 @@ vector &Binder::GetActiveBinders() { void Binder::AddUsingBindingSet(unique_ptr set) { if (parent) { - parent->AddUsingBindingSet(move(set)); + parent->AddUsingBindingSet(std::move(set)); return; } - bind_context.AddUsingBindingSet(move(set)); + bind_context.AddUsingBindingSet(std::move(set)); } void Binder::MoveCorrelatedExpressions(Binder &other) { @@ -205509,6 +217657,12 @@ bool Binder::HasMatchingBinding(const string &table_name, const string &column_n bool Binder::HasMatchingBinding(const string &schema_name, const string &table_name, const string &column_name, string &error_message) { + string empty_catalog; + return HasMatchingBinding(empty_catalog, schema_name, table_name, column_name, error_message); +} + +bool Binder::HasMatchingBinding(const string &catalog_name, const string &schema_name, const string &table_name, + const string &column_name, string &error_message) { Binding *binding = nullptr; D_ASSERT(!lambda_bindings); if (macro_binding && table_name == macro_binding->alias) { @@ -205520,12 +217674,18 @@ bool Binder::HasMatchingBinding(const string &schema_name, const string &table_n if (!binding) { return false; } - if (!schema_name.empty()) { + if (!catalog_name.empty() || !schema_name.empty()) { auto catalog_entry = binding->GetStandardEntry(); if (!catalog_entry) { return false; } - if (catalog_entry->schema->name != schema_name || catalog_entry->name != table_name) { + if (!catalog_name.empty() && catalog_entry->catalog->GetName() != catalog_name) { + return false; + } + if (!schema_name.empty() && catalog_entry->schema->name != schema_name) { + return false; + } + if (catalog_entry->name != table_name) { return false; } } @@ -205557,10 +217717,10 @@ void Binder::SetCanContainNulls(bool can_contain_nulls_p) { void Binder::AddTableName(string table_name) { if (parent) { - parent->AddTableName(move(table_name)); + parent->AddTableName(std::move(table_name)); return; } - table_names.insert(move(table_name)); + table_names.insert(std::move(table_name)); } const unordered_set &Binder::GetTableNames() { @@ -205583,6 +217743,23 @@ string Binder::FormatErrorRecursive(idx_t query_location, const string &message, return context.FormatErrorRecursive(message, values); } +// FIXME: this is extremely naive +void VerifyNotExcluded(ParsedExpression &expr) { + if (expr.type == ExpressionType::COLUMN_REF) { + auto &column_ref = (ColumnRefExpression &)expr; + if (!column_ref.IsQualified()) { + return; + } + auto &table_name = column_ref.GetTableName(); + if (table_name == "excluded") { + throw NotImplementedException("'excluded' qualified columns are not supported in the RETURNING clause yet"); + } + return; + } + ParsedExpressionIterator::EnumerateChildren( + expr, [&](const ParsedExpression &child) { VerifyNotExcluded((ParsedExpression &)child); }); +} + BoundStatement Binder::BindReturning(vector> returning_list, TableCatalogEntry *table, idx_t update_table_index, unique_ptr child_operator, BoundStatement result) { @@ -205594,7 +217771,7 @@ BoundStatement Binder::BindReturning(vector> return vector bound_columns; idx_t column_count = 0; - for (auto &col : table->columns.Logical()) { + for (auto &col : table->GetColumns().Logical()) { names.push_back(col.Name()); types.push_back(col.Type()); if (!col.Generated()) { @@ -205603,7 +217780,7 @@ BoundStatement Binder::BindReturning(vector> return column_count++; } - binder->bind_context.AddBaseTable(update_table_index, table->name, names, types, bound_columns, table); + binder->bind_context.AddBaseTable(update_table_index, table->name, names, types, bound_columns, table, false); ReturningBinder returning_binder(*binder, context); vector> projection_expressions; @@ -205618,20 +217795,22 @@ BoundStatement Binder::BindReturning(vector> return auto star_expr = returning_binder.Bind(star_column, &result_type); result.types.push_back(result_type); result.names.push_back(star_expr->GetName()); - projection_expressions.push_back(move(star_expr)); + projection_expressions.push_back(std::move(star_expr)); } } else { + // TODO: accept 'excluded' in the RETURNING clause + VerifyNotExcluded(*returning_expr); auto expr = returning_binder.Bind(returning_expr, &result_type); result.names.push_back(expr->GetName()); result.types.push_back(result_type); - projection_expressions.push_back(move(expr)); + projection_expressions.push_back(std::move(expr)); } } - auto projection = make_unique(GenerateTableIndex(), move(projection_expressions)); - projection->AddChild(move(child_operator)); + auto projection = make_unique(GenerateTableIndex(), std::move(projection_expressions)); + projection->AddChild(std::move(child_operator)); D_ASSERT(result.types.size() == result.names.size()); - result.plan = move(projection); + result.plan = std::move(projection); properties.allow_stream_result = true; properties.return_type = StatementReturnType::QUERY_RESULT; return result; @@ -205650,11 +217829,11 @@ BoundResultModifier::~BoundResultModifier() { } BoundOrderByNode::BoundOrderByNode(OrderType type, OrderByNullType null_order, unique_ptr expression) - : type(type), null_order(null_order), expression(move(expression)) { + : type(type), null_order(null_order), expression(std::move(expression)) { } BoundOrderByNode::BoundOrderByNode(OrderType type, OrderByNullType null_order, unique_ptr expression, unique_ptr stats) - : type(type), null_order(null_order), expression(move(expression)), stats(move(stats)) { + : type(type), null_order(null_order), expression(std::move(expression)), stats(std::move(stats)) { } BoundOrderByNode BoundOrderByNode::Copy() const { @@ -205665,6 +217844,17 @@ BoundOrderByNode BoundOrderByNode::Copy() const { } } +bool BoundOrderByNode::Equals(const BoundOrderByNode &other) const { + if (type != other.type || null_order != other.null_order) { + return false; + } + if (!expression->Equals(other.expression.get())) { + return false; + } + + return true; +} + string BoundOrderByNode::ToString() const { auto str = expression->ToString(); switch (type) { @@ -205706,7 +217896,7 @@ BoundOrderByNode BoundOrderByNode::Deserialize(Deserializer &source, PlanDeseria auto null_order = reader.ReadRequired(); auto expression = reader.ReadRequiredSerializable(state); reader.Finalize(); - return BoundOrderByNode(type, null_order, move(expression)); + return BoundOrderByNode(type, null_order, std::move(expression)); } BoundLimitModifier::BoundLimitModifier() : BoundResultModifier(ResultModifierType::LIMIT_MODIFIER) { @@ -205779,8 +217969,7 @@ class FunctionSerializer { // note: original_arguments are optional (can be list of size 0) auto original_arguments = reader.ReadRequiredSerializableList(); - auto &catalog = Catalog::GetCatalog(context); - auto func_catalog = catalog.GetEntry(context, type, DEFAULT_SCHEMA, name); + auto func_catalog = Catalog::GetEntry(context, type, SYSTEM_CATALOG, DEFAULT_SCHEMA, name); if (!func_catalog || func_catalog->type != type) { throw InternalException("Cant find catalog entry for function %s", name); } @@ -205788,8 +217977,8 @@ class FunctionSerializer { auto functions = (CATALOG_ENTRY *)func_catalog; auto function = functions->functions.GetFunctionByArguments( state.context, original_arguments.empty() ? arguments : original_arguments); - function.arguments = move(arguments); - function.original_arguments = move(original_arguments); + function.arguments = std::move(arguments); + function.original_arguments = std::move(original_arguments); has_deserialize = reader.ReadRequired(); if (has_deserialize) { @@ -205839,8 +218028,8 @@ BoundAggregateExpression::BoundAggregateExpression(AggregateFunction function, v unique_ptr filter, unique_ptr bind_info, AggregateType aggr_type) : Expression(ExpressionType::BOUND_AGGREGATE, ExpressionClass::BOUND_AGGREGATE, function.return_type), - function(move(function)), children(move(children)), bind_info(move(bind_info)), aggr_type(aggr_type), - filter(move(filter)) { + function(std::move(function)), children(std::move(children)), bind_info(std::move(bind_info)), + aggr_type(aggr_type), filter(std::move(filter)) { D_ASSERT(!function.name.empty()); } @@ -205891,15 +218080,16 @@ bool BoundAggregateExpression::PropagatesNullValues() const { unique_ptr BoundAggregateExpression::Copy() { vector> new_children; + new_children.reserve(children.size()); for (auto &child : children) { new_children.push_back(child->Copy()); } auto new_bind_info = bind_info ? bind_info->Copy() : nullptr; auto new_filter = filter ? filter->Copy() : nullptr; - auto copy = make_unique(function, move(new_children), move(new_filter), - move(new_bind_info), aggr_type); + auto copy = make_unique(function, std::move(new_children), std::move(new_filter), + std::move(new_bind_info), aggr_type); copy->CopyProperties(*this); - return move(copy); + return std::move(copy); } void BoundAggregateExpression::Serialize(FieldWriter &writer) const { @@ -205917,7 +218107,7 @@ unique_ptr BoundAggregateExpression::Deserialize(ExpressionDeseriali auto function = FunctionSerializer::Deserialize( reader, state, CatalogType::AGGREGATE_FUNCTION_ENTRY, children, bind_info); - return make_unique(function, move(children), move(filter), move(bind_info), + return make_unique(function, std::move(children), std::move(filter), std::move(bind_info), distinct ? AggregateType::DISTINCT : AggregateType::NON_DISTINCT); } @@ -205931,7 +218121,7 @@ namespace duckdb { BoundBetweenExpression::BoundBetweenExpression(unique_ptr input, unique_ptr lower, unique_ptr upper, bool lower_inclusive, bool upper_inclusive) : Expression(ExpressionType::COMPARE_BETWEEN, ExpressionClass::BOUND_BETWEEN, LogicalType::BOOLEAN), - input(move(input)), lower(move(lower)), upper(move(upper)), lower_inclusive(lower_inclusive), + input(std::move(input)), lower(std::move(lower)), upper(std::move(upper)), lower_inclusive(lower_inclusive), upper_inclusive(upper_inclusive) { } @@ -205960,7 +218150,7 @@ unique_ptr BoundBetweenExpression::Copy() { auto copy = make_unique(input->Copy(), lower->Copy(), upper->Copy(), lower_inclusive, upper_inclusive); copy->CopyProperties(*this); - return move(copy); + return std::move(copy); } void BoundBetweenExpression::Serialize(FieldWriter &writer) const { @@ -205977,7 +218167,8 @@ unique_ptr BoundBetweenExpression::Deserialize(ExpressionDeserializa auto upper = reader.ReadOptional(nullptr, state.gstate); auto lower_inclusive = reader.ReadRequired(); auto upper_inclusive = reader.ReadRequired(); - return make_unique(move(input), move(lower), move(upper), lower_inclusive, upper_inclusive); + return make_unique(std::move(input), std::move(lower), std::move(upper), lower_inclusive, + upper_inclusive); } } // namespace duckdb @@ -205988,17 +218179,17 @@ unique_ptr BoundBetweenExpression::Deserialize(ExpressionDeserializa namespace duckdb { BoundCaseExpression::BoundCaseExpression(LogicalType type) - : Expression(ExpressionType::CASE_EXPR, ExpressionClass::BOUND_CASE, move(type)) { + : Expression(ExpressionType::CASE_EXPR, ExpressionClass::BOUND_CASE, std::move(type)) { } BoundCaseExpression::BoundCaseExpression(unique_ptr when_expr, unique_ptr then_expr, unique_ptr else_expr_p) : Expression(ExpressionType::CASE_EXPR, ExpressionClass::BOUND_CASE, then_expr->return_type), - else_expr(move(else_expr_p)) { + else_expr(std::move(else_expr_p)) { BoundCaseCheck check; - check.when_expr = move(when_expr); - check.then_expr = move(then_expr); - case_checks.push_back(move(check)); + check.when_expr = std::move(when_expr); + check.then_expr = std::move(then_expr); + case_checks.push_back(std::move(check)); } string BoundCaseExpression::ToString() const { @@ -206033,12 +218224,12 @@ unique_ptr BoundCaseExpression::Copy() { BoundCaseCheck new_check; new_check.when_expr = check.when_expr->Copy(); new_check.then_expr = check.then_expr->Copy(); - new_case->case_checks.push_back(move(new_check)); + new_case->case_checks.push_back(std::move(new_check)); } new_case->else_expr = else_expr->Copy(); new_case->CopyProperties(*this); - return move(new_case); + return std::move(new_case); } void BoundCaseCheck::Serialize(Serializer &serializer) const { @@ -206054,8 +218245,8 @@ BoundCaseCheck BoundCaseCheck::Deserialize(Deserializer &source, PlanDeserializa auto then_expr = reader.ReadRequiredSerializable(state); reader.Finalize(); BoundCaseCheck result; - result.when_expr = move(when_expr); - result.then_expr = move(then_expr); + result.when_expr = std::move(when_expr); + result.then_expr = std::move(then_expr); return result; } @@ -206071,9 +218262,9 @@ unique_ptr BoundCaseExpression::Deserialize(ExpressionDeserializatio auto else_expr = reader.ReadRequiredSerializable(state.gstate); auto result = make_unique(return_type); - result->else_expr = move(else_expr); - result->case_checks = move(case_checks); - return move(result); + result->else_expr = std::move(else_expr); + result->case_checks = std::move(case_checks); + return std::move(result); } } // namespace duckdb @@ -206089,8 +218280,8 @@ namespace duckdb { BoundCastExpression::BoundCastExpression(unique_ptr child_p, LogicalType target_type_p, BoundCastInfo bound_cast_p, bool try_cast_p) - : Expression(ExpressionType::OPERATOR_CAST, ExpressionClass::BOUND_CAST, move(target_type_p)), child(move(child_p)), - try_cast(try_cast_p), bound_cast(move(bound_cast_p)) { + : Expression(ExpressionType::OPERATOR_CAST, ExpressionClass::BOUND_CAST, std::move(target_type_p)), + child(std::move(child_p)), try_cast(try_cast_p), bound_cast(std::move(bound_cast_p)) { } unique_ptr AddCastExpressionInternal(unique_ptr expr, const LogicalType &target_type, @@ -206106,7 +218297,7 @@ unique_ptr AddCastExpressionInternal(unique_ptr expr, co return expr; } } - return make_unique(move(expr), target_type, move(bound_cast), try_cast); + return make_unique(std::move(expr), target_type, std::move(bound_cast), try_cast); } static BoundCastInfo BindCastFunction(ClientContext &context, const LogicalType &source, const LogicalType &target) { @@ -206158,21 +218349,21 @@ unique_ptr AddCastToTypeInternal(unique_ptr expr, const } auto cast_function = cast_functions.GetCastFunction(expr->return_type, target_type, get_input); - return AddCastExpressionInternal(move(expr), target_type, move(cast_function), try_cast); + return AddCastExpressionInternal(std::move(expr), target_type, std::move(cast_function), try_cast); } unique_ptr BoundCastExpression::AddDefaultCastToType(unique_ptr expr, const LogicalType &target_type, bool try_cast) { CastFunctionSet default_set; GetCastFunctionInput get_input; - return AddCastToTypeInternal(move(expr), target_type, default_set, get_input, try_cast); + return AddCastToTypeInternal(std::move(expr), target_type, default_set, get_input, try_cast); } unique_ptr BoundCastExpression::AddCastToType(ClientContext &context, unique_ptr expr, const LogicalType &target_type, bool try_cast) { auto &cast_functions = DBConfig::GetConfig(context).GetCastFunctions(); GetCastFunctionInput get_input(context); - return AddCastToTypeInternal(move(expr), target_type, cast_functions, get_input, try_cast); + return AddCastToTypeInternal(std::move(expr), target_type, cast_functions, get_input, try_cast); } bool BoundCastExpression::CastIsInvertible(const LogicalType &source_type, const LogicalType &target_type) { @@ -206265,7 +218456,7 @@ bool BoundCastExpression::Equals(const BaseExpression *other_p) const { unique_ptr BoundCastExpression::Copy() { auto copy = make_unique(child->Copy(), return_type, bound_cast.Copy(), try_cast); copy->CopyProperties(*this); - return move(copy); + return std::move(copy); } void BoundCastExpression::Serialize(FieldWriter &writer) const { @@ -206279,7 +218470,8 @@ unique_ptr BoundCastExpression::Deserialize(ExpressionDeserializatio auto target_type = reader.ReadRequiredSerializable(); auto try_cast = reader.ReadRequired(); auto cast_function = BindCastFunction(state.gstate.context, child->return_type, target_type); - return make_unique(move(child), move(target_type), move(cast_function), try_cast); + return make_unique(std::move(child), std::move(target_type), std::move(cast_function), + try_cast); } } // namespace duckdb @@ -206292,13 +218484,13 @@ unique_ptr BoundCastExpression::Deserialize(ExpressionDeserializatio namespace duckdb { BoundColumnRefExpression::BoundColumnRefExpression(string alias_p, LogicalType type, ColumnBinding binding, idx_t depth) - : Expression(ExpressionType::BOUND_COLUMN_REF, ExpressionClass::BOUND_COLUMN_REF, move(type)), binding(binding), - depth(depth) { - this->alias = move(alias_p); + : Expression(ExpressionType::BOUND_COLUMN_REF, ExpressionClass::BOUND_COLUMN_REF, std::move(type)), + binding(binding), depth(depth) { + this->alias = std::move(alias_p); } BoundColumnRefExpression::BoundColumnRefExpression(LogicalType type, ColumnBinding binding, idx_t depth) - : BoundColumnRefExpression(string(), move(type), binding, depth) { + : BoundColumnRefExpression(string(), std::move(type), binding, depth) { } unique_ptr BoundColumnRefExpression::Copy() { @@ -206355,7 +218547,8 @@ namespace duckdb { BoundComparisonExpression::BoundComparisonExpression(ExpressionType type, unique_ptr left, unique_ptr right) - : Expression(type, ExpressionClass::BOUND_COMPARISON, LogicalType::BOOLEAN), left(move(left)), right(move(right)) { + : Expression(type, ExpressionClass::BOUND_COMPARISON, LogicalType::BOOLEAN), left(std::move(left)), + right(std::move(right)) { } string BoundComparisonExpression::ToString() const { @@ -206380,7 +218573,7 @@ bool BoundComparisonExpression::Equals(const BaseExpression *other_p) const { unique_ptr BoundComparisonExpression::Copy() { auto copy = make_unique(type, left->Copy(), right->Copy()); copy->CopyProperties(*this); - return move(copy); + return std::move(copy); } void BoundComparisonExpression::Serialize(FieldWriter &writer) const { @@ -206392,7 +218585,7 @@ unique_ptr BoundComparisonExpression::Deserialize(ExpressionDeserial FieldReader &reader) { auto left = reader.ReadOptional(nullptr, state.gstate); auto right = reader.ReadOptional(nullptr, state.gstate); - return make_unique(state.type, move(left), move(right)); + return make_unique(state.type, std::move(left), std::move(right)); } } // namespace duckdb @@ -206410,8 +218603,8 @@ BoundConjunctionExpression::BoundConjunctionExpression(ExpressionType type) BoundConjunctionExpression::BoundConjunctionExpression(ExpressionType type, unique_ptr left, unique_ptr right) : BoundConjunctionExpression(type) { - children.push_back(move(left)); - children.push_back(move(right)); + children.push_back(std::move(left)); + children.push_back(std::move(right)); } string BoundConjunctionExpression::ToString() const { @@ -206436,7 +218629,7 @@ unique_ptr BoundConjunctionExpression::Copy() { copy->children.push_back(expr->Copy()); } copy->CopyProperties(*this); - return move(copy); + return std::move(copy); } void BoundConjunctionExpression::Serialize(FieldWriter &writer) const { @@ -206447,8 +218640,8 @@ unique_ptr BoundConjunctionExpression::Deserialize(ExpressionDeseria FieldReader &reader) { auto children = reader.ReadRequiredSerializableList(state.gstate); auto res = make_unique(state.type); - res->children = move(children); - return move(res); + res->children = std::move(children); + return std::move(res); } } // namespace duckdb @@ -206461,7 +218654,7 @@ namespace duckdb { BoundConstantExpression::BoundConstantExpression(Value value_p) : Expression(ExpressionType::VALUE_CONSTANT, ExpressionClass::BOUND_CONSTANT, value_p.type()), - value(move(value_p)) { + value(std::move(value_p)) { } string BoundConstantExpression::ToString() const { @@ -206484,7 +218677,7 @@ hash_t BoundConstantExpression::Hash() const { unique_ptr BoundConstantExpression::Copy() { auto copy = make_unique(value); copy->CopyProperties(*this); - return move(copy); + return std::move(copy); } void BoundConstantExpression::Serialize(FieldWriter &writer) const { @@ -206513,7 +218706,7 @@ void BoundDefaultExpression::Serialize(FieldWriter &writer) const { namespace duckdb { BoundExpression::BoundExpression(unique_ptr expr) - : ParsedExpression(ExpressionType::INVALID, ExpressionClass::BOUND_EXPRESSION), expr(move(expr)) { + : ParsedExpression(ExpressionType::INVALID, ExpressionClass::BOUND_EXPRESSION), expr(std::move(expr)) { } string BoundExpression::ToString() const { @@ -206551,8 +218744,9 @@ namespace duckdb { BoundFunctionExpression::BoundFunctionExpression(LogicalType return_type, ScalarFunction bound_function, vector> arguments, unique_ptr bind_info, bool is_operator) - : Expression(ExpressionType::BOUND_FUNCTION, ExpressionClass::BOUND_FUNCTION, move(return_type)), - function(move(bound_function)), children(move(arguments)), bind_info(move(bind_info)), is_operator(is_operator) { + : Expression(ExpressionType::BOUND_FUNCTION, ExpressionClass::BOUND_FUNCTION, std::move(return_type)), + function(std::move(bound_function)), children(std::move(arguments)), bind_info(std::move(bind_info)), + is_operator(is_operator) { D_ASSERT(!function.name.empty()); } @@ -206598,15 +218792,16 @@ bool BoundFunctionExpression::Equals(const BaseExpression *other_p) const { unique_ptr BoundFunctionExpression::Copy() { vector> new_children; + new_children.reserve(children.size()); for (auto &child : children) { new_children.push_back(child->Copy()); } unique_ptr new_bind_info = bind_info ? bind_info->Copy() : nullptr; - auto copy = make_unique(return_type, function, move(new_children), move(new_bind_info), - is_operator); + auto copy = make_unique(return_type, function, std::move(new_children), + std::move(new_bind_info), is_operator); copy->CopyProperties(*this); - return move(copy); + return std::move(copy); } void BoundFunctionExpression::Verify() const { @@ -206629,8 +218824,8 @@ unique_ptr BoundFunctionExpression::Deserialize(ExpressionDeserializ reader, state, CatalogType::SCALAR_FUNCTION_ENTRY, children, bind_info); auto return_type = function.return_type; - return make_unique(move(return_type), move(function), move(children), move(bind_info), - is_operator); + return make_unique(std::move(return_type), std::move(function), std::move(children), + std::move(bind_info), is_operator); } } // namespace duckdb @@ -206641,8 +218836,8 @@ namespace duckdb { BoundLambdaExpression::BoundLambdaExpression(ExpressionType type_p, LogicalType return_type_p, unique_ptr lambda_expr_p, idx_t parameter_count_p) - : Expression(type_p, ExpressionClass::BOUND_LAMBDA, move(return_type_p)), lambda_expr(move(lambda_expr_p)), - parameter_count(parameter_count_p) { + : Expression(type_p, ExpressionClass::BOUND_LAMBDA, std::move(return_type_p)), + lambda_expr(std::move(lambda_expr_p)), parameter_count(parameter_count_p) { } string BoundLambdaExpression::ToString() const { @@ -206671,7 +218866,7 @@ unique_ptr BoundLambdaExpression::Copy() { for (auto &capture : captures) { copy->captures.push_back(capture->Copy()); } - return move(copy); + return std::move(copy); } void BoundLambdaExpression::Serialize(FieldWriter &writer) const { @@ -206685,10 +218880,81 @@ void BoundLambdaExpression::Serialize(FieldWriter &writer) const { +namespace duckdb { + +BoundLambdaRefExpression::BoundLambdaRefExpression(string alias_p, LogicalType type, ColumnBinding binding, + idx_t lambda_index, idx_t depth) + : Expression(ExpressionType::BOUND_LAMBDA_REF, ExpressionClass::BOUND_LAMBDA_REF, std::move(type)), + binding(binding), lambda_index(lambda_index), depth(depth) { + this->alias = std::move(alias_p); +} + +BoundLambdaRefExpression::BoundLambdaRefExpression(LogicalType type, ColumnBinding binding, idx_t lambda_index, + idx_t depth) + : BoundLambdaRefExpression(string(), std::move(type), binding, lambda_index, depth) { +} + +unique_ptr BoundLambdaRefExpression::Copy() { + return make_unique(alias, return_type, binding, lambda_index, depth); +} + +hash_t BoundLambdaRefExpression::Hash() const { + auto result = Expression::Hash(); + result = CombineHash(result, duckdb::Hash(lambda_index)); + result = CombineHash(result, duckdb::Hash(binding.column_index)); + result = CombineHash(result, duckdb::Hash(binding.table_index)); + return CombineHash(result, duckdb::Hash(depth)); +} + +bool BoundLambdaRefExpression::Equals(const BaseExpression *other_p) const { + if (!Expression::Equals(other_p)) { + return false; + } + auto other = (BoundLambdaRefExpression *)other_p; + return other->binding == binding && other->lambda_index == lambda_index && other->depth == depth; +} + +string BoundLambdaRefExpression::ToString() const { + if (!alias.empty()) { + return alias; + } + return "#[" + to_string(binding.table_index) + "." + to_string(binding.column_index) + "." + + to_string(lambda_index) + "]"; +} + +void BoundLambdaRefExpression::Serialize(FieldWriter &writer) const { + writer.WriteString(alias); + writer.WriteSerializable(return_type); + writer.WriteField(lambda_index); + writer.WriteField(binding.table_index); + writer.WriteField(binding.column_index); + writer.WriteField(depth); +} + +unique_ptr BoundLambdaRefExpression::Deserialize(ExpressionDeserializationState &state, + FieldReader &reader) { + auto alias = reader.ReadRequired(); + auto return_type = reader.ReadRequiredSerializable(); + auto lambda_index = reader.ReadRequired(); + auto table_index = reader.ReadRequired(); + auto column_index = reader.ReadRequired(); + auto depth = reader.ReadRequired(); + + return make_unique(alias, return_type, ColumnBinding(table_index, column_index), + lambda_index, depth); +} + +} // namespace duckdb + + + + + + namespace duckdb { BoundOperatorExpression::BoundOperatorExpression(ExpressionType type, LogicalType return_type) - : Expression(type, ExpressionClass::BOUND_OPERATOR, move(return_type)) { + : Expression(type, ExpressionClass::BOUND_OPERATOR, std::move(return_type)) { } string BoundOperatorExpression::ToString() const { @@ -206712,7 +218978,7 @@ unique_ptr BoundOperatorExpression::Copy() { for (auto &child : children) { copy->children.push_back(child->Copy()); } - return move(copy); + return std::move(copy); } void BoundOperatorExpression::Serialize(FieldWriter &writer) const { @@ -206726,8 +218992,8 @@ unique_ptr BoundOperatorExpression::Deserialize(ExpressionDeserializ auto children = reader.ReadRequiredSerializableList(state.gstate); auto result = make_unique(state.type, return_type); - result->children = move(children); - return move(result); + result->children = std::move(children); + return std::move(result); } } // namespace duckdb @@ -206795,7 +219061,7 @@ unique_ptr BoundParameterExpression::Copy() { result->parameter_data = parameter_data; result->return_type = return_type; result->CopyProperties(*this); - return move(result); + return std::move(result); } void BoundParameterExpression::Serialize(FieldWriter &writer) const { @@ -206820,8 +219086,8 @@ unique_ptr BoundParameterExpression::Deserialize(ExpressionDeseriali // we have! use the previously deserialized entry parameter_data = entry->second; } - result->parameter_data = move(parameter_data); - return move(result); + result->parameter_data = std::move(parameter_data); + return std::move(result); } } // namespace duckdb @@ -206835,11 +219101,11 @@ unique_ptr BoundParameterExpression::Deserialize(ExpressionDeseriali namespace duckdb { BoundReferenceExpression::BoundReferenceExpression(string alias, LogicalType type, idx_t index) - : Expression(ExpressionType::BOUND_REF, ExpressionClass::BOUND_REF, move(type)), index(index) { - this->alias = move(alias); + : Expression(ExpressionType::BOUND_REF, ExpressionClass::BOUND_REF, std::move(type)), index(index) { + this->alias = std::move(alias); } BoundReferenceExpression::BoundReferenceExpression(LogicalType type, idx_t index) - : BoundReferenceExpression(string(), move(type), index) { + : BoundReferenceExpression(string(), std::move(type), index) { } string BoundReferenceExpression::ToString() const { @@ -206887,7 +219153,7 @@ unique_ptr BoundReferenceExpression::Deserialize(ExpressionDeseriali namespace duckdb { BoundSubqueryExpression::BoundSubqueryExpression(LogicalType return_type) - : Expression(ExpressionType::SUBQUERY, ExpressionClass::BOUND_SUBQUERY, move(return_type)) { + : Expression(ExpressionType::SUBQUERY, ExpressionClass::BOUND_SUBQUERY, std::move(return_type)) { } string BoundSubqueryExpression::ToString() const { @@ -206922,7 +219188,7 @@ void BoundSubqueryExpression::Serialize(FieldWriter &writer) const { namespace duckdb { BoundUnnestExpression::BoundUnnestExpression(LogicalType return_type) - : Expression(ExpressionType::BOUND_UNNEST, ExpressionClass::BOUND_UNNEST, move(return_type)) { + : Expression(ExpressionType::BOUND_UNNEST, ExpressionClass::BOUND_UNNEST, std::move(return_type)) { } bool BoundUnnestExpression::IsFoldable() const { @@ -206952,7 +219218,7 @@ bool BoundUnnestExpression::Equals(const BaseExpression *other_p) const { unique_ptr BoundUnnestExpression::Copy() { auto copy = make_unique(return_type); copy->child = child->Copy(); - return move(copy); + return std::move(copy); } void BoundUnnestExpression::Serialize(FieldWriter &writer) const { @@ -206965,8 +219231,8 @@ unique_ptr BoundUnnestExpression::Deserialize(ExpressionDeserializat auto child = reader.ReadRequiredSerializable(state.gstate); auto result = make_unique(return_type); - result->child = move(child); - return move(result); + result->child = std::move(child); + return std::move(result); } } // namespace duckdb @@ -206983,8 +219249,8 @@ namespace duckdb { BoundWindowExpression::BoundWindowExpression(ExpressionType type, LogicalType return_type, unique_ptr aggregate, unique_ptr bind_info) - : Expression(type, ExpressionClass::BOUND_WINDOW, move(return_type)), aggregate(move(aggregate)), - bind_info(move(bind_info)), ignore_nulls(false) { + : Expression(type, ExpressionClass::BOUND_WINDOW, std::move(return_type)), aggregate(std::move(aggregate)), + bind_info(std::move(bind_info)), ignore_nulls(false) { } string BoundWindowExpression::ToString() const { @@ -207093,7 +219359,7 @@ unique_ptr BoundWindowExpression::Copy() { new_window->default_expr = default_expr ? default_expr->Copy() : nullptr; new_window->ignore_nulls = ignore_nulls; - return move(new_window); + return std::move(new_window); } void BoundWindowExpression::Serialize(FieldWriter &writer) const { @@ -207128,13 +219394,14 @@ unique_ptr BoundWindowExpression::Deserialize(ExpressionDeserializat if (has_aggregate) { auto aggr_function = FunctionSerializer::Deserialize( reader, state, CatalogType::AGGREGATE_FUNCTION_ENTRY, children, bind_info); - aggregate = make_unique(move(aggr_function)); + aggregate = make_unique(std::move(aggr_function)); return_type = aggregate->return_type; } else { children = reader.ReadRequiredSerializableList(state.gstate); return_type = reader.ReadRequiredSerializable(); } - auto result = make_unique(state.type, return_type, move(aggregate), move(bind_info)); + auto result = + make_unique(state.type, return_type, std::move(aggregate), std::move(bind_info)); result->partitions = reader.ReadRequiredSerializableList(state.gstate); result->orders = reader.ReadRequiredSerializableList(state.gstate); @@ -207146,8 +219413,8 @@ unique_ptr BoundWindowExpression::Deserialize(ExpressionDeserializat result->end_expr = reader.ReadOptional(nullptr, state.gstate); result->offset_expr = reader.ReadOptional(nullptr, state.gstate); result->default_expr = reader.ReadOptional(nullptr, state.gstate); - result->children = move(children); - return move(result); + result->children = std::move(children); + return std::move(result); } } // namespace duckdb @@ -207163,7 +219430,7 @@ unique_ptr BoundWindowExpression::Deserialize(ExpressionDeserializat namespace duckdb { Expression::Expression(ExpressionType type, ExpressionClass expression_class, LogicalType return_type) - : BaseExpression(type, expression_class), return_type(move(return_type)) { + : BaseExpression(type, expression_class), return_type(std::move(return_type)) { } Expression::~Expression() { @@ -207352,7 +219619,7 @@ namespace duckdb { AlterBinder::AlterBinder(Binder &binder, ClientContext &context, TableCatalogEntry &table, vector &bound_columns, LogicalType target_type) : ExpressionBinder(binder, context), table(table), bound_columns(bound_columns) { - this->target_type = move(target_type); + this->target_type = std::move(target_type); } BindResult AlterBinder::BindExpression(unique_ptr *expr_ptr, idx_t depth, bool root_expression) { @@ -207382,12 +219649,11 @@ BindResult AlterBinder::BindColumn(ColumnRefExpression &colref) { throw BinderException("Table does not contain column %s referenced in alter statement!", colref.column_names[0]); } - if (table.columns.GetColumn(LogicalIndex(idx)).Generated()) { + if (table.GetColumn(idx).Generated()) { throw BinderException("Using generated columns in alter statement not supported"); } bound_columns.push_back(idx); - return BindResult( - make_unique(table.columns.GetColumn(idx).Type(), bound_columns.size() - 1)); + return BindResult(make_unique(table.GetColumn(idx).Type(), bound_columns.size() - 1)); } } // namespace duckdb @@ -207396,11 +219662,12 @@ BindResult AlterBinder::BindColumn(ColumnRefExpression &colref) { + namespace duckdb { CheckBinder::CheckBinder(Binder &binder, ClientContext &context, string table_p, const ColumnList &columns, physical_index_set_t &bound_columns) - : ExpressionBinder(binder, context), table(move(table_p)), columns(columns), bound_columns(bound_columns) { + : ExpressionBinder(binder, context), table(std::move(table_p)), columns(columns), bound_columns(bound_columns) { target_type = LogicalType::INTEGER; } @@ -207429,12 +219696,25 @@ BindResult ExpressionBinder::BindQualifiedColumnName(ColumnRefExpression &colref } auto result = make_unique_base(colref.column_names.back()); for (idx_t i = struct_start; i + 1 < colref.column_names.size(); i++) { - result = CreateStructExtract(move(result), colref.column_names[i]); + result = CreateStructExtract(std::move(result), colref.column_names[i]); } return BindExpression(&result, 0); } BindResult CheckBinder::BindCheckColumn(ColumnRefExpression &colref) { + + // if this is a lambda parameters, then we temporarily add a BoundLambdaRef, + // which we capture and remove later + if (lambda_bindings) { + for (idx_t i = 0; i < lambda_bindings->size(); i++) { + if (colref.GetColumnName() == (*lambda_bindings)[i].dummy_name) { + // FIXME: support lambdas in CHECK constraints + // FIXME: like so: return (*lambda_bindings)[i].Bind(colref, i, depth); + throw NotImplementedException("Lambda functions are currently not supported in CHECK constraints."); + } + } + } + if (colref.column_names.size() > 1) { return BindQualifiedColumnName(colref, table); } @@ -207459,10 +219739,12 @@ BindResult CheckBinder::BindCheckColumn(ColumnRefExpression &colref) { + + namespace duckdb { ColumnAliasBinder::ColumnAliasBinder(BoundSelectNode &node, const case_insensitive_map_t &alias_map) - : node(node), alias_map(alias_map), in_alias(false) { + : node(node), alias_map(alias_map), visited_select_indexes() { } BindResult ColumnAliasBinder::BindAlias(ExpressionBinder &enclosing_binder, ColumnRefExpression &expr, idx_t depth, @@ -207476,18 +219758,18 @@ BindResult ColumnAliasBinder::BindAlias(ExpressionBinder &enclosing_binder, Colu return BindResult(StringUtil::Format("Alias %s is not found.", expr.ToString())); } - if (in_alias) { + if (visited_select_indexes.find(alias_entry->second) != visited_select_indexes.end()) { return BindResult("Cannot resolve self-referential alias"); } // found an alias: bind the alias expression auto expression = node.original_expressions[alias_entry->second]->Copy(); - in_alias = true; + visited_select_indexes.insert(alias_entry->second); // since the alias has been found, pass a depth of 0. See Issue 4978 (#16) // ColumnAliasBinders are only in Having, Qualify and Where Binders auto result = enclosing_binder.BindExpression(&expression, 0, root_expression); - in_alias = false; + visited_select_indexes.erase(alias_entry->second); return result; } @@ -207497,7 +219779,7 @@ BindResult ColumnAliasBinder::BindAlias(ExpressionBinder &enclosing_binder, Colu namespace duckdb { ConstantBinder::ConstantBinder(Binder &binder, ClientContext &context, string clause) - : ExpressionBinder(binder, context), clause(move(clause)) { + : ExpressionBinder(binder, context), clause(std::move(clause)) { } BindResult ConstantBinder::BindExpression(unique_ptr *expr_ptr, idx_t depth, bool root_expression) { @@ -207580,14 +219862,14 @@ BindResult GroupBinder::BindSelectRef(idx_t entry) { // we replace the root expression, also replace the unbound expression unbound_expression = node.select_list[entry]->Copy(); // move the expression that this refers to here and bind it - auto select_entry = move(node.select_list[entry]); + auto select_entry = std::move(node.select_list[entry]); auto binding = Bind(select_entry, nullptr, false); // now replace the original expression in the select list with a reference to this group group_alias_map[to_string(entry)] = bind_index; node.select_list[entry] = make_unique(to_string(entry)); // insert into the set of used aliases used_aliases.insert(entry); - return BindResult(move(binding)); + return BindResult(std::move(binding)); } BindResult GroupBinder::BindConstant(ConstantExpression &constant) { @@ -207655,14 +219937,17 @@ BindResult HavingBinder::BindColumnRef(unique_ptr *expr_ptr, i return alias_result; } if (aggregate_handling == AggregateHandling::FORCE_AGGREGATES) { + if (depth > 0) { + throw BinderException("Having clause cannot reference column in correlated subquery and group by all"); + } auto expr = duckdb::SelectBinder::BindExpression(expr_ptr, depth); if (expr.HasError()) { return expr; } auto group_ref = make_unique( expr.expression->return_type, ColumnBinding(node.group_index, node.groups.group_expressions.size())); - node.groups.group_expressions.push_back(move(expr.expression)); - return BindResult(move(group_ref)); + node.groups.group_expressions.push_back(std::move(expr.expression)); + return BindResult(std::move(group_ref)); } return BindResult(StringUtil::Format( "column %s must appear in the GROUP BY clause or be used in an aggregate function", expr.ToString())); @@ -207742,6 +220027,137 @@ string InsertBinder::UnsupportedAggregateMessage() { +namespace duckdb { + +LateralBinder::LateralBinder(Binder &binder, ClientContext &context) : ExpressionBinder(binder, context) { +} + +void LateralBinder::ExtractCorrelatedColumns(Expression &expr) { + if (expr.type == ExpressionType::BOUND_COLUMN_REF) { + auto &bound_colref = (BoundColumnRefExpression &)expr; + if (bound_colref.depth > 0) { + // add the correlated column info + CorrelatedColumnInfo info(bound_colref); + if (std::find(correlated_columns.begin(), correlated_columns.end(), info) == correlated_columns.end()) { + correlated_columns.push_back(std::move(info)); + } + } + } + ExpressionIterator::EnumerateChildren(expr, [&](Expression &child) { ExtractCorrelatedColumns(child); }); +} + +BindResult LateralBinder::BindColumnRef(unique_ptr *expr_ptr, idx_t depth, bool root_expression) { + if (depth == 0) { + throw InternalException("Lateral binder can only bind correlated columns"); + } + auto result = ExpressionBinder::BindExpression(expr_ptr, depth); + if (result.HasError()) { + return result; + } + if (depth > 1) { + throw BinderException("Nested lateral joins are not supported yet"); + } + ExtractCorrelatedColumns(*result.expression); + return result; +} + +vector LateralBinder::ExtractCorrelatedColumns(Binder &binder) { + auto all_correlated_columns = binder.correlated_columns; + for (auto &correlated : correlated_columns) { + auto entry = std::find(binder.correlated_columns.begin(), binder.correlated_columns.end(), correlated); + if (entry == binder.correlated_columns.end()) { + throw InternalException("Lateral Binder: could not find correlated column in binder"); + } + binder.correlated_columns.erase(entry); + } + return all_correlated_columns; +} + +BindResult LateralBinder::BindExpression(unique_ptr *expr_ptr, idx_t depth, bool root_expression) { + auto &expr = **expr_ptr; + switch (expr.GetExpressionClass()) { + case ExpressionClass::DEFAULT: + return BindResult("LATERAL join cannot contain DEFAULT clause"); + case ExpressionClass::WINDOW: + return BindResult("LATERAL join cannot contain window functions!"); + case ExpressionClass::COLUMN_REF: + return BindColumnRef(expr_ptr, depth, root_expression); + default: + return ExpressionBinder::BindExpression(expr_ptr, depth); + } +} + +string LateralBinder::UnsupportedAggregateMessage() { + return "LATERAL join cannot contain aggregates!"; +} + +class ExpressionDepthReducer : public LogicalOperatorVisitor { +public: + explicit ExpressionDepthReducer(const vector &correlated) : correlated_columns(correlated) { + } + +protected: + void ReduceColumnRefDepth(BoundColumnRefExpression &expr) { + // don't need to reduce this + if (expr.depth == 0) { + return; + } + for (auto &correlated : correlated_columns) { + if (correlated.binding == expr.binding) { + D_ASSERT(expr.depth > 1); + expr.depth--; + break; + } + } + } + + unique_ptr VisitReplace(BoundColumnRefExpression &expr, unique_ptr *expr_ptr) override { + ReduceColumnRefDepth(expr); + return nullptr; + } + + void ReduceExpressionSubquery(BoundSubqueryExpression &expr) { + for (auto &s_correlated : expr.binder->correlated_columns) { + for (auto &correlated : correlated_columns) { + if (correlated == s_correlated) { + s_correlated.depth--; + break; + } + } + } + } + + void ReduceExpressionDepth(Expression &expr) { + if (expr.GetExpressionType() == ExpressionType::BOUND_COLUMN_REF) { + ReduceColumnRefDepth((BoundColumnRefExpression &)expr); + } + if (expr.GetExpressionClass() == ExpressionClass::BOUND_SUBQUERY) { + ReduceExpressionSubquery((BoundSubqueryExpression &)expr); + } + } + + unique_ptr VisitReplace(BoundSubqueryExpression &expr, unique_ptr *expr_ptr) override { + ReduceExpressionSubquery(expr); + ExpressionIterator::EnumerateQueryNodeChildren( + *expr.subquery, [&](Expression &child_expr) { ReduceExpressionDepth(child_expr); }); + return nullptr; + } + + const vector &correlated_columns; +}; + +void LateralBinder::ReduceExpressionDepth(LogicalOperator &op, const vector &correlated) { + ExpressionDepthReducer depth_reducer(correlated); + depth_reducer.VisitOperator(op); +} + +} // namespace duckdb + + + + + + @@ -207752,12 +220168,13 @@ namespace duckdb { OrderBinder::OrderBinder(vector binders, idx_t projection_index, case_insensitive_map_t &alias_map, expression_map_t &projection_map, idx_t max_count) - : binders(move(binders)), projection_index(projection_index), max_count(max_count), extra_list(nullptr), + : binders(std::move(binders)), projection_index(projection_index), max_count(max_count), extra_list(nullptr), alias_map(alias_map), projection_map(projection_map) { } OrderBinder::OrderBinder(vector binders, idx_t projection_index, SelectNode &node, case_insensitive_map_t &alias_map, expression_map_t &projection_map) - : binders(move(binders)), projection_index(projection_index), alias_map(alias_map), projection_map(projection_map) { + : binders(std::move(binders)), projection_index(projection_index), alias_map(alias_map), + projection_map(projection_map) { this->max_count = node.select_list.size(); this->extra_list = &node.select_list; } @@ -207771,7 +220188,7 @@ unique_ptr OrderBinder::CreateProjectionReference(ParsedExpression & alias = expr.alias; } } - return make_unique(move(alias), LogicalType::INVALID, + return make_unique(std::move(alias), LogicalType::INVALID, ColumnBinding(projection_index, index)); } @@ -207780,7 +220197,7 @@ unique_ptr OrderBinder::CreateExtraReference(unique_ptrsize()); - extra_list->push_back(move(expr)); + extra_list->push_back(std::move(expr)); return result; } @@ -207864,7 +220281,7 @@ unique_ptr OrderBinder::Bind(unique_ptr expr) { expr->ToString()); } // otherwise we need to push the ORDER BY entry into the select list - return CreateExtraReference(move(expr)); + return CreateExtraReference(std::move(expr)); } } // namespace duckdb @@ -207952,7 +220369,7 @@ class RelationBinder : public ExpressionBinder { namespace duckdb { RelationBinder::RelationBinder(Binder &binder, ClientContext &context, string op) - : ExpressionBinder(binder, context), op(move(op)) { + : ExpressionBinder(binder, context), op(std::move(op)) { } BindResult RelationBinder::BindExpression(unique_ptr *expr_ptr, idx_t depth, bool root_expression) { @@ -207985,14 +220402,6 @@ namespace duckdb { ReturningBinder::ReturningBinder(Binder &binder, ClientContext &context) : ExpressionBinder(binder, context) { } -BindResult ReturningBinder::BindColumnRef(unique_ptr *expr_ptr, idx_t depth) { - auto &expr = **expr_ptr; - if (expr.GetName() == "rowid") { - return BindResult("rowid is not supported in returning statements"); - } - return ExpressionBinder::BindExpression(expr_ptr, depth); -} - BindResult ReturningBinder::BindExpression(unique_ptr *expr_ptr, idx_t depth, bool root_expression) { auto &expr = **expr_ptr; switch (expr.GetExpressionClass()) { @@ -208001,7 +220410,7 @@ BindResult ReturningBinder::BindExpression(unique_ptr *expr_pt case ExpressionClass::BOUND_SUBQUERY: return BindResult("BOUND SUBQUERY is not supported in returning statements"); case ExpressionClass::COLUMN_REF: - return BindColumnRef(expr_ptr, depth); + return ExpressionBinder::BindExpression(expr_ptr, depth); default: return ExpressionBinder::BindExpression(expr_ptr, depth); } @@ -208025,7 +220434,7 @@ namespace duckdb { SelectBinder::SelectBinder(Binder &binder, ClientContext &context, BoundSelectNode &node, BoundGroupInformation &info, case_insensitive_map_t alias_map) - : ExpressionBinder(binder, context), inside_window(false), node(node), info(info), alias_map(move(alias_map)) { + : ExpressionBinder(binder, context), inside_window(false), node(node), info(info), alias_map(std::move(alias_map)) { } SelectBinder::SelectBinder(Binder &binder, ClientContext &context, BoundSelectNode &node, BoundGroupInformation &info) @@ -208102,7 +220511,17 @@ BindResult SelectBinder::BindColumnRef(unique_ptr *expr_ptr, i "effects. This is not yet supported.", colref.column_names[0]); } - return BindResult(node.select_list[index]->Copy()); + if (node.select_list[index]->HasSubquery()) { + throw BinderException("Alias \"%s\" referenced in a SELECT clause - but the expression has a subquery." + " This is not yet supported.", + colref.column_names[0]); + } + auto result = BindResult(node.select_list[index]->Copy()); + if (result.expression->type == ExpressionType::BOUND_COLUMN_REF) { + auto &result_expr = (BoundColumnRefExpression &)*result.expression; + result_expr.depth = depth; + } + return result; } } // entry was not found in the alias map: return the original error @@ -208131,7 +220550,7 @@ BindResult SelectBinder::BindGroupingFunction(OperatorExpression &op, idx_t dept group_indexes.push_back(idx); } auto col_idx = node.grouping_functions.size(); - node.grouping_functions.push_back(move(group_indexes)); + node.grouping_functions.push_back(std::move(group_indexes)); return BindResult(make_unique(op.GetName(), LogicalType::BIGINT, ColumnBinding(node.groupings_index, col_idx), depth)); } @@ -208147,12 +220566,25 @@ BindResult SelectBinder::BindGroup(ParsedExpression &expr, idx_t depth, idx_t gr + namespace duckdb { TableFunctionBinder::TableFunctionBinder(Binder &binder, ClientContext &context) : ExpressionBinder(binder, context) { } -BindResult TableFunctionBinder::BindColumnReference(ColumnRefExpression &expr) { +BindResult TableFunctionBinder::BindColumnReference(ColumnRefExpression &expr, idx_t depth) { + + // if this is a lambda parameters, then we temporarily add a BoundLambdaRef, + // which we capture and remove later + if (lambda_bindings) { + auto &colref = (ColumnRefExpression &)expr; + for (idx_t i = 0; i < lambda_bindings->size(); i++) { + if (colref.GetColumnName() == (*lambda_bindings)[i].dummy_name) { + return (*lambda_bindings)[i].Bind(colref, i, depth); + } + } + } + auto result_name = StringUtil::Join(expr.column_names, "."); return BindResult(make_unique(Value(result_name))); } @@ -208162,7 +220594,7 @@ BindResult TableFunctionBinder::BindExpression(unique_ptr *exp auto &expr = **expr_ptr; switch (expr.GetExpressionClass()) { case ExpressionClass::COLUMN_REF: - return BindColumnReference((ColumnRefExpression &)expr); + return BindColumnReference((ColumnRefExpression &)expr, depth); case ExpressionClass::SUBQUERY: throw BinderException("Table function cannot contain subqueries"); case ExpressionClass::DEFAULT: @@ -208368,8 +220800,7 @@ bool ExpressionBinder::ContainsType(const LogicalType &type, LogicalTypeId targe return true; } switch (type.id()) { - case LogicalTypeId::STRUCT: - case LogicalTypeId::MAP: { + case LogicalTypeId::STRUCT: { auto child_count = StructType::GetChildCount(type); for (idx_t i = 0; i < child_count; i++) { if (ContainsType(StructType::GetChildType(type, i), target)) { @@ -208388,6 +220819,7 @@ bool ExpressionBinder::ContainsType(const LogicalType &type, LogicalTypeId targe return false; } case LogicalTypeId::LIST: + case LogicalTypeId::MAP: return ContainsType(ListType::GetChildType(type), target); default: return false; @@ -208399,25 +220831,25 @@ LogicalType ExpressionBinder::ExchangeType(const LogicalType &type, LogicalTypeI return new_type; } switch (type.id()) { - case LogicalTypeId::STRUCT: - case LogicalTypeId::MAP: { + case LogicalTypeId::STRUCT: { // we make a copy of the child types of the struct here auto child_types = StructType::GetChildTypes(type); for (auto &child_type : child_types) { child_type.second = ExchangeType(child_type.second, target, new_type); } - return type.id() == LogicalTypeId::MAP ? LogicalType::MAP(move(child_types)) - : LogicalType::STRUCT(move(child_types)); + return LogicalType::STRUCT(std::move(child_types)); } case LogicalTypeId::UNION: { auto member_types = UnionType::CopyMemberTypes(type); for (auto &member_type : member_types) { member_type.second = ExchangeType(member_type.second, target, new_type); } - return LogicalType::UNION(move(member_types)); + return LogicalType::UNION(std::move(member_types)); } case LogicalTypeId::LIST: return LogicalType::LIST(ExchangeType(ListType::GetChildType(type), target, new_type)); + case LogicalTypeId::MAP: + return LogicalType::MAP(ExchangeType(ListType::GetChildType(type), target, new_type)); default: return type; } @@ -208446,17 +220878,17 @@ unique_ptr ExpressionBinder::Bind(unique_ptr &expr } D_ASSERT(expr->expression_class == ExpressionClass::BOUND_EXPRESSION); auto bound_expr = (BoundExpression *)expr.get(); - unique_ptr result = move(bound_expr->expr); + unique_ptr result = std::move(bound_expr->expr); if (target_type.id() != LogicalTypeId::INVALID) { // the binder has a specific target type: add a cast to that type - result = BoundCastExpression::AddCastToType(context, move(result), target_type); + result = BoundCastExpression::AddCastToType(context, std::move(result), target_type); } else { if (!binder.can_contain_nulls) { // SQL NULL type is only used internally in the binder // cast to INTEGER if we encounter it outside of the binder if (ContainsNullType(result->return_type)) { auto result_type = ExchangeNullType(result->return_type); - result = BoundCastExpression::AddCastToType(context, move(result), result_type); + result = BoundCastExpression::AddCastToType(context, std::move(result), result_type); } } if (result->return_type.id() == LogicalTypeId::UNKNOWN) { @@ -208483,7 +220915,7 @@ string ExpressionBinder::Bind(unique_ptr *expr, idx_t depth, b return result.error; } // successfully bound: replace the node with a BoundExpression - *expr = make_unique(move(result.expression)); + *expr = make_unique(std::move(result.expression)); auto be = (BoundExpression *)expr->get(); D_ASSERT(be); be->alias = alias; @@ -208510,7 +220942,6 @@ string ExpressionBinder::Bind(unique_ptr *expr, idx_t depth, b - namespace duckdb { void ExpressionIterator::EnumerateChildren(const Expression &expr, @@ -208624,6 +221055,7 @@ void ExpressionIterator::EnumerateChildren(Expression &expr, break; } case ExpressionClass::BOUND_COLUMN_REF: + case ExpressionClass::BOUND_LAMBDA_REF: case ExpressionClass::BOUND_CONSTANT: case ExpressionClass::BOUND_DEFAULT: case ExpressionClass::BOUND_PARAMETER: @@ -208648,12 +221080,6 @@ void ExpressionIterator::EnumerateExpression(unique_ptr &expr, void ExpressionIterator::EnumerateTableRefChildren(BoundTableRef &ref, const std::function &callback) { switch (ref.type) { - case TableReferenceType::CROSS_PRODUCT: { - auto &bound_crossproduct = (BoundCrossProductRef &)ref; - EnumerateTableRefChildren(*bound_crossproduct.left, callback); - EnumerateTableRefChildren(*bound_crossproduct.right, callback); - break; - } case TableReferenceType::EXPRESSION_LIST: { auto &bound_expr_list = (BoundExpressionListRef &)ref; for (auto &expr_list : bound_expr_list.values) { @@ -208665,7 +221091,9 @@ void ExpressionIterator::EnumerateTableRefChildren(BoundTableRef &ref, } case TableReferenceType::JOIN: { auto &bound_join = (BoundJoinRef &)ref; - EnumerateExpression(bound_join.condition, callback); + if (bound_join.condition) { + EnumerateExpression(bound_join.condition, callback); + } EnumerateTableRefChildren(*bound_join.left, callback); EnumerateTableRefChildren(*bound_join.right, callback); break; @@ -208802,7 +221230,7 @@ void ConjunctionOrFilter::Serialize(FieldWriter &writer) const { unique_ptr ConjunctionOrFilter::Deserialize(FieldReader &source) { auto res = make_unique(); res->child_filters = source.ReadRequiredSerializableList(); - return move(res); + return std::move(res); } ConjunctionAndFilter::ConjunctionAndFilter() : ConjunctionFilter(TableFilterType::CONJUNCTION_AND) { @@ -208857,7 +221285,7 @@ void ConjunctionAndFilter::Serialize(FieldWriter &writer) const { unique_ptr ConjunctionAndFilter::Deserialize(FieldReader &source) { auto res = make_unique(); res->child_filters = source.ReadRequiredSerializableList(); - return move(res); + return std::move(res); } } // namespace duckdb @@ -208871,7 +221299,7 @@ namespace duckdb { ConstantFilter::ConstantFilter(ExpressionType comparison_type_p, Value constant_p) : TableFilter(TableFilterType::CONSTANT_COMPARISON), comparison_type(comparison_type_p), - constant(move(constant_p)) { + constant(std::move(constant_p)) { } FilterPropagateResult ConstantFilter::CheckStatistics(BaseStatistics &stats) { @@ -208990,20 +221418,21 @@ unique_ptr IsNullFilter::Deserialize(FieldReader &source) { namespace duckdb { unique_ptr JoinCondition::CreateExpression(JoinCondition cond) { - auto bound_comparison = make_unique(cond.comparison, move(cond.left), move(cond.right)); - return move(bound_comparison); + auto bound_comparison = + make_unique(cond.comparison, std::move(cond.left), std::move(cond.right)); + return std::move(bound_comparison); } unique_ptr JoinCondition::CreateExpression(vector conditions) { unique_ptr result; for (auto &cond : conditions) { - auto expr = CreateExpression(move(cond)); + auto expr = CreateExpression(std::move(cond)); if (!result) { - result = move(expr); + result = std::move(expr); } else { - auto conj = - make_unique(ExpressionType::CONJUNCTION_AND, move(expr), move(result)); - result = move(conj); + auto conj = make_unique(ExpressionType::CONJUNCTION_AND, std::move(expr), + std::move(result)); + result = std::move(conj); } } return result; @@ -209025,8 +221454,8 @@ JoinCondition JoinCondition::Deserialize(Deserializer &source, PlanDeserializati FieldReader reader(source); auto left = reader.ReadOptional(nullptr, state); auto right = reader.ReadOptional(nullptr, state); - result.left = move(left); - result.right = move(right); + result.left = std::move(left); + result.right = std::move(right); result.comparison = reader.ReadRequired(); reader.Finalize(); return result; @@ -209045,8 +221474,8 @@ JoinSide JoinSide::CombineJoinSide(JoinSide left, JoinSide right) { return left; } -JoinSide JoinSide::GetJoinSide(idx_t table_binding, unordered_set &left_bindings, - unordered_set &right_bindings) { +JoinSide JoinSide::GetJoinSide(idx_t table_binding, const unordered_set &left_bindings, + const unordered_set &right_bindings) { if (left_bindings.find(table_binding) != left_bindings.end()) { // column references table on left side D_ASSERT(right_bindings.find(table_binding) == right_bindings.end()); @@ -209058,8 +221487,8 @@ JoinSide JoinSide::GetJoinSide(idx_t table_binding, unordered_set &left_b } } -JoinSide JoinSide::GetJoinSide(Expression &expression, unordered_set &left_bindings, - unordered_set &right_bindings) { +JoinSide JoinSide::GetJoinSide(Expression &expression, const unordered_set &left_bindings, + const unordered_set &right_bindings) { if (expression.type == ExpressionType::BOUND_COLUMN_REF) { auto &colref = (BoundColumnRefExpression &)expression; if (colref.depth > 0) { @@ -209095,8 +221524,8 @@ JoinSide JoinSide::GetJoinSide(Expression &expression, unordered_set &lef return join_side; } -JoinSide JoinSide::GetJoinSide(const unordered_set &bindings, unordered_set &left_bindings, - unordered_set &right_bindings) { +JoinSide JoinSide::GetJoinSide(const unordered_set &bindings, const unordered_set &left_bindings, + const unordered_set &right_bindings) { JoinSide side = JoinSide::NONE; for (auto binding : bindings) { side = CombineJoinSide(side, GetJoinSide(binding, left_bindings, right_bindings)); @@ -209125,7 +221554,7 @@ LogicalOperator::LogicalOperator(LogicalOperatorType type) } LogicalOperator::LogicalOperator(LogicalOperatorType type, vector> expressions) - : type(type), expressions(move(expressions)), estimated_cardinality(0), has_estimated_cardinality(false) { + : type(type), expressions(std::move(expressions)), estimated_cardinality(0), has_estimated_cardinality(false) { } LogicalOperator::~LogicalOperator() { @@ -209259,7 +221688,7 @@ void LogicalOperator::Verify(ClientContext &context) { void LogicalOperator::AddChild(unique_ptr child) { D_ASSERT(child); - children.push_back(move(child)); + children.push_back(std::move(child)); } idx_t LogicalOperator::EstimateCardinality(ClientContext &context) { @@ -209368,6 +221797,9 @@ unique_ptr LogicalOperator::Deserialize(Deserializer &deseriali case LogicalOperatorType::LOGICAL_CROSS_PRODUCT: result = LogicalCrossProduct::Deserialize(state, reader); break; + case LogicalOperatorType::LOGICAL_POSITIONAL_JOIN: + result = LogicalPositionalJoin::Deserialize(state, reader); + break; case LogicalOperatorType::LOGICAL_UNION: result = LogicalSetOperation::Deserialize(state, reader); break; @@ -209389,9 +221821,6 @@ unique_ptr LogicalOperator::Deserialize(Deserializer &deseriali case LogicalOperatorType::LOGICAL_UPDATE: result = LogicalUpdate::Deserialize(state, reader); break; - case LogicalOperatorType::LOGICAL_ALTER: - result = LogicalSimple::Deserialize(state, reader); - break; case LogicalOperatorType::LOGICAL_CREATE_TABLE: result = LogicalCreateTable::Deserialize(state, reader); break; @@ -209410,15 +221839,9 @@ unique_ptr LogicalOperator::Deserialize(Deserializer &deseriali case LogicalOperatorType::LOGICAL_CREATE_MACRO: result = LogicalCreate::Deserialize(state, reader); break; - case LogicalOperatorType::LOGICAL_DROP: - result = LogicalSimple::Deserialize(state, reader); - break; case LogicalOperatorType::LOGICAL_PRAGMA: result = LogicalPragma::Deserialize(state, reader); break; - case LogicalOperatorType::LOGICAL_TRANSACTION: - result = LogicalSimple::Deserialize(state, reader); - break; case LogicalOperatorType::LOGICAL_CREATE_TYPE: result = LogicalCreate::Deserialize(state, reader); break; @@ -209437,13 +221860,18 @@ unique_ptr LogicalOperator::Deserialize(Deserializer &deseriali case LogicalOperatorType::LOGICAL_EXPORT: result = LogicalExport::Deserialize(state, reader); break; - case LogicalOperatorType::LOGICAL_VACUUM: - result = LogicalSimple::Deserialize(state, reader); - break; case LogicalOperatorType::LOGICAL_SET: result = LogicalSet::Deserialize(state, reader); break; + case LogicalOperatorType::LOGICAL_RESET: + result = LogicalReset::Deserialize(state, reader); + break; + case LogicalOperatorType::LOGICAL_ALTER: + case LogicalOperatorType::LOGICAL_VACUUM: case LogicalOperatorType::LOGICAL_LOAD: + case LogicalOperatorType::LOGICAL_ATTACH: + case LogicalOperatorType::LOGICAL_TRANSACTION: + case LogicalOperatorType::LOGICAL_DROP: result = LogicalSimple::Deserialize(state, reader); break; case LogicalOperatorType::LOGICAL_EXTENSION_OPERATOR: @@ -209455,7 +221883,7 @@ unique_ptr LogicalOperator::Deserialize(Deserializer &deseriali } reader.Finalize(); - result->children = move(children); + result->children = std::move(children); return result; } @@ -209533,6 +221961,16 @@ void LogicalOperatorVisitor::EnumerateExpressions(LogicalOperator &op, } break; } + case LogicalOperatorType::LOGICAL_INSERT: { + auto &insert = (LogicalInsert &)op; + if (insert.on_conflict_condition) { + callback(&insert.on_conflict_condition); + } + if (insert.do_update_condition) { + callback(&insert.do_update_condition); + } + break; + } case LogicalOperatorType::LOGICAL_DELIM_JOIN: case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: { if (op.type == LogicalOperatorType::LOGICAL_DELIM_JOIN) { @@ -209648,7 +222086,7 @@ void LogicalOperatorVisitor::VisitExpression(unique_ptr *expression) throw InternalException("Unrecognized expression type in logical operator visitor"); } if (result) { - *expression = move(result); + *expression = std::move(result); } else { // visit the children of this node VisitExpressionChildren(expr); @@ -209752,8 +222190,8 @@ unique_ptr LogicalOperatorVisitor::VisitReplace(BoundUnnestExpressio namespace duckdb { LogicalAggregate::LogicalAggregate(idx_t group_index, idx_t aggregate_index, vector> select_list) - : LogicalOperator(LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY, move(select_list)), group_index(group_index), - aggregate_index(aggregate_index), groupings_index(DConstants::INVALID_INDEX) { + : LogicalOperator(LogicalOperatorType::LOGICAL_AGGREGATE_AND_GROUP_BY, std::move(select_list)), + group_index(group_index), aggregate_index(aggregate_index), groupings_index(DConstants::INVALID_INDEX) { } void LogicalAggregate::ResolveTypes() { @@ -209773,6 +222211,7 @@ void LogicalAggregate::ResolveTypes() { vector LogicalAggregate::GetColumnBindings() { D_ASSERT(groupings_index != DConstants::INVALID_INDEX || grouping_functions.empty()); vector result; + result.reserve(groups.size() + expressions.size() + grouping_functions.size()); for (idx_t i = 0; i < groups.size(); i++) { result.emplace_back(group_index, i); } @@ -209838,13 +222277,13 @@ unique_ptr LogicalAggregate::Deserialize(LogicalDeserialization for (idx_t i = 0; i < grouping_functions_size; i++) { grouping_functions.push_back(reader.ReadRequiredList()); } - auto result = make_unique(group_index, aggregate_index, move(expressions)); + auto result = make_unique(group_index, aggregate_index, std::move(expressions)); result->groupings_index = groupings_index; - result->groups = move(groups); - result->grouping_functions = move(grouping_functions); - result->grouping_sets = move(grouping_sets); + result->groups = std::move(groups); + result->grouping_functions = std::move(grouping_functions); + result->grouping_sets = std::move(grouping_sets); - return move(result); + return std::move(result); } idx_t LogicalAggregate::EstimateCardinality(ClientContext &context) { @@ -209885,8 +222324,8 @@ unique_ptr LogicalAnyJoin::Deserialize(LogicalDeserializationSt auto join_type = reader.ReadRequired(); auto condition = reader.ReadOptional(nullptr, state.gstate); auto result = make_unique(join_type); - result->condition = move(condition); - return move(result); + result->condition = std::move(condition); + return std::move(result); } } // namespace duckdb @@ -209898,9 +222337,10 @@ namespace duckdb { LogicalColumnDataGet::LogicalColumnDataGet(idx_t table_index, vector types, unique_ptr collection) - : LogicalOperator(LogicalOperatorType::LOGICAL_CHUNK_GET), table_index(table_index), collection(move(collection)) { + : LogicalOperator(LogicalOperatorType::LOGICAL_CHUNK_GET), table_index(table_index), + collection(std::move(collection)) { D_ASSERT(types.size() > 0); - chunk_types = move(types); + chunk_types = std::move(types); } vector LogicalColumnDataGet::GetColumnBindings() { @@ -209926,7 +222366,7 @@ unique_ptr LogicalColumnDataGet::Deserialize(LogicalDeserializa chunk.Deserialize(reader.GetSource()); collection->Append(chunk); } - return make_unique(table_index, move(chunk_types), move(collection)); + return make_unique(table_index, std::move(chunk_types), std::move(collection)); } vector LogicalColumnDataGet::GetTableIndex() const { @@ -209974,7 +222414,7 @@ unique_ptr LogicalComparisonJoin::Deserialize(LogicalDeserializ FieldReader &reader) { auto result = make_unique(JoinType::INVALID, state.type); LogicalComparisonJoin::Deserialize(*result, state, reader); - return move(result); + return std::move(result); } } // namespace duckdb @@ -209986,10 +222426,14 @@ unique_ptr LogicalComparisonJoin::Deserialize(LogicalDeserializ namespace duckdb { +// Warning: some fields here were added while this code appears untested +// -> copy test in test/api/test_plan_serialization.cpp was commented out as WIP void LogicalCopyToFile::Serialize(FieldWriter &writer) const { writer.WriteString(file_path); writer.WriteField(use_tmp_file); - writer.WriteField(is_file_and_exists); + writer.WriteField(allow_overwrite); + writer.WriteField(per_thread_output); + writer.WriteList(partition_columns); D_ASSERT(!function.name.empty()); writer.WriteString(function.name); @@ -210005,19 +222449,20 @@ void LogicalCopyToFile::Serialize(FieldWriter &writer) const { unique_ptr LogicalCopyToFile::Deserialize(LogicalDeserializationState &state, FieldReader &reader) { auto file_path = reader.ReadRequired(); auto use_tmp_file = reader.ReadRequired(); - auto is_file_and_exists = reader.ReadRequired(); + auto allow_overwrite = reader.ReadRequired(); + auto per_thread_output = reader.ReadRequired(); + auto partition_columns = reader.ReadRequiredList(); auto copy_func_name = reader.ReadRequired(); auto has_bind_data = reader.ReadRequired(); auto &context = state.gstate.context; - auto &catalog = Catalog::GetCatalog(context); - auto func_catalog = catalog.GetEntry(context, CatalogType::COPY_FUNCTION_ENTRY, DEFAULT_SCHEMA, copy_func_name); - if (!func_catalog || func_catalog->type != CatalogType::COPY_FUNCTION_ENTRY) { + auto copy_func_catalog_entry = + Catalog::GetEntry(context, INVALID_CATALOG, DEFAULT_SCHEMA, copy_func_name); + if (!copy_func_catalog_entry) { throw InternalException("Cant find catalog entry for function %s", copy_func_name); } - auto copy_func_catalog_entry = (CopyFunctionCatalogEntry *)func_catalog; CopyFunction copy_func = copy_func_catalog_entry->function; unique_ptr bind_data; @@ -210028,11 +222473,13 @@ unique_ptr LogicalCopyToFile::Deserialize(LogicalDeserializatio bind_data = copy_func.deserialize(context, reader, copy_func); } - auto result = make_unique(copy_func, move(bind_data)); + auto result = make_unique(copy_func, std::move(bind_data)); result->file_path = file_path; result->use_tmp_file = use_tmp_file; - result->is_file_and_exists = is_file_and_exists; - return move(result); + result->allow_overwrite = allow_overwrite; + result->per_thread_output = per_thread_output; + result->partition_columns = std::move(partition_columns); + return std::move(result); } idx_t LogicalCopyToFile::EstimateCardinality(ClientContext &context) { @@ -210052,11 +222499,8 @@ unique_ptr LogicalCreate::Deserialize(LogicalDeserializationSta auto &context = state.gstate.context; auto info = CreateInfo::Deserialize(reader.GetSource()); - auto &catalog = Catalog::GetCatalog(context); - // TODO(stephwang): review if below is necessary or just not pass schema_catalog_entry - SchemaCatalogEntry *schema_catalog_entry = catalog.GetSchema(context, info->schema, true); - - return make_unique(state.type, move(info), schema_catalog_entry); + auto schema_catalog_entry = Catalog::GetSchema(context, INVALID_CATALOG, info->schema, true); + return make_unique(state.type, std::move(info), schema_catalog_entry); } idx_t LogicalCreate::EstimateCardinality(ClientContext &context) { @@ -210086,9 +222530,9 @@ unique_ptr LogicalCreateIndex::Deserialize(LogicalDeserializati auto &context = state.gstate.context; auto catalog_info = TableCatalogEntry::Deserialize(reader.GetSource(), context); - auto &catalog = Catalog::GetCatalog(context); - TableCatalogEntry *table = catalog.GetEntry(context, catalog_info->schema, catalog_info->table); + auto table = + Catalog::GetEntry(context, INVALID_CATALOG, catalog_info->schema, catalog_info->table); auto unbound_expressions = reader.ReadRequiredSerializableList(state.gstate); auto create_info = reader.ReadOptional(nullptr); @@ -210108,8 +222552,8 @@ unique_ptr LogicalCreateIndex::Deserialize(LogicalDeserializati reader, state.gstate, CatalogType::TABLE_FUNCTION_ENTRY, bind_data, has_deserialize); reader.Finalize(); - return make_unique(move(bind_data), move(info), move(unbound_expressions), *table, - move(function)); + return make_unique(std::move(bind_data), std::move(info), std::move(unbound_expressions), + *table, std::move(function)); } } // namespace duckdb @@ -210124,7 +222568,7 @@ void LogicalCreateTable::Serialize(FieldWriter &writer) const { unique_ptr LogicalCreateTable::Deserialize(LogicalDeserializationState &state, FieldReader &reader) { auto info = reader.ReadRequiredSerializable(state.gstate); auto schema = info->schema; - return make_unique(schema, move(info)); + return make_unique(schema, std::move(info)); } idx_t LogicalCreateTable::EstimateCardinality(ClientContext &context) { @@ -210137,23 +222581,7 @@ idx_t LogicalCreateTable::EstimateCardinality(ClientContext &context) { namespace duckdb { LogicalCrossProduct::LogicalCrossProduct(unique_ptr left, unique_ptr right) - : LogicalOperator(LogicalOperatorType::LOGICAL_CROSS_PRODUCT) { - D_ASSERT(left); - D_ASSERT(right); - children.push_back(move(left)); - children.push_back(move(right)); -} - -vector LogicalCrossProduct::GetColumnBindings() { - auto left_bindings = children[0]->GetColumnBindings(); - auto right_bindings = children[1]->GetColumnBindings(); - left_bindings.insert(left_bindings.end(), right_bindings.begin(), right_bindings.end()); - return left_bindings; -} - -void LogicalCrossProduct::ResolveTypes() { - types.insert(types.end(), children[0]->types.begin(), children[0]->types.end()); - types.insert(types.end(), children[1]->types.begin(), children[1]->types.end()); + : LogicalUnconditionalJoin(LogicalOperatorType::LOGICAL_CROSS_PRODUCT, std::move(left), std::move(right)) { } unique_ptr LogicalCrossProduct::Create(unique_ptr left, @@ -210164,7 +222592,7 @@ unique_ptr LogicalCrossProduct::Create(unique_ptrtype == LogicalOperatorType::LOGICAL_DUMMY_SCAN) { return left; } - return make_unique(move(left), move(right)); + return make_unique(std::move(left), std::move(right)); } void LogicalCrossProduct::Serialize(FieldWriter &writer) const { @@ -210173,7 +222601,7 @@ void LogicalCrossProduct::Serialize(FieldWriter &writer) const { unique_ptr LogicalCrossProduct::Deserialize(LogicalDeserializationState &state, FieldReader &reader) { // TODO(stephwang): review if unique_ptr plan is needed auto result = unique_ptr(new LogicalCrossProduct()); - return move(result); + return std::move(result); } } // namespace duckdb @@ -210205,8 +222633,14 @@ vector LogicalCTERef::GetTableIndex() const { + namespace duckdb { +LogicalDelete::LogicalDelete(TableCatalogEntry *table, idx_t table_index) + : LogicalOperator(LogicalOperatorType::LOGICAL_DELETE), table(table), table_index(table_index), + return_chunk(false) { +} + void LogicalDelete::Serialize(FieldWriter &writer) const { table->Serialize(writer.GetSerializer()); writer.WriteField(table_index); @@ -210217,14 +222651,13 @@ unique_ptr LogicalDelete::Deserialize(LogicalDeserializationSta auto &context = state.gstate.context; auto info = TableCatalogEntry::Deserialize(reader.GetSource(), context); - auto &catalog = Catalog::GetCatalog(context); - - TableCatalogEntry *table_catalog_entry = catalog.GetEntry(context, info->schema, info->table); + auto table_catalog_entry = + Catalog::GetEntry(context, INVALID_CATALOG, info->schema, info->table); auto table_index = reader.ReadRequired(); auto result = make_unique(table_catalog_entry, table_index); result->return_chunk = reader.ReadRequired(); - return move(result); + return std::move(result); } idx_t LogicalDelete::EstimateCardinality(ClientContext &context) { @@ -210235,6 +222668,21 @@ vector LogicalDelete::GetTableIndex() const { return vector {table_index}; } +vector LogicalDelete::GetColumnBindings() { + if (return_chunk) { + return GenerateColumnBindings(table_index, table->GetTypes().size()); + } + return {ColumnBinding(0, 0)}; +} + +void LogicalDelete::ResolveTypes() { + if (return_chunk) { + types = table->GetTypes(); + } else { + types.emplace_back(LogicalType::BIGINT); + } +} + } // namespace duckdb @@ -210280,7 +222728,7 @@ unique_ptr LogicalDelimJoin::Deserialize(LogicalDeserialization auto result = make_unique(JoinType::INVALID); LogicalComparisonJoin::Deserialize(*result, state, reader); result->duplicate_eliminated_columns = reader.ReadRequiredSerializableList(state.gstate); - return move(result); + return std::move(result); } } // namespace duckdb @@ -210305,7 +222753,7 @@ void LogicalDistinct::Serialize(FieldWriter &writer) const { unique_ptr LogicalDistinct::Deserialize(LogicalDeserializationState &state, FieldReader &reader) { auto distinct_targets = reader.ReadRequiredSerializableList(state.gstate); - return make_unique(move(distinct_targets)); + return make_unique(std::move(distinct_targets)); } } // namespace duckdb @@ -210356,7 +222804,7 @@ unique_ptr LogicalEmptyResult::Deserialize(LogicalDeserializati auto result = unique_ptr(new LogicalEmptyResult()); result->return_types = return_types; result->bindings = bindings; - return move(result); + return std::move(result); } } // namespace duckdb @@ -210391,7 +222839,7 @@ unique_ptr LogicalExplain::Deserialize(LogicalDeserializationSt result->physical_plan = reader.ReadRequired(); result->logical_plan_unopt = reader.ReadRequired(); result->logical_plan_opt = reader.ReadRequired(); - return move(result); + return std::move(result); } } // namespace duckdb @@ -210432,7 +222880,7 @@ unique_ptr LogicalExpressionGet::Deserialize(LogicalDeserializa expressions.push_back(reader.ReadRequiredSerializableList(state.gstate)); } - return make_unique(table_index, expr_types, move(expressions)); + return make_unique(table_index, expr_types, std::move(expressions)); } vector LogicalExpressionGet::GetTableIndex() const { @@ -210465,7 +222913,7 @@ unique_ptr LogicalExtensionOperator::Deserialize(Logic namespace duckdb { LogicalFilter::LogicalFilter(unique_ptr expression) : LogicalOperator(LogicalOperatorType::LOGICAL_FILTER) { - expressions.push_back(move(expression)); + expressions.push_back(std::move(expression)); SplitPredicates(expressions); } @@ -210491,10 +222939,10 @@ bool LogicalFilter::SplitPredicates(vector> &expressions) found_conjunction = true; // AND expression, append the other children for (idx_t k = 1; k < conjunction.children.size(); k++) { - expressions.push_back(move(conjunction.children[k])); + expressions.push_back(std::move(conjunction.children[k])); } // replace this expression with the first child of the conjunction - expressions[i] = move(conjunction.children[0]); + expressions[i] = std::move(conjunction.children[0]); // we move back by one so the right child is checked again // in case it is an AND expression as well i--; @@ -210512,9 +222960,9 @@ unique_ptr LogicalFilter::Deserialize(LogicalDeserializationSta auto expressions = reader.ReadRequiredSerializableList(state.gstate); auto projection_map = reader.ReadRequiredList(); auto result = make_unique(); - result->expressions = move(expressions); - result->projection_map = move(projection_map); - return move(result); + result->expressions = std::move(expressions); + result->projection_map = std::move(projection_map); + return std::move(result); } } // namespace duckdb @@ -210532,8 +222980,8 @@ namespace duckdb { LogicalGet::LogicalGet(idx_t table_index, TableFunction function, unique_ptr bind_data, vector returned_types, vector returned_names) - : LogicalOperator(LogicalOperatorType::LOGICAL_GET), table_index(table_index), function(move(function)), - bind_data(move(bind_data)), returned_types(move(returned_types)), names(move(returned_names)) { + : LogicalOperator(LogicalOperatorType::LOGICAL_GET), table_index(table_index), function(std::move(function)), + bind_data(std::move(bind_data)), returned_types(std::move(returned_types)), names(std::move(returned_names)) { } string LogicalGet::GetName() const { @@ -210574,6 +223022,16 @@ vector LogicalGet::GetColumnBindings() { result.emplace_back(table_index, proj_id); } } + if (!projected_input.empty()) { + if (children.size() != 1) { + throw InternalException("LogicalGet::project_input can only be set for table-in-out functions"); + } + auto child_bindings = children[0]->GetColumnBindings(); + for (auto entry : projected_input) { + D_ASSERT(entry < child_bindings.size()); + result.emplace_back(child_bindings[entry]); + } + } return result; } @@ -210600,6 +223058,15 @@ void LogicalGet::ResolveTypes() { } } } + if (!projected_input.empty()) { + if (children.size() != 1) { + throw InternalException("LogicalGet::project_input can only be set for table-in-out functions"); + } + for (auto entry : projected_input) { + D_ASSERT(entry < children[0]->types.size()); + types.push_back(children[0]->types[entry]); + } + } } idx_t LogicalGet::EstimateCardinality(ClientContext &context) { @@ -210633,6 +223100,7 @@ void LogicalGet::Serialize(FieldWriter &writer) const { writer.WriteRegularSerializableList(input_table_types); writer.WriteList(input_table_names); } + writer.WriteList(projected_input); } unique_ptr LogicalGet::Deserialize(LogicalDeserializationState &state, FieldReader &reader) { @@ -210682,16 +223150,19 @@ unique_ptr LogicalGet::Deserialize(LogicalDeserializationState "Table function deserialization failure - bind returned different returned names than were serialized"); } } + vector projected_input; + reader.ReadList(projected_input); - auto result = make_unique(table_index, function, move(bind_data), returned_types, returned_names); - result->column_ids = move(column_ids); - result->projection_ids = move(projection_ids); - result->table_filters = move(*table_filters); - result->parameters = move(parameters); - result->named_parameters = move(named_parameters); + auto result = make_unique(table_index, function, std::move(bind_data), returned_types, returned_names); + result->column_ids = std::move(column_ids); + result->projection_ids = std::move(projection_ids); + result->table_filters = std::move(*table_filters); + result->parameters = std::move(parameters); + result->named_parameters = std::move(named_parameters); result->input_table_types = input_table_types; result->input_table_names = input_table_names; - return move(result); + result->projected_input = std::move(projected_input); + return std::move(result); } vector LogicalGet::GetTableIndex() const { @@ -210706,6 +223177,11 @@ vector LogicalGet::GetTableIndex() const { namespace duckdb { +LogicalInsert::LogicalInsert(TableCatalogEntry *table, idx_t table_index) + : LogicalOperator(LogicalOperatorType::LOGICAL_INSERT), table(table), table_index(table_index), return_chunk(false), + action_type(OnConflictAction::THROW) { +} + void LogicalInsert::Serialize(FieldWriter &writer) const { writer.WriteField(insert_values.size()); for (auto &entry : insert_values) { @@ -210718,6 +223194,7 @@ void LogicalInsert::Serialize(FieldWriter &writer) const { writer.WriteField(table_index); writer.WriteField(return_chunk); writer.WriteSerializableList(bound_defaults); + writer.WriteField(action_type); } unique_ptr LogicalInsert::Deserialize(LogicalDeserializationState &state, FieldReader &reader) { @@ -210734,8 +223211,9 @@ unique_ptr LogicalInsert::Deserialize(LogicalDeserializationSta auto table_index = reader.ReadRequired(); auto return_chunk = reader.ReadRequired(); auto bound_defaults = reader.ReadRequiredSerializableList(state.gstate); + auto action_type = reader.ReadRequired(); - auto &catalog = Catalog::GetCatalog(context); + auto &catalog = Catalog::GetCatalog(context, INVALID_CATALOG); TableCatalogEntry *table_catalog_entry = catalog.GetEntry(context, info->schema, info->table); @@ -210747,11 +223225,12 @@ unique_ptr LogicalInsert::Deserialize(LogicalDeserializationSta result->type = state.type; result->table = table_catalog_entry; result->return_chunk = return_chunk; - result->insert_values = move(insert_values); + result->insert_values = std::move(insert_values); result->column_index_map = column_index_map; result->expected_types = expected_types; - result->bound_defaults = move(bound_defaults); - return move(result); + result->bound_defaults = std::move(bound_defaults); + result->action_type = action_type; + return std::move(result); } idx_t LogicalInsert::EstimateCardinality(ClientContext &context) { @@ -210762,6 +223241,21 @@ vector LogicalInsert::GetTableIndex() const { return vector {table_index}; } +vector LogicalInsert::GetColumnBindings() { + if (return_chunk) { + return GenerateColumnBindings(table_index, table->GetTypes().size()); + } + return {ColumnBinding(0, 0)}; +} + +void LogicalInsert::ResolveTypes() { + if (return_chunk) { + types = table->GetTypes(); + } else { + types.emplace_back(LogicalType::BIGINT); + } +} + } // namespace duckdb @@ -210849,7 +223343,7 @@ namespace duckdb { LogicalLimit::LogicalLimit(int64_t limit_val, int64_t offset_val, unique_ptr limit, unique_ptr offset) : LogicalOperator(LogicalOperatorType::LOGICAL_LIMIT), limit_val(limit_val), offset_val(offset_val), - limit(move(limit)), offset(move(offset)) { + limit(std::move(limit)), offset(std::move(offset)) { } vector LogicalLimit::GetColumnBindings() { @@ -210880,7 +223374,7 @@ unique_ptr LogicalLimit::Deserialize(LogicalDeserializationStat auto offset_val = reader.ReadRequired(); auto limit = reader.ReadOptional(nullptr, state.gstate); auto offset = reader.ReadOptional(nullptr, state.gstate); - return make_unique(limit_val, offset_val, move(limit), move(offset)); + return make_unique(limit_val, offset_val, std::move(limit), std::move(offset)); } } // namespace duckdb @@ -210902,7 +223396,7 @@ unique_ptr LogicalLimitPercent::Deserialize(LogicalDeserializat auto offset_val = reader.ReadRequired(); auto limit = reader.ReadOptional(nullptr, state.gstate); auto offset = reader.ReadOptional(nullptr, state.gstate); - return make_unique(limit_percent, offset_val, move(limit), move(offset)); + return make_unique(limit_percent, offset_val, std::move(limit), std::move(offset)); } idx_t LogicalLimitPercent::EstimateCardinality(ClientContext &context) { @@ -210928,9 +223422,39 @@ void LogicalOrder::Serialize(FieldWriter &writer) const { unique_ptr LogicalOrder::Deserialize(LogicalDeserializationState &state, FieldReader &reader) { auto orders = reader.ReadRequiredSerializableList(state.gstate); auto projections = reader.ReadRequiredList(); - auto result = make_unique(move(orders)); - result->projections = move(projections); - return move(result); + auto result = make_unique(std::move(orders)); + result->projections = std::move(projections); + return std::move(result); +} + +} // namespace duckdb + + +namespace duckdb { + +LogicalPositionalJoin::LogicalPositionalJoin(unique_ptr left, unique_ptr right) + : LogicalUnconditionalJoin(LogicalOperatorType::LOGICAL_POSITIONAL_JOIN, std::move(left), std::move(right)) { +} + +unique_ptr LogicalPositionalJoin::Create(unique_ptr left, + unique_ptr right) { + if (left->type == LogicalOperatorType::LOGICAL_DUMMY_SCAN) { + return right; + } + if (right->type == LogicalOperatorType::LOGICAL_DUMMY_SCAN) { + return left; + } + return make_unique(std::move(left), std::move(right)); +} + +void LogicalPositionalJoin::Serialize(FieldWriter &writer) const { +} + +unique_ptr LogicalPositionalJoin::Deserialize(LogicalDeserializationState &state, + FieldReader &reader) { + // TODO(stephwang): review if unique_ptr plan is needed + auto result = unique_ptr(new LogicalPositionalJoin()); + return std::move(result); } } // namespace duckdb @@ -210974,7 +223498,7 @@ idx_t LogicalPrepare::EstimateCardinality(ClientContext &context) { namespace duckdb { LogicalProjection::LogicalProjection(idx_t table_index, vector> select_list) - : LogicalOperator(LogicalOperatorType::LOGICAL_PROJECTION, move(select_list)), table_index(table_index) { + : LogicalOperator(LogicalOperatorType::LOGICAL_PROJECTION, std::move(select_list)), table_index(table_index) { } vector LogicalProjection::GetColumnBindings() { @@ -210995,7 +223519,7 @@ void LogicalProjection::Serialize(FieldWriter &writer) const { unique_ptr LogicalProjection::Deserialize(LogicalDeserializationState &state, FieldReader &reader) { auto table_index = reader.ReadRequired(); auto expressions = reader.ReadRequiredSerializableList(state.gstate); - return make_unique(table_index, move(expressions)); + return make_unique(table_index, std::move(expressions)); } vector LogicalProjection::GetTableIndex() const { @@ -211030,11 +223554,32 @@ vector LogicalRecursiveCTE::GetTableIndex() const { +namespace duckdb { + +void LogicalReset::Serialize(FieldWriter &writer) const { + writer.WriteString(name); + writer.WriteField(scope); +} + +unique_ptr LogicalReset::Deserialize(LogicalDeserializationState &state, FieldReader &reader) { + auto name = reader.ReadRequired(); + auto scope = reader.ReadRequired(); + return make_unique(name, scope); +} + +idx_t LogicalReset::EstimateCardinality(ClientContext &context) { + return 1; +} + +} // namespace duckdb + + + namespace duckdb { LogicalSample::LogicalSample(unique_ptr sample_options_p, unique_ptr child) - : LogicalOperator(LogicalOperatorType::LOGICAL_SAMPLE), sample_options(move(sample_options_p)) { - children.push_back(move(child)); + : LogicalOperator(LogicalOperatorType::LOGICAL_SAMPLE), sample_options(std::move(sample_options_p)) { + children.push_back(std::move(child)); } vector LogicalSample::GetColumnBindings() { @@ -211070,8 +223615,8 @@ void LogicalSample::Serialize(FieldWriter &writer) const { unique_ptr LogicalSample::Deserialize(LogicalDeserializationState &state, FieldReader &reader) { auto sample_options = SampleOptions::Deserialize(reader.GetSource()); // TODO(stephwang): review how to pass child LogicalOperator - auto result = make_unique(move(sample_options), nullptr); - return move(result); + auto result = make_unique(std::move(sample_options), nullptr); + return std::move(result); } } // namespace duckdb @@ -211137,19 +223682,50 @@ unique_ptr LogicalShow::Deserialize(LogicalDeserializationState auto result = unique_ptr(new LogicalShow()); result->types_select = types_select; result->aliases = aliases; - return move(result); + return std::move(result); } } // namespace duckdb + + + namespace duckdb { void LogicalSimple::Serialize(FieldWriter &writer) const { - throw NotImplementedException(LogicalOperatorToString(type)); + writer.WriteField(type); + switch (type) { + case LogicalOperatorType::LOGICAL_ALTER: + static_cast(*info).Serialize(writer.GetSerializer()); + break; + case LogicalOperatorType::LOGICAL_DROP: + static_cast(*info).Serialize(writer.GetSerializer()); + break; + case LogicalOperatorType::LOGICAL_LOAD: + static_cast(*info).Serialize(writer.GetSerializer()); + break; + default: + throw NotImplementedException(LogicalOperatorToString(type)); + } } unique_ptr LogicalSimple::Deserialize(LogicalDeserializationState &state, FieldReader &reader) { - throw NotImplementedException(LogicalOperatorToString(state.type)); + auto type = reader.ReadRequired(); + unique_ptr parse_info; + switch (type) { + case LogicalOperatorType::LOGICAL_ALTER: + parse_info = AlterInfo::Deserialize(reader.GetSource()); + break; + case LogicalOperatorType::LOGICAL_DROP: + parse_info = DropInfo::Deserialize(reader.GetSource()); + break; + case LogicalOperatorType::LOGICAL_LOAD: + parse_info = LoadInfo::Deserialize(reader.GetSource()); + break; + default: + throw NotImplementedException(LogicalOperatorToString(state.type)); + } + return make_unique(type, std::move(parse_info)); } idx_t LogicalSimple::EstimateCardinality(ClientContext &context) { @@ -211172,7 +223748,7 @@ unique_ptr LogicalTopN::Deserialize(LogicalDeserializationState auto orders = reader.ReadRequiredSerializableList(state.gstate); auto offset = reader.ReadRequired(); auto limit = reader.ReadRequired(); - return make_unique(move(orders), limit, offset); + return make_unique(std::move(orders), limit, offset); } idx_t LogicalTopN::EstimateCardinality(ClientContext &context) { @@ -211186,6 +223762,32 @@ idx_t LogicalTopN::EstimateCardinality(ClientContext &context) { } // namespace duckdb +namespace duckdb { + +LogicalUnconditionalJoin::LogicalUnconditionalJoin(LogicalOperatorType logical_type, unique_ptr left, + unique_ptr right) + : LogicalOperator(logical_type) { + D_ASSERT(left); + D_ASSERT(right); + children.push_back(std::move(left)); + children.push_back(std::move(right)); +} + +vector LogicalUnconditionalJoin::GetColumnBindings() { + auto left_bindings = children[0]->GetColumnBindings(); + auto right_bindings = children[1]->GetColumnBindings(); + left_bindings.insert(left_bindings.end(), right_bindings.begin(), right_bindings.end()); + return left_bindings; +} + +void LogicalUnconditionalJoin::ResolveTypes() { + types.insert(types.end(), children[0]->types.begin(), children[0]->types.end()); + types.insert(types.end(), children[1]->types.begin(), children[1]->types.end()); +} + +} // namespace duckdb + + namespace duckdb { @@ -211213,8 +223815,8 @@ unique_ptr LogicalUnnest::Deserialize(LogicalDeserializationSta auto unnest_index = reader.ReadRequired(); auto expressions = reader.ReadRequiredSerializableList(state.gstate); auto result = make_unique(unnest_index); - result->expressions = move(expressions); - return move(result); + result->expressions = std::move(expressions); + return std::move(result); } vector LogicalUnnest::GetTableIndex() const { @@ -211229,6 +223831,10 @@ vector LogicalUnnest::GetTableIndex() const { namespace duckdb { +LogicalUpdate::LogicalUpdate(TableCatalogEntry *table) + : LogicalOperator(LogicalOperatorType::LOGICAL_UPDATE), table(table), table_index(0), return_chunk(false) { +} + void LogicalUpdate::Serialize(FieldWriter &writer) const { table->Serialize(writer.GetSerializer()); writer.WriteField(table_index); @@ -211241,7 +223847,7 @@ void LogicalUpdate::Serialize(FieldWriter &writer) const { unique_ptr LogicalUpdate::Deserialize(LogicalDeserializationState &state, FieldReader &reader) { auto &context = state.gstate.context; auto info = TableCatalogEntry::Deserialize(reader.GetSource(), context); - auto &catalog = Catalog::GetCatalog(context); + auto &catalog = Catalog::GetCatalog(context, INVALID_CATALOG); TableCatalogEntry *table_catalog_entry = catalog.GetEntry(context, info->schema, info->table); @@ -211255,13 +223861,28 @@ unique_ptr LogicalUpdate::Deserialize(LogicalDeserializationSta result->columns = reader.ReadRequiredIndexList(); result->bound_defaults = reader.ReadRequiredSerializableList(state.gstate); result->update_is_del_and_insert = reader.ReadRequired(); - return move(result); + return std::move(result); } idx_t LogicalUpdate::EstimateCardinality(ClientContext &context) { return return_chunk ? LogicalOperator::EstimateCardinality(context) : 1; } +vector LogicalUpdate::GetColumnBindings() { + if (return_chunk) { + return GenerateColumnBindings(table_index, table->GetTypes().size()); + } + return {ColumnBinding(0, 0)}; +} + +void LogicalUpdate::ResolveTypes() { + if (return_chunk) { + types = table->GetTypes(); + } else { + types.emplace_back(LogicalType::BIGINT); + } +} + } // namespace duckdb @@ -211292,7 +223913,7 @@ unique_ptr LogicalWindow::Deserialize(LogicalDeserializationSta auto window_index = reader.ReadRequired(); auto result = make_unique(window_index); result->expressions = reader.ReadRequiredSerializableList(state.gstate); - return move(result); + return std::move(result); } vector LogicalWindow::GetTableIndex() const { @@ -211339,9 +223960,9 @@ unique_ptr BoundCreateTableInfo::Deserialize(Deserializer PlanDeserializationState &state) { auto create_info = SchemaCatalogEntry::Deserialize(source); auto schema_name = create_info->schema; - auto result = make_unique(move(create_info)); + auto result = make_unique(std::move(create_info)); auto &context = state.context; - result->schema = Catalog::GetCatalog(context).GetSchema(context, schema_name); + result->schema = Catalog::GetSchema(context, INVALID_CATALOG, schema_name); result->base = source.ReadOptional(); source.ReadList(result->constraints); @@ -211415,7 +224036,7 @@ void Planner::CreatePlan(SQLStatement &statement) { this->names = bound_statement.names; this->types = bound_statement.types; - this->plan = move(bound_statement.plan); + this->plan = std::move(bound_statement.plan); auto max_tree_depth = ClientConfig::GetConfig(context).max_expression_depth; CheckTreeDepth(*plan, max_tree_depth); @@ -211435,7 +224056,7 @@ void Planner::CreatePlan(SQLStatement &statement) { if (bound_statement.plan != nullptr) { this->names = bound_statement.names; this->types = bound_statement.types; - this->plan = move(bound_statement.plan); + this->plan = std::move(bound_statement.plan); break; } } @@ -211469,15 +224090,15 @@ void Planner::CreatePlan(SQLStatement &statement) { shared_ptr Planner::PrepareSQLStatement(unique_ptr statement) { auto copied_statement = statement->Copy(); // create a plan of the underlying statement - CreatePlan(move(statement)); + CreatePlan(std::move(statement)); // now create the logical prepare auto prepared_data = make_shared(copied_statement->type); - prepared_data->unbound_statement = move(copied_statement); + prepared_data->unbound_statement = std::move(copied_statement); prepared_data->names = names; prepared_data->types = types; - prepared_data->value_map = move(value_map); + prepared_data->value_map = std::move(value_map); prepared_data->properties = properties; - prepared_data->catalog_version = Transaction::GetTransaction(context).catalog_version; + prepared_data->catalog_version = MetaTransaction::Get(context).catalog_version; return prepared_data; } @@ -211506,6 +224127,7 @@ void Planner::CreatePlan(unique_ptr statement) { case StatementType::PREPARE_STATEMENT: case StatementType::EXECUTE_STATEMENT: case StatementType::LOGICAL_PLAN_STATEMENT: + case StatementType::ATTACH_STATEMENT: CreatePlan(*statement); break; default: @@ -211527,13 +224149,11 @@ static bool OperatorSupportsSerialization(LogicalOperator &op) { case LogicalOperatorType::LOGICAL_CREATE_VIEW: case LogicalOperatorType::LOGICAL_CREATE_SCHEMA: case LogicalOperatorType::LOGICAL_CREATE_MACRO: - case LogicalOperatorType::LOGICAL_DROP: case LogicalOperatorType::LOGICAL_PRAGMA: case LogicalOperatorType::LOGICAL_TRANSACTION: case LogicalOperatorType::LOGICAL_CREATE_TYPE: case LogicalOperatorType::LOGICAL_EXPLAIN: case LogicalOperatorType::LOGICAL_COPY_TO_FILE: - case LogicalOperatorType::LOGICAL_LOAD: case LogicalOperatorType::LOGICAL_VACUUM: // unsupported (for now) return false; @@ -211570,9 +224190,9 @@ void Planner::VerifyPlan(ClientContext &context, unique_ptr &op PlanDeserializationState state(context); auto new_plan = LogicalOperator::Deserialize(deserializer, state); if (map) { - *map = move(state.parameter_data); + *map = std::move(state.parameter_data); } - op = move(new_plan); + op = std::move(new_plan); } } // namespace duckdb @@ -211611,14 +224231,14 @@ void PragmaHandler::HandlePragmaStatementsInternal(vector> &statements) { @@ -211640,7 +224260,7 @@ void PragmaHandler::HandlePragmaStatements(ClientContextLock &lock, vector(context, DEFAULT_SCHEMA, info.name, false); + Catalog::GetEntry(context, INVALID_CATALOG, DEFAULT_SCHEMA, info.name, false); string error; FunctionBinder function_binder(context); @@ -211688,11 +224308,12 @@ namespace duckdb { //! Helper class to recursively detect correlated expressions inside a single LogicalOperator class HasCorrelatedExpressions : public LogicalOperatorVisitor { public: - explicit HasCorrelatedExpressions(const vector &correlated); + explicit HasCorrelatedExpressions(const vector &correlated, bool lateral = false); void VisitOperator(LogicalOperator &op) override; bool has_correlated_expressions; + bool lateral; protected: unique_ptr VisitReplace(BoundColumnRefExpression &expr, unique_ptr *expr_ptr) override; @@ -211767,7 +224388,8 @@ namespace duckdb { FlattenDependentJoins::FlattenDependentJoins(Binder &binder, const vector &correlated, bool perform_delim, bool any_join) - : binder(binder), correlated_columns(correlated), perform_delim(perform_delim), any_join(any_join) { + : binder(binder), delim_offset(DConstants::INVALID_INDEX), correlated_columns(correlated), + perform_delim(perform_delim), any_join(any_join) { for (idx_t i = 0; i < correlated_columns.size(); i++) { auto &col = correlated_columns[i]; correlated_map[col.binding] = i; @@ -211775,10 +224397,10 @@ FlattenDependentJoins::FlattenDependentJoins(Binder &binder, const vector FlattenDependentJoins::PushDownDependentJoin(unique_ptr plan) { bool propagate_null_values = true; - auto result = PushDownDependentJoinInternal(move(plan), propagate_null_values); + auto result = PushDownDependentJoinInternal(std::move(plan), propagate_null_values); if (!replacement_map.empty()) { // check if we have to replace any COUNT aggregates into "CASE WHEN X IS NULL THEN 0 ELSE COUNT END" RewriteCountAggregates aggr(replacement_map); @@ -211833,10 +224455,10 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal auto left_columns = plan->GetColumnBindings().size(); auto delim_index = binder.GenerateTableIndex(); this->base_binding = ColumnBinding(delim_index, 0); - this->delim_offset = 0; - this->data_offset = left_columns; + this->delim_offset = left_columns; + this->data_offset = 0; auto delim_scan = make_unique(delim_index, delim_types); - return LogicalCrossProduct::Create(move(plan), move(delim_scan)); + return LogicalCrossProduct::Create(std::move(plan), std::move(delim_scan)); } switch (plan->type) { case LogicalOperatorType::LOGICAL_UNNEST: @@ -211846,7 +224468,7 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal for (auto &expr : plan->expressions) { any_join |= SubqueryDependentFilter(expr.get()); } - plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values); + plan->children[0] = PushDownDependentJoinInternal(std::move(plan->children[0]), parent_propagate_null_values); // then we replace any correlated expressions with the corresponding entry in the correlated_map RewriteCorrelatedExpressions rewriter(base_binding, correlated_map); @@ -211859,7 +224481,7 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal for (auto &expr : plan->expressions) { parent_propagate_null_values &= expr->PropagatesNullValues(); } - plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values); + plan->children[0] = PushDownDependentJoinInternal(std::move(plan->children[0]), parent_propagate_null_values); // then we replace any correlated expressions with the corresponding entry in the correlated_map RewriteCorrelatedExpressions rewriter(base_binding, correlated_map); @@ -211870,7 +224492,7 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal auto &col = correlated_columns[i]; auto colref = make_unique( col.name, col.type, ColumnBinding(base_binding.table_index, base_binding.column_index + i)); - plan->expressions.push_back(move(colref)); + plan->expressions.push_back(std::move(colref)); } base_binding.table_index = proj->table_index; @@ -211885,7 +224507,7 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal for (auto &expr : plan->expressions) { parent_propagate_null_values &= expr->PropagatesNullValues(); } - plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values); + plan->children[0] = PushDownDependentJoinInternal(std::move(plan->children[0]), parent_propagate_null_values); // then we replace any correlated expressions with the corresponding entry in the correlated_map RewriteCorrelatedExpressions rewriter(base_binding, correlated_map); rewriter.VisitOperator(*plan); @@ -211901,7 +224523,7 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal for (auto &set : aggr.grouping_sets) { set.insert(aggr.groups.size()); } - aggr.groups.push_back(move(colref)); + aggr.groups.push_back(std::move(colref)); } if (!perform_delim) { // if we are not performing the duplicate elimination, we have only added the row_id column to the grouping @@ -211915,10 +224537,11 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal auto colref = make_unique( col.name, col.type, ColumnBinding(base_binding.table_index, base_binding.column_index + i)); vector> aggr_children; - aggr_children.push_back(move(colref)); - auto first_fun = make_unique(move(first_aggregate), move(aggr_children), - nullptr, nullptr, AggregateType::NON_DISTINCT); - aggr.expressions.push_back(move(first_fun)); + aggr_children.push_back(std::move(colref)); + auto first_fun = + make_unique(std::move(first_aggregate), std::move(aggr_children), nullptr, + nullptr, AggregateType::NON_DISTINCT); + aggr.expressions.push_back(std::move(first_fun)); } } else { delim_table_index = aggr.group_index; @@ -211939,8 +224562,8 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal } auto left_index = binder.GenerateTableIndex(); auto delim_scan = make_unique(left_index, delim_types); - join->children.push_back(move(delim_scan)); - join->children.push_back(move(plan)); + join->children.push_back(std::move(delim_scan)); + join->children.push_back(std::move(plan)); for (idx_t i = 0; i < new_group_count; i++) { auto &col = correlated_columns[i]; JoinCondition cond; @@ -211948,7 +224571,7 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal cond.right = make_unique( correlated_columns[i].type, ColumnBinding(delim_table_index, delim_column_offset + i)); cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM; - join->conditions.push_back(move(cond)); + join->conditions.push_back(std::move(cond)); } // for any COUNT aggregate we replace references to the column with: CASE WHEN COUNT(*) IS NULL THEN 0 // ELSE COUNT(*) END @@ -211965,7 +224588,7 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal base_binding.table_index = left_index; this->delim_offset = base_binding.column_index = 0; this->data_offset = 0; - return move(join); + return std::move(join); } else { // update the delim_index base_binding.table_index = delim_table_index; @@ -211981,20 +224604,22 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal bool right_has_correlation = has_correlated_expressions.find(plan->children[1].get())->second; if (!right_has_correlation) { // only left has correlation: push into left - plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values); + plan->children[0] = + PushDownDependentJoinInternal(std::move(plan->children[0]), parent_propagate_null_values); return plan; } if (!left_has_correlation) { // only right has correlation: push into right - plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]), parent_propagate_null_values); + plan->children[1] = + PushDownDependentJoinInternal(std::move(plan->children[1]), parent_propagate_null_values); return plan; } // both sides have correlation // turn into an inner join auto join = make_unique(JoinType::INNER); - plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values); + plan->children[0] = PushDownDependentJoinInternal(std::move(plan->children[0]), parent_propagate_null_values); auto left_binding = this->base_binding; - plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]), parent_propagate_null_values); + plan->children[1] = PushDownDependentJoinInternal(std::move(plan->children[1]), parent_propagate_null_values); // add the correlated columns to the join conditions for (idx_t i = 0; i < correlated_columns.size(); i++) { JoinCondition cond; @@ -212003,11 +224628,11 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal cond.right = make_unique( correlated_columns[i].type, ColumnBinding(base_binding.table_index, base_binding.column_index + i)); cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM; - join->conditions.push_back(move(cond)); + join->conditions.push_back(std::move(cond)); } - join->children.push_back(move(plan->children[0])); - join->children.push_back(move(plan->children[1])); - return move(join); + join->children.push_back(std::move(plan->children[0])); + join->children.push_back(std::move(plan->children[1])); + return std::move(join); } case LogicalOperatorType::LOGICAL_ANY_JOIN: case LogicalOperatorType::LOGICAL_COMPARISON_JOIN: { @@ -212022,13 +224647,13 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal if (!right_has_correlation) { // only left has correlation: push into left plan->children[0] = - PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values); + PushDownDependentJoinInternal(std::move(plan->children[0]), parent_propagate_null_values); return plan; } if (!left_has_correlation) { // only right has correlation: push into right plan->children[1] = - PushDownDependentJoinInternal(move(plan->children[1]), parent_propagate_null_values); + PushDownDependentJoinInternal(std::move(plan->children[1]), parent_propagate_null_values); return plan; } } else if (join.join_type == JoinType::LEFT) { @@ -212036,7 +224661,7 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal if (!right_has_correlation) { // only left has correlation: push into left plan->children[0] = - PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values); + PushDownDependentJoinInternal(std::move(plan->children[0]), parent_propagate_null_values); return plan; } } else if (join.join_type == JoinType::RIGHT) { @@ -212044,7 +224669,7 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal if (!left_has_correlation) { // only right has correlation: push into right plan->children[1] = - PushDownDependentJoinInternal(move(plan->children[1]), parent_propagate_null_values); + PushDownDependentJoinInternal(std::move(plan->children[1]), parent_propagate_null_values); return plan; } } else if (join.join_type == JoinType::MARK) { @@ -212052,7 +224677,8 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal throw Exception("MARK join with correlation in RHS not supported"); } // push the child into the LHS - plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values); + plan->children[0] = + PushDownDependentJoinInternal(std::move(plan->children[0]), parent_propagate_null_values); // rewrite expressions in the join conditions RewriteCorrelatedExpressions rewriter(base_binding, correlated_map); rewriter.VisitOperator(*plan); @@ -212062,9 +224688,9 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal } // both sides have correlation // push into both sides - plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values); + plan->children[0] = PushDownDependentJoinInternal(std::move(plan->children[0]), parent_propagate_null_values); auto left_binding = this->base_binding; - plan->children[1] = PushDownDependentJoinInternal(move(plan->children[1]), parent_propagate_null_values); + plan->children[1] = PushDownDependentJoinInternal(std::move(plan->children[1]), parent_propagate_null_values); auto right_binding = this->base_binding; // NOTE: for OUTER JOINS it matters what the BASE BINDING is after the join // for the LEFT OUTER JOIN, we want the LEFT side to be the base binding after we push @@ -212083,19 +224709,19 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal if (join.type == LogicalOperatorType::LOGICAL_COMPARISON_JOIN) { JoinCondition cond; - cond.left = move(left); - cond.right = move(right); + cond.left = std::move(left); + cond.right = std::move(right); cond.comparison = ExpressionType::COMPARE_NOT_DISTINCT_FROM; auto &comparison_join = (LogicalComparisonJoin &)join; - comparison_join.conditions.push_back(move(cond)); + comparison_join.conditions.push_back(std::move(cond)); } else { auto &any_join = (LogicalAnyJoin &)join; auto comparison = make_unique(ExpressionType::COMPARE_NOT_DISTINCT_FROM, - move(left), move(right)); - auto conjunction = make_unique(ExpressionType::CONJUNCTION_AND, - move(comparison), move(any_join.condition)); - any_join.condition = move(conjunction); + std::move(left), std::move(right)); + auto conjunction = make_unique( + ExpressionType::CONJUNCTION_AND, std::move(comparison), std::move(any_join.condition)); + any_join.condition = std::move(conjunction); } } // then we replace any correlated expressions with the corresponding entry in the correlated_map @@ -212115,10 +224741,10 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal // check if the direct child of this LIMIT node is an ORDER BY node, if so, keep it separate // this is done for an optimization to avoid having to compute the total order if (plan->children[0]->type == LogicalOperatorType::LOGICAL_ORDER_BY) { - order_by = unique_ptr_cast(move(plan->children[0])); - child = PushDownDependentJoinInternal(move(order_by->children[0]), parent_propagate_null_values); + order_by = unique_ptr_cast(std::move(plan->children[0])); + child = PushDownDependentJoinInternal(std::move(order_by->children[0]), parent_propagate_null_values); } else { - child = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values); + child = PushDownDependentJoinInternal(std::move(plan->children[0]), parent_propagate_null_values); } auto child_column_count = child->GetColumnBindings().size(); // we push a row_number() OVER (PARTITION BY [correlated columns]) @@ -212131,18 +224757,18 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal auto &col = correlated_columns[i]; auto colref = make_unique( col.name, col.type, ColumnBinding(base_binding.table_index, base_binding.column_index + i)); - row_number->partitions.push_back(move(colref)); + row_number->partitions.push_back(std::move(colref)); } if (order_by) { // optimization: if there is an ORDER BY node followed by a LIMIT // rather than computing the entire order, we push the ORDER BY expressions into the row_num computation // this way, the order only needs to be computed per partition - row_number->orders = move(order_by->orders); + row_number->orders = std::move(order_by->orders); } row_number->start = WindowBoundary::UNBOUNDED_PRECEDING; row_number->end = WindowBoundary::CURRENT_ROW_ROWS; - window->expressions.push_back(move(row_number)); - window->children.push_back(move(child)); + window->expressions.push_back(std::move(row_number)); + window->children.push_back(std::move(child)); // add a filter based on the row_number // the filter we add is "row_number > offset AND row_number <= offset + limit" @@ -212155,23 +224781,23 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal TryAddOperator::Operation(limit.offset_val, limit.limit_val, upper_bound_limit); auto upper_bound = make_unique(Value::BIGINT(upper_bound_limit)); condition = make_unique(ExpressionType::COMPARE_LESSTHANOREQUALTO, - row_num_ref->Copy(), move(upper_bound)); + row_num_ref->Copy(), std::move(upper_bound)); // we only need to add "row_number >= offset + 1" if offset is bigger than 0 if (limit.offset_val > 0) { auto lower_bound = make_unique(Value::BIGINT(limit.offset_val)); auto lower_comp = make_unique(ExpressionType::COMPARE_GREATERTHAN, - row_num_ref->Copy(), move(lower_bound)); - auto conj = make_unique(ExpressionType::CONJUNCTION_AND, move(lower_comp), - move(condition)); - condition = move(conj); + row_num_ref->Copy(), std::move(lower_bound)); + auto conj = make_unique(ExpressionType::CONJUNCTION_AND, std::move(lower_comp), + std::move(condition)); + condition = std::move(conj); } - filter->expressions.push_back(move(condition)); - filter->children.push_back(move(window)); + filter->expressions.push_back(std::move(condition)); + filter->children.push_back(std::move(window)); // we prune away the row_number after the filter clause using the projection map for (idx_t i = 0; i < child_column_count; i++) { filter->projection_map.push_back(i); } - return move(filter); + return std::move(filter); } case LogicalOperatorType::LOGICAL_LIMIT_PERCENT: { // NOTE: limit percent could be supported in a manner similar to the LIMIT above @@ -212182,7 +224808,7 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal case LogicalOperatorType::LOGICAL_WINDOW: { auto &window = (LogicalWindow &)*plan; // push into children - plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values); + plan->children[0] = PushDownDependentJoinInternal(std::move(plan->children[0]), parent_propagate_null_values); // add the correlated columns to the PARTITION BY clauses in the Window for (auto &expr : window.expressions) { D_ASSERT(expr->GetExpressionClass() == ExpressionClass::BOUND_WINDOW); @@ -212205,8 +224831,8 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal plan->children[1]->ResolveOperatorTypes(); D_ASSERT(plan->children[0]->types == plan->children[1]->types); #endif - plan->children[0] = PushDownDependentJoin(move(plan->children[0])); - plan->children[1] = PushDownDependentJoin(move(plan->children[1])); + plan->children[0] = PushDownDependentJoin(std::move(plan->children[0])); + plan->children[1] = PushDownDependentJoin(std::move(plan->children[1])); #ifdef DEBUG D_ASSERT(plan->children[0]->GetColumnBindings().size() == plan->children[1]->GetColumnBindings().size()); plan->children[0]->ResolveOperatorTypes(); @@ -212222,7 +224848,7 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal case LogicalOperatorType::LOGICAL_DISTINCT: { auto &distinct = (LogicalDistinct &)*plan; // push down into child - distinct.children[0] = PushDownDependentJoin(move(distinct.children[0])); + distinct.children[0] = PushDownDependentJoin(std::move(distinct.children[0])); // add all correlated columns to the distinct targets for (idx_t i = 0; i < correlated_columns.size(); i++) { distinct.distinct_targets.push_back(make_unique( @@ -212233,7 +224859,7 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal case LogicalOperatorType::LOGICAL_EXPRESSION_GET: { // expression get // first we flatten the dependent join in the child - plan->children[0] = PushDownDependentJoinInternal(move(plan->children[0]), parent_propagate_null_values); + plan->children[0] = PushDownDependentJoinInternal(std::move(plan->children[0]), parent_propagate_null_values); // then we replace any correlated expressions with the corresponding entry in the correlated_map RewriteCorrelatedExpressions rewriter(base_binding, correlated_map); rewriter.VisitOperator(*plan); @@ -212243,7 +224869,7 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal for (auto &expr_list : expr_get->expressions) { auto colref = make_unique( correlated_columns[i].type, ColumnBinding(base_binding.table_index, base_binding.column_index + i)); - expr_list.push_back(move(colref)); + expr_list.push_back(std::move(colref)); } expr_get->expr_types.push_back(correlated_columns[i].type); } @@ -212254,11 +224880,29 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal return plan; } case LogicalOperatorType::LOGICAL_ORDER_BY: - plan->children[0] = PushDownDependentJoin(move(plan->children[0])); + plan->children[0] = PushDownDependentJoin(std::move(plan->children[0])); + return plan; + case LogicalOperatorType::LOGICAL_GET: { + auto &get = (LogicalGet &)*plan; + if (get.children.size() != 1) { + throw InternalException("Flatten dependent joins - logical get encountered without children"); + } + plan->children[0] = PushDownDependentJoin(std::move(plan->children[0])); + for (idx_t i = 0; i < (perform_delim ? correlated_columns.size() : 1); i++) { + get.projected_input.push_back(this->delim_offset + i); + } + this->delim_offset = get.returned_types.size(); + this->data_offset = 0; return plan; + } case LogicalOperatorType::LOGICAL_RECURSIVE_CTE: { - throw ParserException("Recursive CTEs not supported in correlated subquery"); + throw BinderException("Recursive CTEs not supported in correlated subquery"); + } + case LogicalOperatorType::LOGICAL_DELIM_JOIN: { + throw BinderException("Nested lateral joins or lateral joins in correlated subqueries are not (yet) supported"); } + case LogicalOperatorType::LOGICAL_SAMPLE: + throw BinderException("Sampling in correlated subqueries is not (yet) supported"); default: throw InternalException("Logical operator type \"%s\" for dependent join", LogicalOperatorToString(plan->type)); } @@ -212274,12 +224918,11 @@ unique_ptr FlattenDependentJoins::PushDownDependentJoinInternal namespace duckdb { -HasCorrelatedExpressions::HasCorrelatedExpressions(const vector &correlated) - : has_correlated_expressions(false), correlated_columns(correlated) { +HasCorrelatedExpressions::HasCorrelatedExpressions(const vector &correlated, bool lateral) + : has_correlated_expressions(false), lateral(lateral), correlated_columns(correlated) { } void HasCorrelatedExpressions::VisitOperator(LogicalOperator &op) { - //! The HasCorrelatedExpressions does not recursively visit logical operators, it only visits the current one VisitOperatorExpressions(op); } @@ -212288,6 +224931,12 @@ unique_ptr HasCorrelatedExpressions::VisitReplace(BoundColumnRefExpr if (expr.depth == 0) { return nullptr; } + if (expr.depth > 1) { + if (lateral) { + throw BinderException("Nested lateral joins are not (yet) supported"); + } + throw InternalException("Expression with depth > 1 detected in non-lateral join"); + } // correlated column reference D_ASSERT(expr.depth == 1); has_correlated_expressions = true; @@ -212418,10 +225067,11 @@ unique_ptr RewriteCountAggregates::VisitReplace(BoundColumnRefExpres // replace this with CASE WHEN COUNT(*) IS NULL THEN 0 ELSE COUNT(*) END auto is_null = make_unique(ExpressionType::OPERATOR_IS_NULL, LogicalType::BOOLEAN); is_null->children.push_back(expr.Copy()); - auto check = move(is_null); + auto check = std::move(is_null); auto result_if_true = make_unique(Value::Numeric(expr.return_type, 0)); - auto result_if_false = move(*expr_ptr); - return make_unique(move(check), move(result_if_true), move(result_if_false)); + auto result_if_false = std::move(*expr_ptr); + return make_unique(std::move(check), std::move(result_if_true), + std::move(result_if_false)); } return nullptr; } @@ -212439,11 +225089,14 @@ unique_ptr RewriteCountAggregates::VisitReplace(BoundColumnRefExpres + +#include + namespace duckdb { Binding::Binding(BindingType binding_type, const string &alias, vector coltypes, vector colnames, idx_t index) - : binding_type(binding_type), alias(alias), index(index), types(move(coltypes)), names(move(colnames)) { + : binding_type(binding_type), alias(alias), index(index), types(std::move(coltypes)), names(std::move(colnames)) { D_ASSERT(types.size() == names.size()); for (idx_t i = 0; i < names.size(); i++) { auto &name = names[i]; @@ -212505,7 +225158,7 @@ StandardEntry *Binding::GetStandardEntry() { EntryBinding::EntryBinding(const string &alias, vector types_p, vector names_p, idx_t index, StandardEntry &entry) - : Binding(BindingType::CATALOG_ENTRY, alias, move(types_p), move(names_p), index), entry(entry) { + : Binding(BindingType::CATALOG_ENTRY, alias, std::move(types_p), std::move(names_p), index), entry(entry) { } StandardEntry *EntryBinding::GetStandardEntry() { @@ -212514,8 +225167,8 @@ StandardEntry *EntryBinding::GetStandardEntry() { TableBinding::TableBinding(const string &alias, vector types_p, vector names_p, vector &bound_column_ids, StandardEntry *entry, idx_t index, bool add_row_id) - : Binding(BindingType::TABLE, alias, move(types_p), move(names_p), index), bound_column_ids(bound_column_ids), - entry(entry) { + : Binding(BindingType::TABLE, alias, std::move(types_p), std::move(names_p), index), + bound_column_ids(bound_column_ids), entry(entry) { if (add_row_id) { if (name_map.find("rowid") == name_map.end()) { name_map["rowid"] = COLUMN_IDENTIFIER_ROW_ID; @@ -212558,18 +225211,53 @@ unique_ptr TableBinding::ExpandGeneratedColumn(const string &c // Get the index of the generated column auto column_index = GetBindingIndex(column_name); - D_ASSERT(table_entry->columns.GetColumn(LogicalIndex(column_index)).Generated()); + D_ASSERT(table_entry->GetColumn(LogicalIndex(column_index)).Generated()); // Get a copy of the generated column - auto expression = table_entry->columns.GetColumn(LogicalIndex(column_index)).GeneratedExpression().Copy(); + auto expression = table_entry->GetColumn(LogicalIndex(column_index)).GeneratedExpression().Copy(); unordered_map alias_map; for (auto &entry : name_map) { alias_map[entry.second] = entry.first; } - ReplaceAliases(*expression, table_entry->columns, alias_map); + ReplaceAliases(*expression, table_entry->GetColumns(), alias_map); BakeTableName(*expression, alias); return (expression); } +const vector &TableBinding::GetBoundColumnIds() const { +#ifdef DEBUG + unordered_set column_ids; + for (auto &id : bound_column_ids) { + auto result = column_ids.insert(id); + // assert that all entries in the bound_column_ids are unique + D_ASSERT(result.second); + auto it = std::find_if(name_map.begin(), name_map.end(), + [&](const std::pair &it) { return it.second == id; }); + // assert that every id appears in the name_map + D_ASSERT(it != name_map.end()); + // the order that they appear in is not guaranteed to be sequential + } +#endif + return bound_column_ids; +} + +ColumnBinding TableBinding::GetColumnBinding(column_t column_index) { + auto &column_ids = bound_column_ids; + ColumnBinding binding; + + // Locate the column_id that matches the 'column_index' + auto it = std::find_if(column_ids.begin(), column_ids.end(), + [&](const column_t &id) -> bool { return id == column_index; }); + // Get the index of it + binding.column_index = std::distance(column_ids.begin(), it); + // If it wasn't found, add it + if (it == column_ids.end()) { + column_ids.push_back(column_index); + } + + binding.table_index = index; + return binding; +} + BindResult TableBinding::Bind(ColumnRefExpression &colref, idx_t depth) { auto &column_name = colref.GetColumnName(); column_t column_index; @@ -212583,7 +225271,7 @@ BindResult TableBinding::Bind(ColumnRefExpression &colref, idx_t depth) { D_ASSERT(entry->type == CatalogType::TABLE_ENTRY); // Either there is no table, or the columns category has to be standard auto table_entry = (TableCatalogEntry *)entry; - auto &column_entry = table_entry->columns.GetColumn(LogicalIndex(column_index)); + auto &column_entry = table_entry->GetColumn(LogicalIndex(column_index)); (void)table_entry; (void)column_entry; D_ASSERT(column_entry.Category() == TableColumnType::STANDARD); @@ -212600,23 +225288,7 @@ BindResult TableBinding::Bind(ColumnRefExpression &colref, idx_t depth) { colref.alias = names[column_index]; } } - - auto &column_ids = bound_column_ids; - // check if the entry already exists in the column list for the table - ColumnBinding binding; - - binding.column_index = column_ids.size(); - for (idx_t i = 0; i < column_ids.size(); i++) { - if (column_ids[i] == column_index) { - binding.column_index = i; - break; - } - } - if (binding.column_index == column_ids.size()) { - // column binding not found: add it to the list of bindings - column_ids.push_back(column_index); - } - binding.table_index = index; + ColumnBinding binding = GetColumnBinding(column_index); return BindResult(make_unique(colref.GetName(), col_type, binding, depth)); } @@ -212629,8 +225301,9 @@ string TableBinding::ColumnNotFoundError(const string &column_name) const { } DummyBinding::DummyBinding(vector types_p, vector names_p, string dummy_name_p) - : Binding(BindingType::DUMMY, DummyBinding::DUMMY_NAME + dummy_name_p, move(types_p), move(names_p), -1), - dummy_name(move(dummy_name_p)) { + : Binding(BindingType::DUMMY, DummyBinding::DUMMY_NAME + dummy_name_p, std::move(types_p), std::move(names_p), + DConstants::INVALID_INDEX), + dummy_name(std::move(dummy_name_p)) { } BindResult DummyBinding::Bind(ColumnRefExpression &colref, idx_t depth) { @@ -212638,14 +225311,22 @@ BindResult DummyBinding::Bind(ColumnRefExpression &colref, idx_t depth) { if (!TryGetBindingIndex(colref.GetColumnName(), column_index)) { throw InternalException("Column %s not found in bindings", colref.GetColumnName()); } - ColumnBinding binding; - binding.table_index = index; - binding.column_index = column_index; + ColumnBinding binding(index, column_index); // we are binding a parameter to create the dummy binding, no arguments are supplied return BindResult(make_unique(colref.GetName(), types[column_index], binding, depth)); } +BindResult DummyBinding::Bind(ColumnRefExpression &colref, idx_t lambda_index, idx_t depth) { + column_t column_index; + if (!TryGetBindingIndex(colref.GetColumnName(), column_index)) { + throw InternalException("Column %s not found in bindings", colref.GetColumnName()); + } + ColumnBinding binding(index, column_index); + return BindResult( + make_unique(colref.GetName(), types[column_index], binding, lambda_index, depth)); +} + unique_ptr DummyBinding::ParamToArg(ColumnRefExpression &colref) { column_t column_index; if (!TryGetBindingIndex(colref.GetColumnName(), column_index)) { @@ -212669,17 +225350,17 @@ void TableFilterSet::PushFilter(idx_t column_index, unique_ptr filt auto entry = filters.find(column_index); if (entry == filters.end()) { // no filter yet: push the filter directly - filters[column_index] = move(filter); + filters[column_index] = std::move(filter); } else { // there is already a filter: AND it together if (entry->second->filter_type == TableFilterType::CONJUNCTION_AND) { auto &and_filter = (ConjunctionAndFilter &)*entry->second; - and_filter.child_filters.push_back(move(filter)); + and_filter.child_filters.push_back(std::move(filter)); } else { auto and_filter = make_unique(); - and_filter->child_filters.push_back(move(entry->second)); - and_filter->child_filters.push_back(move(filter)); - filters[column_index] = move(and_filter); + and_filter->child_filters.push_back(std::move(entry->second)); + and_filter->child_filters.push_back(std::move(filter)); + filters[column_index] = std::move(and_filter); } } } @@ -212700,7 +225381,7 @@ unique_ptr TableFilterSet::Deserialize(Deserializer &source) { for (idx_t i = 0; i < len; i++) { auto key = source.Read(); auto value = TableFilter::Deserialize(source); - res->filters[key] = move(value); + res->filters[key] = std::move(value); } return res; } @@ -212746,6 +225427,7 @@ unique_ptr TableFilter::Deserialize(Deserializer &source) { + namespace duckdb { ArenaChunk::ArenaChunk(Allocator &allocator, idx_t size) : current_position(0), maximum_size(size), prev(nullptr) { @@ -212754,9 +225436,9 @@ ArenaChunk::ArenaChunk(Allocator &allocator, idx_t size) : current_position(0), } ArenaChunk::~ArenaChunk() { if (next) { - auto current_next = move(next); + auto current_next = std::move(next); while (current_next) { - current_next = move(current_next->next); + current_next = std::move(current_next->next); } } } @@ -212779,11 +225461,11 @@ data_ptr_t ArenaAllocator::Allocate(idx_t len) { auto new_chunk = make_unique(allocator, current_capacity); if (head) { head->prev = new_chunk.get(); - new_chunk->next = move(head); + new_chunk->next = std::move(head); } else { tail = new_chunk.get(); } - head = move(new_chunk); + head = std::move(new_chunk); } D_ASSERT(head->current_position + len <= head->maximum_size); auto result = head->data.get() + head->current_position; @@ -212791,14 +225473,43 @@ data_ptr_t ArenaAllocator::Allocate(idx_t len) { return result; } +data_ptr_t ArenaAllocator::Reallocate(data_ptr_t pointer, idx_t old_size, idx_t size) { + D_ASSERT(head); + if (old_size == size) { + // nothing to do + return pointer; + } + + auto head_ptr = head->data.get() + head->current_position; + int64_t diff = size - old_size; + if (pointer == head_ptr && (size < old_size || head->current_position + diff <= head->maximum_size)) { + // passed pointer is the head pointer, and the diff fits on the current chunk + head->current_position += diff; + return pointer; + } else { + // allocate new memory + auto result = Allocate(size); + memcpy(result, pointer, old_size); + return result; + } +} + +data_ptr_t ArenaAllocator::AllocateAligned(idx_t size) { + return Allocate(AlignValue(size)); +} + +data_ptr_t ArenaAllocator::ReallocateAligned(data_ptr_t pointer, idx_t old_size, idx_t size) { + return Reallocate(pointer, old_size, AlignValue(size)); +} + void ArenaAllocator::Reset() { if (head) { // destroy all chunks except the current one if (head->next) { - auto current_next = move(head->next); + auto current_next = std::move(head->next); while (current_next) { - current_next = move(current_next->next); + current_next = std::move(current_next->next); } } tail = head.get(); @@ -212818,7 +225529,7 @@ void ArenaAllocator::Destroy() { void ArenaAllocator::Move(ArenaAllocator &other) { D_ASSERT(!other.head); other.tail = tail; - other.head = move(head); + other.head = std::move(head); other.current_capacity = current_capacity; Destroy(); } @@ -212847,11 +225558,11 @@ Block::Block(Allocator &allocator, block_id_t id) Block::Block(Allocator &allocator, block_id_t id, uint32_t internal_size) : FileBuffer(allocator, FileBufferType::BLOCK, internal_size), id(id) { - D_ASSERT((GetMallocedSize() & (Storage::SECTOR_SIZE - 1)) == 0); + D_ASSERT((AllocSize() & (Storage::SECTOR_SIZE - 1)) == 0); } Block::Block(FileBuffer &source, block_id_t id) : FileBuffer(source, FileBufferType::BLOCK), id(id) { - D_ASSERT((GetMallocedSize() & (Storage::SECTOR_SIZE - 1)) == 0); + D_ASSERT((AllocSize() & (Storage::SECTOR_SIZE - 1)) == 0); } } // namespace duckdb @@ -212863,7 +225574,7 @@ namespace duckdb { BufferHandle::BufferHandle() : handle(nullptr), node(nullptr) { } -BufferHandle::BufferHandle(shared_ptr handle, FileBuffer *node) : handle(move(handle)), node(node) { +BufferHandle::BufferHandle(shared_ptr handle, FileBuffer *node) : handle(std::move(handle)), node(node) { } BufferHandle::BufferHandle(BufferHandle &&other) noexcept { @@ -213053,6 +225764,7 @@ class InMemoryBlockManager : public BlockManager { + namespace duckdb { BufferPoolReservation::BufferPoolReservation(BufferPoolReservation &&src) noexcept { @@ -213101,10 +225813,10 @@ BlockHandle::BlockHandle(BlockManager &block_manager, block_id_t block_id_p, uni bool can_destroy_p, idx_t block_size, BufferPoolReservation &&reservation) : block_manager(block_manager), readers(0), block_id(block_id_p), eviction_timestamp(0), can_destroy(can_destroy_p), unswizzled(nullptr) { - buffer = move(buffer_p); + buffer = std::move(buffer_p); state = BlockState::BLOCK_LOADED; memory_usage = block_size; - memory_charge = move(reservation); + memory_charge = std::move(reservation); } BlockHandle::~BlockHandle() { @@ -213132,7 +225844,7 @@ unique_ptr AllocateBlock(BlockManager &block_manager, unique_ptr(move(reusable_buffer)); + return unique_ptr_cast(std::move(reusable_buffer)); } auto block = block_manager.CreateBlock(block_id, reusable_buffer.get()); reusable_buffer.reset(); @@ -213143,10 +225855,14 @@ unique_ptr AllocateBlock(BlockManager &block_manager, unique_ptr(size + Storage::BLOCK_HEADER_SIZE); +} + unique_ptr BufferManager::ConstructManagedBuffer(idx_t size, unique_ptr &&source, FileBufferType type) { if (source) { - auto tmp = move(source); + auto tmp = std::move(source); D_ASSERT(tmp->AllocSize() == BufferManager::GetAllocSize(size)); return make_unique(*tmp, type); } else { @@ -213164,14 +225880,15 @@ BufferHandle BlockHandle::Load(shared_ptr &handle, unique_ptrblock_manager; if (handle->block_id < MAXIMUM_BLOCK) { - auto block = AllocateBlock(block_manager, move(reusable_buffer), handle->block_id); + auto block = AllocateBlock(block_manager, std::move(reusable_buffer), handle->block_id); block_manager.Read(*block); - handle->buffer = move(block); + handle->buffer = std::move(block); } else { if (handle->can_destroy) { return BufferHandle(); } else { - handle->buffer = block_manager.buffer_manager.ReadTemporaryBuffer(handle->block_id, move(reusable_buffer)); + handle->buffer = + block_manager.buffer_manager.ReadTemporaryBuffer(handle->block_id, std::move(reusable_buffer)); } } handle->state = BlockState::BLOCK_LOADED; @@ -213192,7 +225909,7 @@ unique_ptr BlockHandle::UnloadAndTakeBlock() { } memory_charge.Resize(block_manager.buffer_manager.current_memory, 0); state = BlockState::BLOCK_UNLOADED; - return move(buffer); + return std::move(buffer); } void BlockHandle::Unload() { @@ -213222,7 +225939,7 @@ struct BufferEvictionNode { BufferEvictionNode() { } BufferEvictionNode(weak_ptr handle_p, idx_t timestamp_p) - : handle(move(handle_p)), timestamp(timestamp_p) { + : handle(std::move(handle_p)), timestamp(timestamp_p) { D_ASSERT(!handle.expired()); } @@ -213277,11 +225994,11 @@ void BufferManager::SetTemporaryDirectory(string new_dir) { if (temp_directory_handle) { throw NotImplementedException("Cannot switch temporary directory after the current one has been used"); } - this->temp_directory = move(new_dir); + this->temp_directory = std::move(new_dir); } BufferManager::BufferManager(DatabaseInstance &db, string tmp, idx_t maximum_memory) - : db(db), current_memory(0), maximum_memory(maximum_memory), temp_directory(move(tmp)), + : db(db), current_memory(0), maximum_memory(maximum_memory), temp_directory(std::move(tmp)), queue(make_unique()), temporary_id(MAXIMUM_BLOCK), queue_insertions(0), buffer_allocator(BufferAllocatorAllocate, BufferAllocatorFree, BufferAllocatorRealloc, make_unique(*this)) { @@ -213291,7 +226008,7 @@ BufferManager::BufferManager(DatabaseInstance &db, string tmp, idx_t maximum_mem BufferManager::~BufferManager() { } -shared_ptr BlockManager::RegisterBlock(block_id_t block_id) { +shared_ptr BlockManager::RegisterBlock(block_id_t block_id, bool is_meta_block) { lock_guard lock(blocks_lock); // check if the block already exists auto entry = blocks.find(block_id); @@ -213305,11 +226022,19 @@ shared_ptr BlockManager::RegisterBlock(block_id_t block_id) { } // create a new block pointer for this block auto result = make_shared(*this, block_id); + // for meta block, cache the handle in meta_blocks + if (is_meta_block) { + meta_blocks[block_id] = result; + } // register the block pointer in the set of blocks as a weak pointer blocks[block_id] = weak_ptr(result); return result; } +void BlockManager::ClearMetaBlockHandles() { + meta_blocks.clear(); +} + shared_ptr BlockManager::ConvertToPersistent(block_id_t block_id, shared_ptr old_block) { // pin the old block to ensure we have it loaded in memory @@ -213330,7 +226055,7 @@ shared_ptr BlockManager::ConvertToPersistent(block_id_t block_id, s new_block->state = BlockState::BLOCK_LOADED; new_block->buffer = CreateBlock(block_id, old_block->buffer.get()); new_block->memory_usage = old_block->memory_usage; - new_block->memory_charge = move(old_block->memory_charge); + new_block->memory_charge = std::move(old_block->memory_charge); // clear the old buffer and unload it old_block->buffer.reset(); @@ -213354,7 +226079,7 @@ TempBufferPoolReservation BufferManager::EvictBlocksOrThrow(idx_t memory_delta, if (!r.success) { throw OutOfMemoryException(args..., InMemoryWarning()); } - return move(r.reservation); + return std::move(r.reservation); } shared_ptr BufferManager::RegisterSmallMemory(idx_t block_size) { @@ -213366,7 +226091,8 @@ shared_ptr BufferManager::RegisterSmallMemory(idx_t block_size) { auto buffer = ConstructManagedBuffer(block_size, nullptr, FileBufferType::TINY_BUFFER); // create a new block pointer for this block - return make_shared(*temp_block_manager, ++temporary_id, move(buffer), false, block_size, move(res)); + return make_shared(*temp_block_manager, ++temporary_id, std::move(buffer), false, block_size, + std::move(res)); } shared_ptr BufferManager::RegisterMemory(idx_t block_size, bool can_destroy) { @@ -213378,11 +226104,11 @@ shared_ptr BufferManager::RegisterMemory(idx_t block_size, bool can "could not allocate block of %lld bytes (%lld/%lld used) %s", alloc_size, GetUsedMemory(), GetMaxMemory()); - auto buffer = ConstructManagedBuffer(block_size, move(reusable_buffer)); + auto buffer = ConstructManagedBuffer(block_size, std::move(reusable_buffer)); // create a new block pointer for this block - return make_shared(*temp_block_manager, ++temporary_id, move(buffer), can_destroy, alloc_size, - move(res)); + return make_shared(*temp_block_manager, ++temporary_id, std::move(buffer), can_destroy, alloc_size, + std::move(res)); } BufferHandle BufferManager::Allocate(idx_t block_size, bool can_destroy, shared_ptr *block) { @@ -213410,7 +226136,7 @@ void BufferManager::ReAllocate(shared_ptr &handle, idx_t block_size EvictBlocksOrThrow(memory_delta, maximum_memory, nullptr, "failed to resize block from %lld to %lld%s", handle->memory_usage, req.alloc_size); // EvictBlocks decrements 'current_memory' for us. - handle->memory_charge.Merge(move(reservation)); + handle->memory_charge.Merge(std::move(reservation)); } else { // no need to evict blocks, but we do need to decrement 'current_memory'. handle->memory_charge.Resize(current_memory, req.alloc_size); @@ -213451,8 +226177,8 @@ BufferHandle BufferManager::Pin(shared_ptr &handle) { // now we can actually load the current block D_ASSERT(handle->readers == 0); handle->readers = 1; - auto buf = handle->Load(handle, move(reusable_buffer)); - handle->memory_charge = move(reservation); + auto buf = handle->Load(handle, std::move(reusable_buffer)); + handle->memory_charge = std::move(reservation); // In the case of a variable sized block, the buffer may be smaller than a full block. int64_t delta = handle->buffer->AllocSize() - handle->memory_usage; if (delta) { @@ -213481,8 +226207,8 @@ void BufferManager::VerifyZeroReaders(shared_ptr &handle) { auto replacement_buffer = make_unique(Allocator::Get(db), handle->buffer->type, handle->memory_usage - Storage::BLOCK_HEADER_SIZE); memcpy(replacement_buffer->buffer, handle->buffer->buffer, handle->buffer->size); - memset(handle->buffer->buffer, 190, handle->buffer->size); - handle->buffer = move(replacement_buffer); + memset(handle->buffer->buffer, 165, handle->buffer->size); // 165 is default memory in debug mode + handle->buffer = std::move(replacement_buffer); #endif } @@ -213508,7 +226234,7 @@ BufferManager::EvictionResult BufferManager::EvictBlocks(idx_t extra_memory, idx if (!queue->q.try_dequeue(node)) { // Failed to reserve. Adjust size of temp reservation to 0. r.Resize(current_memory, 0); - return {false, move(r)}; + return {false, std::move(r)}; } // get a reference to the underlying block pointer auto handle = node.TryGetBlockHandle(); @@ -213525,13 +226251,13 @@ BufferManager::EvictionResult BufferManager::EvictBlocks(idx_t extra_memory, idx if (buffer && handle->buffer->AllocSize() == extra_memory) { // we can actually re-use the memory directly! *buffer = handle->UnloadAndTakeBlock(); - return {true, move(r)}; + return {true, std::move(r)}; } else { // release the memory and mark the block as unloaded handle->Unload(); } } - return {true, move(r)}; + return {true, std::move(r)}; } void BufferManager::PurgeQueue() { @@ -213544,7 +226270,7 @@ void BufferManager::PurgeQueue() { if (!handle) { continue; } else { - queue->q.enqueue(move(node)); + queue->q.enqueue(std::move(node)); break; } } @@ -213585,12 +226311,24 @@ void BufferManager::SetLimit(idx_t limit) { } } +void BufferManager::IncreaseUsedMemory(idx_t size) { + if (current_memory + size > maximum_memory) { + throw OutOfMemoryException("Failed to allocate data of size %lld%s", size, InMemoryWarning()); + } + current_memory += size; +} + +void BufferManager::DecreaseUsedMemory(idx_t size) { + D_ASSERT(current_memory >= size); + current_memory -= size; +} + //===--------------------------------------------------------------------===// // Temporary File Management //===--------------------------------------------------------------------===// unique_ptr ReadTemporaryBufferInternal(BufferManager &buffer_manager, FileHandle &handle, idx_t position, idx_t size, block_id_t id, unique_ptr reusable_buffer) { - auto buffer = buffer_manager.ConstructManagedBuffer(size, move(reusable_buffer)); + auto buffer = buffer_manager.ConstructManagedBuffer(size, std::move(reusable_buffer)); buffer->Read(handle, position); return buffer; } @@ -213713,7 +226451,7 @@ class TemporaryFileHandle { unique_ptr reusable_buffer) { auto buffer = ReadTemporaryBufferInternal(BufferManager::GetBufferManager(db), *handle, GetPositionInFile(block_index), - Storage::BLOCK_SIZE, id, move(reusable_buffer)); + Storage::BLOCK_SIZE, id, std::move(reusable_buffer)); { // remove the block (and potentially truncate the temp file) TemporaryFileLock lock(file_lock); @@ -213751,9 +226489,9 @@ class TemporaryFileHandle { if (index_manager.RemoveIndex(index)) { // the max_index that is currently in use has decreased // as a result we can truncate the file +#ifndef WIN32 // this ended up causing issues when sorting auto max_index = index_manager.GetMaxIndex(); auto &fs = FileSystem::GetFileSystem(db); -#ifndef WIN32 // this ended up causing issues when sorting fs.Truncate(*handle, GetPositionInFile(max_index + 1)); #endif } @@ -213807,7 +226545,7 @@ class TemporaryFileManager { auto new_file_index = index_manager.GetNewBlockIndex(); auto new_file = make_unique(db, temp_directory, new_file_index); handle = new_file.get(); - files[new_file_index] = move(new_file); + files[new_file_index] = std::move(new_file); index = handle->TryGetBlockIndex(); } @@ -213832,7 +226570,7 @@ class TemporaryFileManager { index = GetTempBlockIndex(lock, id); handle = GetFileHandle(lock, index.file_index); } - auto buffer = handle->ReadTemporaryBuffer(id, index.block_index, move(reusable_buffer)); + auto buffer = handle->ReadTemporaryBuffer(id, index.block_index, std::move(reusable_buffer)); { // remove the block (and potentially erase the temp file) TemporaryManagerLock lock(manager_lock); @@ -213884,7 +226622,7 @@ class TemporaryFileManager { }; TemporaryDirectoryHandle::TemporaryDirectoryHandle(DatabaseInstance &db, string path_p) - : db(db), temp_directory(move(path_p)), temp_file(make_unique(db, temp_directory)) { + : db(db), temp_directory(std::move(path_p)), temp_file(make_unique(db, temp_directory)) { auto &fs = FileSystem::GetFileSystem(db); if (!temp_directory.empty()) { fs.CreateDirectory(temp_directory); @@ -213942,7 +226680,7 @@ unique_ptr BufferManager::ReadTemporaryBuffer(block_id_t id, unique_ D_ASSERT(!temp_directory.empty()); D_ASSERT(temp_directory_handle.get()); if (temp_directory_handle->GetTempFile().HasTemporaryBuffer(id)) { - return temp_directory_handle->GetTempFile().ReadTemporaryBuffer(id, move(reusable_buffer)); + return temp_directory_handle->GetTempFile().ReadTemporaryBuffer(id, std::move(reusable_buffer)); } idx_t block_size; // open the temporary file and read the size @@ -213952,7 +226690,8 @@ unique_ptr BufferManager::ReadTemporaryBuffer(block_id_t id, unique_ handle->Read(&block_size, sizeof(idx_t), 0); // now allocate a buffer of this size and read the data into that buffer - auto buffer = ReadTemporaryBufferInternal(*this, *handle, sizeof(idx_t), block_size, id, move(reusable_buffer)); + auto buffer = + ReadTemporaryBufferInternal(*this, *handle, sizeof(idx_t), block_size, id, std::move(reusable_buffer)); handle.reset(); DeleteTemporaryFile(id); @@ -214051,6 +226790,10 @@ Allocator &BufferAllocator::Get(DatabaseInstance &db) { return BufferManager::GetBufferManager(db).GetBufferAllocator(); } +Allocator &BufferAllocator::Get(AttachedDatabase &db) { + return BufferAllocator::Get(db.GetDatabase()); +} + Allocator &BufferManager::GetBufferAllocator() { return buffer_allocator; } @@ -214124,7 +226867,7 @@ struct PartialBlockState { }; struct PartialBlock { - explicit PartialBlock(PartialBlockState state) : state(move(state)) { + explicit PartialBlock(PartialBlockState state) : state(std::move(state)) { } virtual ~PartialBlock() { } @@ -214156,10 +226899,10 @@ class PartialBlockManager { // 20% free / 80% utilization static constexpr const idx_t DEFAULT_MAX_PARTIAL_BLOCK_SIZE = Storage::BLOCK_SIZE / 5 * 4; // Max number of shared references to a block. No effective limit by default. - static constexpr const idx_t DEFAULT_MAX_USE_COUNT = 1 << 20; + static constexpr const idx_t DEFAULT_MAX_USE_COUNT = 1u << 20; // No point letting map size grow unbounded. We'll drop blocks with the // least free space first. - static constexpr const idx_t MAX_BLOCK_MAP_SIZE = 1 << 31; + static constexpr const idx_t MAX_BLOCK_MAP_SIZE = 1u << 31; public: PartialBlockManager(BlockManager &block_manager, uint32_t max_partial_block_size = DEFAULT_MAX_PARTIAL_BLOCK_SIZE, @@ -214202,6 +226945,7 @@ class PartialBlockManager { + namespace duckdb { class DatabaseInstance; class ClientContext; @@ -214215,13 +226959,13 @@ class TypeCatalogEntry; class CheckpointWriter { public: - explicit CheckpointWriter(DatabaseInstance &db) : db(db) { + explicit CheckpointWriter(AttachedDatabase &db) : db(db) { } virtual ~CheckpointWriter() { } //! The database - DatabaseInstance &db; + AttachedDatabase &db; virtual MetaBlockWriter &GetMetaBlockWriter() = 0; virtual unique_ptr GetTableDataWriter(TableCatalogEntry &table) = 0; @@ -214239,9 +226983,14 @@ class CheckpointWriter { class CheckpointReader { public: + CheckpointReader(Catalog &catalog) : catalog(catalog) { + } virtual ~CheckpointReader() { } +protected: + Catalog &catalog; + protected: virtual void LoadCheckpoint(ClientContext &context, MetaBlockReader &reader); virtual void ReadSchema(ClientContext &context, MetaBlockReader &reader); @@ -214258,7 +227007,8 @@ class CheckpointReader { class SingleFileCheckpointReader final : public CheckpointReader { public: - explicit SingleFileCheckpointReader(SingleFileStorageManager &storage) : storage(storage) { + explicit SingleFileCheckpointReader(SingleFileStorageManager &storage) + : CheckpointReader(Catalog::GetCatalog(storage.GetAttached())), storage(storage) { } void LoadFromStorage(); @@ -214276,9 +227026,7 @@ class SingleFileCheckpointWriter final : public CheckpointWriter { friend class SingleFileTableDataWriter; public: - explicit SingleFileCheckpointWriter(DatabaseInstance &db, BlockManager &block_manager) - : CheckpointWriter(db), partial_block_manager(block_manager) { - } + SingleFileCheckpointWriter(AttachedDatabase &db, BlockManager &block_manager); //! Checkpoint the current state of the WAL and flush it to the main storage. This should be called BEFORE any //! connection is available because right now the checkpointing cannot be done online. (TODO) @@ -214360,6 +227108,7 @@ class SingleFileRowGroupWriter : public RowGroupWriter { namespace duckdb { +class DuckTableEntry; //! The table data writer is responsible for writing the data of a table to //! storage. @@ -214384,7 +227133,7 @@ class TableDataWriter { virtual void AddRowGroup(RowGroupPointer &&row_group_pointer, unique_ptr &&writer); protected: - TableCatalogEntry &table; + DuckTableEntry &table; // Pointers to the start of each row group. vector row_group_pointers; }; @@ -214463,11 +227212,11 @@ struct ColumnCheckpointState { namespace duckdb { CompressionType RowGroupWriter::GetColumnCompressionType(idx_t i) { - return table.columns.GetColumn(LogicalIndex(i)).CompressionType(); + return table.GetColumn(LogicalIndex(i)).CompressionType(); } void RowGroupWriter::RegisterPartialBlock(PartialBlockAllocation &&allocation) { - partial_block_manager.RegisterPartialBlock(move(allocation)); + partial_block_manager.RegisterPartialBlock(std::move(allocation)); } PartialBlockAllocation RowGroupWriter::GetBlockAllocation(uint32_t segment_size) { @@ -214560,7 +227309,7 @@ void TableDataReader::ReadTableData() { info.data->row_groups.reserve(row_group_count); for (idx_t i = 0; i < row_group_count; i++) { auto row_group_pointer = RowGroup::Deserialize(reader, columns); - info.data->row_groups.push_back(move(row_group_pointer)); + info.data->row_groups.push_back(std::move(row_group_pointer)); } } @@ -214572,9 +227321,11 @@ void TableDataReader::ReadTableData() { + namespace duckdb { -TableDataWriter::TableDataWriter(TableCatalogEntry &table) : table(table) { +TableDataWriter::TableDataWriter(TableCatalogEntry &table_p) : table((DuckTableEntry &)table_p) { + D_ASSERT(table_p.IsDuckTable()); } TableDataWriter::~TableDataWriter() { @@ -214582,15 +227333,15 @@ TableDataWriter::~TableDataWriter() { void TableDataWriter::WriteTableData() { // start scanning the table and append the data to the uncompressed segments - table.storage->Checkpoint(*this); + table.GetStorage().Checkpoint(*this); } CompressionType TableDataWriter::GetColumnCompressionType(idx_t i) { - return table.columns.GetColumn(LogicalIndex(i)).CompressionType(); + return table.GetColumn(LogicalIndex(i)).CompressionType(); } void TableDataWriter::AddRowGroup(RowGroupPointer &&row_group_pointer, unique_ptr &&writer) { - row_group_pointers.push_back(move(row_group_pointer)); + row_group_pointers.push_back(std::move(row_group_pointer)); writer.reset(); } @@ -214782,12 +227533,17 @@ void WriteOverflowStringsToDisk::AllocateNewBlock(block_id_t new_block_id) { + namespace duckdb { void ReorderTableEntries(vector &tables); +SingleFileCheckpointWriter::SingleFileCheckpointWriter(AttachedDatabase &db, BlockManager &block_manager) + : CheckpointWriter(db), partial_block_manager(block_manager) { +} + BlockManager &SingleFileCheckpointWriter::GetBlockManager() { auto &storage_manager = (SingleFileStorageManager &)db.GetStorageManager(); return *storage_manager.block_manager; @@ -214802,7 +227558,7 @@ unique_ptr SingleFileCheckpointWriter::GetTableDataWriter(Table } void SingleFileCheckpointWriter::CreateCheckpoint() { - auto &config = DBConfig::GetConfig(db); + auto &config = DBConfig::Get(db); auto &storage_manager = (SingleFileStorageManager &)db.GetStorageManager(); if (storage_manager.InMemory()) { return; @@ -214821,8 +227577,8 @@ void SingleFileCheckpointWriter::CreateCheckpoint() { vector schemas; // we scan the set of committed schemas - auto &catalog = Catalog::GetCatalog(db); - catalog.schemas->Scan([&](CatalogEntry *entry) { schemas.push_back((SchemaCatalogEntry *)entry); }); + auto &catalog = (DuckCatalog &)Catalog::GetCatalog(db); + catalog.ScanSchemas([&](CatalogEntry *entry) { schemas.push_back((SchemaCatalogEntry *)entry); }); // write the actual data into the database // write the amount of schemas metadata_writer->Write(schemas.size()); @@ -214872,7 +227628,7 @@ void SingleFileCheckpointReader::LoadFromStorage() { return; } - Connection con(storage.db); + Connection con(storage.GetDatabase()); con.BeginTransaction(); // create the MetaBlockReader to read from the storage MetaBlockReader reader(block_manager, meta_block); @@ -214996,8 +227752,6 @@ void CheckpointWriter::WriteSchema(SchemaCatalogEntry &schema) { } void CheckpointReader::ReadSchema(ClientContext &context, MetaBlockReader &reader) { - auto &catalog = Catalog::GetCatalog(context); - // read the schema and create it in the catalog auto info = SchemaCatalogEntry::Deserialize(reader); // we set create conflict to ignore to ignore the failure of recreating the main schema @@ -215055,8 +227809,6 @@ void CheckpointWriter::WriteView(ViewCatalogEntry &view) { void CheckpointReader::ReadView(ClientContext &context, MetaBlockReader &reader) { auto info = ViewCatalogEntry::Deserialize(reader, context); - - auto &catalog = Catalog::GetCatalog(context); catalog.CreateView(context, info.get()); } @@ -215069,8 +227821,6 @@ void CheckpointWriter::WriteSequence(SequenceCatalogEntry &seq) { void CheckpointReader::ReadSequence(ClientContext &context, MetaBlockReader &reader) { auto info = SequenceCatalogEntry::Deserialize(reader); - - auto &catalog = Catalog::GetCatalog(context); catalog.CreateSequence(context, info.get()); } @@ -215094,12 +227844,11 @@ void CheckpointReader::ReadIndex(ClientContext &context, MetaBlockReader &reader auto info = IndexCatalogEntry::Deserialize(reader, context); // Create index in the catalog - auto &catalog = Catalog::GetCatalog(context); auto schema_catalog = catalog.GetSchema(context, info->schema); auto table_catalog = - (TableCatalogEntry *)catalog.GetEntry(context, CatalogType::TABLE_ENTRY, info->schema, info->table->table_name); - auto index_catalog = (IndexCatalogEntry *)schema_catalog->CreateIndex(context, info.get(), table_catalog); - index_catalog->info = table_catalog->storage->info; + (DuckTableEntry *)catalog.GetEntry(context, CatalogType::TABLE_ENTRY, info->schema, info->table->table_name); + auto index_catalog = (DuckIndexEntry *)schema_catalog->CreateIndex(context, info.get(), table_catalog); + index_catalog->info = table_catalog->GetStorage().info; // Here we just gotta read the root node auto root_block_id = reader.Read(); auto root_offset = reader.Read(); @@ -215127,7 +227876,7 @@ void CheckpointReader::ReadIndex(ClientContext &context, MetaBlockReader &reader // column refs unbound_expressions.reserve(info->column_ids.size()); for (idx_t key_nr = 0; key_nr < info->column_ids.size(); key_nr++) { - auto &col = table_catalog->columns.GetColumn(LogicalIndex(info->column_ids[key_nr])); + auto &col = table_catalog->GetColumn(LogicalIndex(info->column_ids[key_nr])); unbound_expressions.push_back( make_unique(col.GetName(), col.GetType(), ColumnBinding(0, key_nr))); } @@ -215135,11 +227884,11 @@ void CheckpointReader::ReadIndex(ClientContext &context, MetaBlockReader &reader switch (info->index_type) { case IndexType::ART: { - auto art = - make_unique(info->column_ids, TableIOManager::Get(*table_catalog->storage), move(unbound_expressions), - info->constraint_type, *context.db, root_block_id, root_offset); + auto &storage = table_catalog->GetStorage(); + auto art = make_unique(info->column_ids, TableIOManager::Get(storage), std::move(unbound_expressions), + info->constraint_type, storage.db, true, root_block_id, root_offset); index_catalog->index = art.get(); - table_catalog->storage->info->indexes.AddIndex(move(art)); + storage.info->indexes.AddIndex(std::move(art)); break; } default: @@ -215156,8 +227905,6 @@ void CheckpointWriter::WriteType(TypeCatalogEntry &table) { void CheckpointReader::ReadType(ClientContext &context, MetaBlockReader &reader) { auto info = TypeCatalogEntry::Deserialize(reader); - - auto &catalog = Catalog::GetCatalog(context); catalog.CreateType(context, info.get()); } @@ -215170,7 +227917,6 @@ void CheckpointWriter::WriteMacro(ScalarMacroCatalogEntry ¯o) { void CheckpointReader::ReadMacro(ClientContext &context, MetaBlockReader &reader) { auto info = ScalarMacroCatalogEntry::Deserialize(reader, context); - auto &catalog = Catalog::GetCatalog(context); catalog.CreateFunction(context, info.get()); } @@ -215180,7 +227926,6 @@ void CheckpointWriter::WriteTableMacro(TableMacroCatalogEntry ¯o) { void CheckpointReader::ReadTableMacro(ClientContext &context, MetaBlockReader &reader) { auto info = TableMacroCatalogEntry::Deserialize(reader, context); - auto &catalog = Catalog::GetCatalog(context); catalog.CreateFunction(context, info.get()); } @@ -215201,13 +227946,13 @@ void CheckpointReader::ReadTable(ClientContext &context, MetaBlockReader &reader auto info = TableCatalogEntry::Deserialize(reader, context); // bind the info auto binder = Binder::CreateBinder(context); - auto bound_info = binder->BindCreateTableInfo(move(info)); + auto schema = catalog.GetSchema(context, info->schema); + auto bound_info = binder->BindCreateTableInfo(std::move(info), schema); // now read the actual table data and place it into the create table info ReadTableData(context, reader, *bound_info); // finally create the table in the catalog - auto &catalog = Catalog::GetCatalog(context); catalog.CreateTable(context, bound_info.get()); } @@ -216688,6 +229433,7 @@ class DatabaseInstance; class RowGroup; class RowGroupWriter; class TableDataWriter; +class TableStorageInfo; struct TransactionData; struct DataTableInfo; @@ -216786,7 +229532,7 @@ class ColumnData { idx_t start_row, Deserializer &source, const LogicalType &type, ColumnData *parent); - virtual void GetStorageInfo(idx_t row_group_index, vector col_path, vector> &result); + virtual void GetStorageInfo(idx_t row_group_index, vector col_path, TableStorageInfo &result); virtual void Verify(RowGroup &parent); static shared_ptr CreateColumn(BlockManager &block_manager, DataTableInfo &info, idx_t column_index, @@ -216862,112 +229608,290 @@ class ColumnDataCheckpointer { + #include namespace duckdb { -// Note that optimizations in scanning only work if this value is equal to STANDARD_VECTOR_SIZE, however we keep them -// separated to prevent the code from break on lower vector sizes -static constexpr const idx_t BITPACKING_METADATA_GROUP_SIZE = 1024; +static constexpr const idx_t BITPACKING_METADATA_GROUP_SIZE = STANDARD_VECTOR_SIZE > 512 ? STANDARD_VECTOR_SIZE : 2048; + +BitpackingMode BitpackingModeFromString(const string &str) { + auto mode = StringUtil::Lower(str); + + if (mode == "auto") { + return BitpackingMode::AUTO; + } else if (mode == "constant") { + return BitpackingMode::CONSTANT; + } else if (mode == "constant_delta") { + return BitpackingMode::CONSTANT_DELTA; + } else if (mode == "delta_for") { + return BitpackingMode::DELTA_FOR; + } else if (mode == "for") { + return BitpackingMode::FOR; + } else { + return BitpackingMode::AUTO; + } +} + +string BitpackingModeToString(const BitpackingMode &mode) { + switch (mode) { + case (BitpackingMode::AUTO): + return "auto"; + case (BitpackingMode::CONSTANT): + return "constant"; + case (BitpackingMode::CONSTANT_DELTA): + return "constant_delta"; + case (BitpackingMode::DELTA_FOR): + return "delta_for"; + case (BitpackingMode::FOR): + return "for"; + default: + throw NotImplementedException("Unknown bitpacking mode: " + to_string((uint8_t)mode) + "\n"); + } +} + +typedef struct { + BitpackingMode mode; + uint32_t offset; +} bitpacking_metadata_t; + +typedef uint32_t bitpacking_metadata_encoded_t; + +static bitpacking_metadata_encoded_t EncodeMeta(bitpacking_metadata_t metadata) { + D_ASSERT(metadata.offset <= 16777215); // max uint24_t + bitpacking_metadata_encoded_t encoded_value = metadata.offset; + encoded_value |= (uint8_t)metadata.mode << 24; + return encoded_value; +} +static bitpacking_metadata_t DecodeMeta(bitpacking_metadata_encoded_t *metadata_encoded) { + bitpacking_metadata_t metadata; + metadata.mode = Load((data_ptr_t)(metadata_encoded) + 3); + metadata.offset = *metadata_encoded & 0x00FFFFFF; + return metadata; +} struct EmptyBitpackingWriter { template - static void Operation(T *values, bool *validity, bitpacking_width_t width, T frame_of_reference, idx_t count, - void *data_ptr) { + static void WriteConstant(T constant, idx_t count, void *data_ptr, bool all_invalid) { + } + template ::type> + static void WriteConstantDelta(T_S constant, T frame_of_reference, idx_t count, T *values, bool *validity, + void *data_ptr) { + } + template ::type> + static void WriteDeltaFor(T *values, bool *validity, bitpacking_width_t width, T frame_of_reference, + T_S delta_offset, T *original_values, idx_t count, void *data_ptr) { + } + template + static void WriteFor(T *values, bool *validity, bitpacking_width_t width, T frame_of_reference, idx_t count, + void *data_ptr) { } }; -template +template ::type, class T_S = typename std::make_signed::type> struct BitpackingState { public: BitpackingState() : compression_buffer_idx(0), total_size(0), data_ptr(nullptr) { - ResetMinMax(); + compression_buffer_internal[0] = (T)0; + compression_buffer = &compression_buffer_internal[1]; + Reset(); } - T compression_buffer[BITPACKING_METADATA_GROUP_SIZE]; + // Extra val for delta encoding + T compression_buffer_internal[BITPACKING_METADATA_GROUP_SIZE + 1]; + T *compression_buffer; + T_S delta_buffer[BITPACKING_METADATA_GROUP_SIZE]; bool compression_buffer_validity[BITPACKING_METADATA_GROUP_SIZE]; idx_t compression_buffer_idx; idx_t total_size; + + // Used to pass CompressionState ptr through the Bitpacking writer void *data_ptr; - bool min_max_set; + // Stats on current compression buffer T minimum; T maximum; + T min_max_diff; + T_S minimum_delta; + T_S maximum_delta; + T_S min_max_delta_diff; + T_S delta_offset; + bool all_valid; + bool all_invalid; + + bool can_do_delta; + bool can_do_for; + + // Used to force a specific mode, useful in testing + BitpackingMode mode = BitpackingMode::AUTO; public: - void SubtractFrameOfReference(const T &frame_of_reference) { - for (idx_t i = 0; i < compression_buffer_idx; i++) { - compression_buffer[i] -= frame_of_reference; - } + void Reset() { + minimum = NumericLimits::Maximum(); + minimum_delta = NumericLimits::Maximum(); + maximum = NumericLimits::Minimum(); + maximum_delta = NumericLimits::Minimum(); + delta_offset = 0; + all_valid = true; + all_invalid = true; + can_do_delta = false; + can_do_for = false; + compression_buffer_idx = 0; + min_max_diff = 0; + min_max_delta_diff = 0; } - void ResetMinMax() { - min_max_set = false; - //! We set these to 0, in case all values are NULL, in which case the min and max will never be set. - minimum = 0; - maximum = 0; + void CalculateFORStats() { + can_do_for = TrySubtractOperator::Operation(maximum, minimum, min_max_diff); } - bool TryUpdateMinMax(T value) { - bool updated = false; - if (!min_max_set || value < minimum) { - minimum = value; - updated = true; + void CalculateDeltaStats() { + // TODO: currently we dont support delta compression of values above NumericLimits::Maximum(), + // we could support this with some clever substract trickery? + if (maximum > (T)NumericLimits::Maximum()) { + return; } - if (!min_max_set || value > maximum) { - maximum = value; - updated = true; + + // Don't delta encoding 1 value makes no sense + if (compression_buffer_idx < 2) { + return; + }; + + // TODO: handle NULLS here? + // Currently we cannot handle nulls because we would need an additional step of patching for this. + // we could for example copy the last value on a null insert. This would help a bit, but not be optimal for + // large deltas since theres suddenly a zero then. Ideally we would insert a value that leads to a delta within + // the current domain of deltas however we dont know that domain here yet + if (!all_valid) { + return; } - min_max_set = min_max_set || updated; - //! Only when either of the values are updated, do we need to test the overflow - if (updated) { - T ignore; - return TrySubtractOperator::Operation(maximum, minimum, ignore); + + // Note: since we dont allow any values over NumericLimits::Maximum(), all subtractions for unsigned types + // are guaranteed not to overflow + bool can_do_all = true; + if (std::is_signed()) { + T_S bogus; + can_do_all = TrySubtractOperator::Operation((T_S)(minimum), (T_S)(maximum), bogus) && + TrySubtractOperator::Operation((T_S)(maximum), (T_S)(minimum), bogus); } - return true; - } - T GetFrameOfReference() { - return minimum; + // Calculate delta's + if (can_do_all) { + for (int64_t i = 0; i < (int64_t)compression_buffer_idx; i++) { + delta_buffer[i] = (T_S)compression_buffer[i] - (T_S)compression_buffer[i - 1]; + } + } else { + for (int64_t i = 0; i < (int64_t)compression_buffer_idx; i++) { + auto success = TrySubtractOperator::Operation((T_S)(compression_buffer[i]), + (T_S)(compression_buffer[i - 1]), delta_buffer[i]); + if (!success) { + return; + } + } + } + + can_do_delta = true; + + for (int64_t i = 1; i < (int64_t)compression_buffer_idx; i++) { + maximum_delta = MaxValue(maximum_delta, delta_buffer[i]); + minimum_delta = MinValue(minimum_delta, delta_buffer[i]); + } + + // Since we can set the first value arbitrarily, we want to pick one from the current domain, note that + // we will store the original first value - this offset as the delta_offset to be able to decode this again. + delta_buffer[0] = minimum_delta; + + can_do_delta = can_do_delta && TrySubtractOperator::Operation(maximum_delta, minimum_delta, min_max_delta_diff); + can_do_delta = + can_do_delta && TrySubtractOperator::Operation((T_S)(compression_buffer[0]), minimum_delta, delta_offset); } - T Maximum() { - return maximum; + + template + void SubtractFrameOfReference(T_INNER *buffer, T_INNER frame_of_reference) { + static_assert(std::is_integral::value, "Integral type required."); + for (idx_t i = 0; i < compression_buffer_idx; i++) { + buffer[i] -= uint64_t(frame_of_reference); + } } - template ::type> - void Flush() { - T frame_of_reference = GetFrameOfReference(); - SubtractFrameOfReference(frame_of_reference); + template + bool Flush() { + if (compression_buffer_idx == 0) { + return true; + } + + if ((all_invalid || maximum == minimum) && (mode == BitpackingMode::AUTO || mode == BitpackingMode::CONSTANT)) { + OP::WriteConstant(maximum, compression_buffer_idx, data_ptr, all_invalid); + total_size += sizeof(T) + sizeof(bitpacking_metadata_encoded_t); + return true; + } - //! Because of FOR, we can guarantee that all values are positive - T_U adjusted_maximum = T_U(Maximum() - frame_of_reference); + CalculateFORStats(); + CalculateDeltaStats(); - bitpacking_width_t width = BitpackingPrimitives::MinimumBitWidth((T_U)0, adjusted_maximum); - OP::template Operation(compression_buffer, compression_buffer_validity, width, frame_of_reference, - compression_buffer_idx, data_ptr); - total_size += (BITPACKING_METADATA_GROUP_SIZE * width) / 8 + sizeof(bitpacking_width_t) + sizeof(T); - compression_buffer_idx = 0; - ResetMinMax(); + if (can_do_delta) { + if (maximum_delta == minimum_delta && mode != BitpackingMode::FOR && mode != BitpackingMode::DELTA_FOR) { + idx_t frame_of_reference = compression_buffer[0]; + OP::WriteConstantDelta((T_S)maximum_delta, (T)frame_of_reference, compression_buffer_idx, + (T *)compression_buffer, (bool *)compression_buffer_validity, data_ptr); + total_size += sizeof(T) + sizeof(T) + sizeof(bitpacking_metadata_encoded_t); + return true; + } + + // Check if delta has benefit + auto delta_required_bitwidth = BitpackingPrimitives::MinimumBitWidth(min_max_delta_diff); + auto regular_required_bitwidth = BitpackingPrimitives::MinimumBitWidth(min_max_diff); + + if (delta_required_bitwidth < regular_required_bitwidth && mode != BitpackingMode::FOR) { + SubtractFrameOfReference(delta_buffer, minimum_delta); + + OP::WriteDeltaFor((T *)delta_buffer, compression_buffer_validity, delta_required_bitwidth, + (T)minimum_delta, delta_offset, (T *)compression_buffer, compression_buffer_idx, + data_ptr); + + total_size += BitpackingPrimitives::GetRequiredSize(compression_buffer_idx, delta_required_bitwidth); + total_size += sizeof(T); // FOR value + total_size += sizeof(T); // Delta offset value + total_size += AlignValue(sizeof(bitpacking_width_t)); // FOR value + + return true; + } + } + + if (can_do_for) { + auto width = BitpackingPrimitives::MinimumBitWidth(min_max_diff); + SubtractFrameOfReference(compression_buffer, minimum); + OP::WriteFor(compression_buffer, compression_buffer_validity, width, minimum, compression_buffer_idx, + data_ptr); + + total_size += BitpackingPrimitives::GetRequiredSize(compression_buffer_idx, width); + total_size += sizeof(T); // FOR value + total_size += AlignValue(sizeof(bitpacking_width_t)); + + return true; + } + + return false; } template - bool Update(T *data, ValidityMask &validity, idx_t idx) { + bool Update(T value, bool is_valid) { + compression_buffer_validity[compression_buffer_idx] = is_valid; + all_valid = all_valid && is_valid; + all_invalid = all_invalid && !is_valid; - if (validity.RowIsValid(idx)) { - compression_buffer_validity[compression_buffer_idx] = true; - compression_buffer[compression_buffer_idx++] = data[idx]; - if (!TryUpdateMinMax(data[idx])) { - return false; - } - } else { - // We write zero for easy bitwidth analysis of the compression buffer later - compression_buffer_validity[compression_buffer_idx] = false; - compression_buffer[compression_buffer_idx++] = 0; + if (is_valid) { + compression_buffer[compression_buffer_idx] = value; + minimum = MinValue(minimum, value); + maximum = MaxValue(maximum, value); } + compression_buffer_idx++; + if (compression_buffer_idx == BITPACKING_METADATA_GROUP_SIZE) { - // Calculate bitpacking width; - Flush(); + bool success = Flush(); + Reset(); + return success; } return true; } @@ -216983,7 +229907,12 @@ struct BitpackingAnalyzeState : public AnalyzeState { template unique_ptr BitpackingInitAnalyze(ColumnData &col_data, PhysicalType type) { - return make_unique>(); + auto &config = DBConfig::GetConfig(col_data.GetDatabase()); + + auto state = make_unique>(); + state->state.mode = config.options.force_bitpacking_mode; + + return std::move(state); } template @@ -216995,7 +229924,7 @@ bool BitpackingAnalyze(AnalyzeState &state, Vector &input, idx_t count) { auto data = (T *)vdata.data; for (idx_t i = 0; i < count; i++) { auto idx = vdata.sel->get_index(i); - if (!analyze_state.state.template Update(data, vdata.validity, idx)) { + if (!analyze_state.state.template Update(data[idx], vdata.validity.RowIsValid(idx))) { return false; } } @@ -217005,14 +229934,17 @@ bool BitpackingAnalyze(AnalyzeState &state, Vector &input, idx_t count) { template idx_t BitpackingFinalAnalyze(AnalyzeState &state) { auto &bitpacking_state = (BitpackingAnalyzeState &)state; - bitpacking_state.state.template Flush(); + auto flush_result = bitpacking_state.state.template Flush(); + if (!flush_result) { + return DConstants::INVALID_INDEX; + } return bitpacking_state.state.total_size; } //===--------------------------------------------------------------------===// // Compress //===--------------------------------------------------------------------===// -template +template ::type> struct BitpackingCompressState : public CompressionState { public: explicit BitpackingCompressState(ColumnDataCheckpointer &checkpointer) : checkpointer(checkpointer) { @@ -217023,6 +229955,8 @@ struct BitpackingCompressState : public CompressionState { CreateEmptySegment(checkpointer.GetRowGroup().start); state.data_ptr = (void *)this; + + state.mode = config.options.force_bitpacking_mode; } ColumnDataCheckpointer &checkpointer; @@ -217039,33 +229973,88 @@ struct BitpackingCompressState : public CompressionState { public: struct BitpackingWriter { + static void WriteConstant(T constant, idx_t count, void *data_ptr, bool all_invalid) { + auto state = (BitpackingCompressState *)data_ptr; - template - static void Operation(VALUE_TYPE *values, bool *validity, bitpacking_width_t width, - VALUE_TYPE frame_of_reference, idx_t count, void *data_ptr) { + ReserveSpace(state, sizeof(T)); + WriteMetaData(state, BitpackingMode::CONSTANT); + WriteData(state->data_ptr, constant); + + UpdateStats(state, count); + } + + static void WriteConstantDelta(T_S constant, T frame_of_reference, idx_t count, T *values, bool *validity, + void *data_ptr) { auto state = (BitpackingCompressState *)data_ptr; - auto total_bits_needed = (width * BITPACKING_METADATA_GROUP_SIZE); - D_ASSERT(total_bits_needed % 8 == 0); - // FIXME: we call AlignValue in FlushSegment, this could add up to 7 bytes - // That space is unaccounted for here, which on rare occassions might lead to a heap-buffer overflow - auto total_bytes_needed = total_bits_needed / 8; - total_bytes_needed += sizeof(bitpacking_width_t); - total_bytes_needed += sizeof(VALUE_TYPE); - - if (state->RemainingSize() < total_bytes_needed) { - // Segment is full - auto row_start = state->current_segment->start + state->current_segment->count; - state->FlushSegment(); - state->CreateEmptySegment(row_start); - } - for (idx_t i = 0; i < count; i++) { - if (validity[i]) { - NumericStatistics::Update(state->current_segment->stats, values[i] + frame_of_reference); - } - } + ReserveSpace(state, 2 * sizeof(T)); + WriteMetaData(state, BitpackingMode::CONSTANT_DELTA); + WriteData(state->data_ptr, frame_of_reference); + WriteData(state->data_ptr, constant); - state->WriteValues(values, width, frame_of_reference, count); + UpdateStats(state, count); + } + + static void WriteDeltaFor(T *values, bool *validity, bitpacking_width_t width, T frame_of_reference, + T_S delta_offset, T *original_values, idx_t count, void *data_ptr) { + auto state = (BitpackingCompressState *)data_ptr; + + auto bp_size = BitpackingPrimitives::GetRequiredSize(count, width); + ReserveSpace(state, bp_size + 3 * sizeof(T)); + + WriteMetaData(state, BitpackingMode::DELTA_FOR); + WriteData(state->data_ptr, frame_of_reference); + WriteData(state->data_ptr, (T)width); + WriteData(state->data_ptr, delta_offset); + + BitpackingPrimitives::PackBuffer(state->data_ptr, values, count, width); + state->data_ptr += bp_size; + + UpdateStats(state, count); + } + + static void WriteFor(T *values, bool *validity, bitpacking_width_t width, T frame_of_reference, idx_t count, + void *data_ptr) { + auto state = (BitpackingCompressState *)data_ptr; + + auto bp_size = BitpackingPrimitives::GetRequiredSize(count, width); + ReserveSpace(state, bp_size + 2 * sizeof(T)); + + WriteMetaData(state, BitpackingMode::FOR); + WriteData(state->data_ptr, frame_of_reference); + WriteData(state->data_ptr, (T)width); + + BitpackingPrimitives::PackBuffer(state->data_ptr, values, count, width); + state->data_ptr += bp_size; + + UpdateStats(state, count); + } + + template + static void WriteData(data_ptr_t &ptr, T_OUT val) { + *((T_OUT *)ptr) = val; + ptr += sizeof(T_OUT); + } + + static void WriteMetaData(BitpackingCompressState *state, BitpackingMode mode) { + bitpacking_metadata_t metadata {mode, (uint32_t)(state->data_ptr - state->handle.Ptr())}; + state->metadata_ptr -= sizeof(bitpacking_metadata_encoded_t); + Store(EncodeMeta(metadata), state->metadata_ptr); + } + + static void ReserveSpace(BitpackingCompressState *state, idx_t data_bytes) { + idx_t meta_bytes = sizeof(bitpacking_metadata_encoded_t); + state->FlushAndCreateSegmentIfFull(data_bytes + meta_bytes); + D_ASSERT(data_bytes + meta_bytes <= state->RemainingSize()); + } + + static void UpdateStats(BitpackingCompressState *state, idx_t count) { + state->current_segment->count += count; + + if (!state->state.all_invalid) { + NumericStatistics::Update(state->current_segment->stats, state->state.minimum); + NumericStatistics::Update(state->current_segment->stats, state->state.maximum); + } } }; @@ -217079,57 +230068,51 @@ struct BitpackingCompressState : public CompressionState { auto &type = checkpointer.GetType(); auto compressed_segment = ColumnSegment::CreateTransientSegment(db, type, row_start); compressed_segment->function = function; - current_segment = move(compressed_segment); + current_segment = std::move(compressed_segment); auto &buffer_manager = BufferManager::GetBufferManager(db); handle = buffer_manager.Pin(current_segment->block); data_ptr = handle.Ptr() + BitpackingPrimitives::BITPACKING_HEADER_SIZE; - metadata_ptr = handle.Ptr() + Storage::BLOCK_SIZE - sizeof(bitpacking_width_t); + metadata_ptr = handle.Ptr() + Storage::BLOCK_SIZE; } void Append(UnifiedVectorFormat &vdata, idx_t count) { - // TODO Optimization: avoid use of compression buffer if we can compress straight to result vector auto data = (T *)vdata.data; for (idx_t i = 0; i < count; i++) { auto idx = vdata.sel->get_index(i); - state.template Update::BitpackingWriter>(data, vdata.validity, idx); + state.template Update::BitpackingWriter>(data[idx], + vdata.validity.RowIsValid(idx)); } } - void WriteValues(T *values, bitpacking_width_t width, T frame_of_reference, idx_t count) { - // TODO we can optimize this by stopping early if count < BITPACKING_METADATA_GROUP_SIZE - BitpackingPrimitives::PackBuffer(data_ptr, values, count, width); - data_ptr += (BITPACKING_METADATA_GROUP_SIZE * width) / 8; - - Store(width, metadata_ptr); - metadata_ptr -= sizeof(T); - Store(frame_of_reference, metadata_ptr); - metadata_ptr -= sizeof(bitpacking_width_t); - - current_segment->count += count; + void FlushAndCreateSegmentIfFull(idx_t required_space) { + if (RemainingSize() < required_space) { + auto row_start = current_segment->start + current_segment->count; + FlushSegment(); + CreateEmptySegment(row_start); + } } void FlushSegment() { auto &state = checkpointer.GetCheckpointState(); - auto dataptr = handle.Ptr(); + auto base_ptr = handle.Ptr(); // Compact the segment by moving the metadata next to the data. - idx_t metadata_offset = data_ptr - dataptr; - D_ASSERT(ValueIsAligned(metadata_offset)); - idx_t metadata_size = dataptr + Storage::BLOCK_SIZE - metadata_ptr - 1; + idx_t metadata_offset = AlignValue(data_ptr - base_ptr); + idx_t metadata_size = base_ptr + Storage::BLOCK_SIZE - metadata_ptr; idx_t total_segment_size = metadata_offset + metadata_size; - memmove(dataptr + metadata_offset, metadata_ptr + 1, metadata_size); + memmove(base_ptr + metadata_offset, metadata_ptr, metadata_size); // Store the offset of the metadata of the first group (which is at the highest address). - Store(metadata_offset + metadata_size - 1, dataptr); + Store(metadata_offset + metadata_size, base_ptr); handle.Destroy(); - state.FlushSegment(move(current_segment), total_segment_size); + state.FlushSegment(std::move(current_segment), total_segment_size); } void Finalize() { - state.template Flush::BitpackingWriter>(); + state.template Flush::BitpackingWriter>(); FlushSegment(); current_segment.reset(); } @@ -217159,84 +230142,188 @@ void BitpackingFinalizeCompress(CompressionState &state_p) { // Scan //===--------------------------------------------------------------------===// template +static void ApplyFrameOfReference(T *dst, T frame_of_reference, idx_t size) { + if (!frame_of_reference) { + return; + } + for (idx_t i = 0; i < size; i++) { + dst[i] += frame_of_reference; + } +} + +// Based on https://github.com/lemire/FastPFor (Apache License 2.0) +template +static T DeltaDecode(T *data, T previous_value, const size_t size) { + D_ASSERT(size >= 1); + + data[0] += previous_value; + + const size_t UnrollQty = 4; + const size_t sz0 = (size / UnrollQty) * UnrollQty; // equal to 0, if size < UnrollQty + size_t i = 1; + if (sz0 >= UnrollQty) { + T a = data[0]; + for (; i < sz0 - UnrollQty; i += UnrollQty) { + a = data[i] += a; + a = data[i + 1] += a; + a = data[i + 2] += a; + a = data[i + 3] += a; + } + } + for (; i != size; ++i) { + data[i] += data[i - 1]; + } + + return data[size - 1]; +} + +template ::type> struct BitpackingScanState : public SegmentScanState { public: - explicit BitpackingScanState(ColumnSegment &segment) { + explicit BitpackingScanState(ColumnSegment &segment) : current_segment(segment) { auto &buffer_manager = BufferManager::GetBufferManager(segment.db); handle = buffer_manager.Pin(segment.block); auto dataptr = handle.Ptr(); - current_metadata_group_ptr = dataptr + segment.GetBlockOffset() + BitpackingPrimitives::BITPACKING_HEADER_SIZE; // load offset to bitpacking widths pointer auto bitpacking_metadata_offset = Load(dataptr + segment.GetBlockOffset()); - bitpacking_metadata_ptr = dataptr + segment.GetBlockOffset() + bitpacking_metadata_offset; + bitpacking_metadata_ptr = + dataptr + segment.GetBlockOffset() + bitpacking_metadata_offset - sizeof(bitpacking_metadata_encoded_t); - // load the metadata of the first vector - LoadCurrentMetaData(); + // load the first group + LoadNextGroup(); } BufferHandle handle; + ColumnSegment ¤t_segment; - T decompression_buffer[BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE]; + T decompression_buffer[BITPACKING_METADATA_GROUP_SIZE]; + + bitpacking_metadata_t current_group; - idx_t position_in_group = 0; - data_ptr_t current_metadata_group_ptr; - data_ptr_t bitpacking_metadata_ptr; bitpacking_width_t current_width; T current_frame_of_reference; + T current_constant; + T current_delta_offset; + + idx_t current_group_offset = 0; + data_ptr_t current_group_ptr; + data_ptr_t bitpacking_metadata_ptr; public: - //! Loads the current group header, and sets pointer to next header - void LoadCurrentMetaData() { + //! Loads the metadata for the current metadata group. This will set bitpacking_metadata_ptr to the next group. + //! this will also load any metadata that is at the start of a compressed buffer (e.g. the width, for, or constant + //! value) depending on the bitpacking mode for that group + void LoadNextGroup() { D_ASSERT(bitpacking_metadata_ptr > handle.Ptr() && bitpacking_metadata_ptr < handle.Ptr() + Storage::BLOCK_SIZE); - current_width = Load(bitpacking_metadata_ptr); - bitpacking_metadata_ptr -= sizeof(T); - current_frame_of_reference = Load(bitpacking_metadata_ptr); - bitpacking_metadata_ptr -= sizeof(bitpacking_width_t); + current_group_offset = 0; + current_group = DecodeMeta((bitpacking_metadata_encoded_t *)bitpacking_metadata_ptr); + + bitpacking_metadata_ptr -= sizeof(bitpacking_metadata_encoded_t); + current_group_ptr = GetPtr(current_group); + + // Read first value + switch (current_group.mode) { + case BitpackingMode::CONSTANT: + current_constant = *(T *)(current_group_ptr); + current_group_ptr += sizeof(T); + break; + case BitpackingMode::FOR: + case BitpackingMode::CONSTANT_DELTA: + case BitpackingMode::DELTA_FOR: + current_frame_of_reference = *(T *)(current_group_ptr); + current_group_ptr += sizeof(T); + break; + default: + throw InternalException("Invalid bitpacking mode"); + } + + // Read second value + switch (current_group.mode) { + case BitpackingMode::CONSTANT_DELTA: + current_constant = *(T *)(current_group_ptr); + current_group_ptr += sizeof(T); + break; + case BitpackingMode::FOR: + case BitpackingMode::DELTA_FOR: + current_width = (bitpacking_width_t) * (T *)(current_group_ptr); + current_group_ptr += MaxValue(sizeof(T), sizeof(bitpacking_width_t)); + break; + case BitpackingMode::CONSTANT: + break; + default: + throw InternalException("Invalid bitpacking mode"); + } + + // Read third value + if (current_group.mode == BitpackingMode::DELTA_FOR) { + current_delta_offset = *(T *)(current_group_ptr); + current_group_ptr += sizeof(T); + } } void Skip(ColumnSegment &segment, idx_t skip_count) { while (skip_count > 0) { - if (position_in_group + skip_count < BITPACKING_METADATA_GROUP_SIZE) { - // We're not leaving this bitpacking group, we can perform all skips. - position_in_group += skip_count; + if (current_group_offset + skip_count < BITPACKING_METADATA_GROUP_SIZE) { + // Skipping Delta FOR requires a bit of decoding to figure out the new delta + if (current_group.mode == BitpackingMode::DELTA_FOR) { + // if current_group_offset points into the middle of a + // BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE, we need to scan a few + // values before current_group_offset to align with the algorithm groups + idx_t extra_count = current_group_offset % BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE; + + // Calculate total offset and count to bitunpack + idx_t base_decompress_count = BitpackingPrimitives::RoundUpToAlgorithmGroupSize(skip_count); + idx_t decompress_count = base_decompress_count + extra_count; + idx_t decompress_offset = current_group_offset - extra_count; + bool skip_sign_extension = true; + + BitpackingPrimitives::UnPackBuffer((data_ptr_t)decompression_buffer, + current_group_ptr + decompress_offset, decompress_count, + current_width, skip_sign_extension); + + ApplyFrameOfReference((T_S *)&decompression_buffer[extra_count], current_frame_of_reference, + skip_count); + DeltaDecode((T_S *)&decompression_buffer[extra_count], (T_S)current_delta_offset, + (idx_t)skip_count); + current_delta_offset = decompression_buffer[extra_count + skip_count - 1]; + + current_group_offset += skip_count; + } else { + current_group_offset += skip_count; + } break; } else { - // The skip crosses the current bitpacking group, we skip the remainder of this group. - auto skipping = BITPACKING_METADATA_GROUP_SIZE - position_in_group; - position_in_group = 0; - current_metadata_group_ptr += (current_width * BITPACKING_METADATA_GROUP_SIZE) / 8; + auto left_in_this_group = BITPACKING_METADATA_GROUP_SIZE - current_group_offset; + auto number_of_groups_to_skip = (skip_count - left_in_this_group) / BITPACKING_METADATA_GROUP_SIZE; + + current_group_offset = 0; + bitpacking_metadata_ptr -= number_of_groups_to_skip * sizeof(bitpacking_metadata_encoded_t); - // Load new width - LoadCurrentMetaData(); + LoadNextGroup(); - skip_count -= skipping; + skip_count -= left_in_this_group; + skip_count -= number_of_groups_to_skip * BITPACKING_METADATA_GROUP_SIZE; } } } + + data_ptr_t GetPtr(bitpacking_metadata_t group) { + return handle.Ptr() + current_segment.GetBlockOffset() + group.offset; + } }; template unique_ptr BitpackingInitScan(ColumnSegment &segment) { auto result = make_unique>(segment); - return move(result); -} - -template -static void ApplyFrameOfReference(T *dst, T frame_of_reference, idx_t size) { - if (!frame_of_reference) { - return; - } - for (idx_t i = 0; i < size; i++) { - dst[i] += frame_of_reference; - } + return std::move(result); } //===--------------------------------------------------------------------===// // Scan base data //===--------------------------------------------------------------------===// -template +template ::type> void BitpackingScanPartial(ColumnSegment &segment, ColumnScanState &state, idx_t scan_count, Vector &result, idx_t result_offset) { auto &scan_state = (BitpackingScanState &)*state.scan_state; @@ -217244,18 +230331,6 @@ void BitpackingScanPartial(ColumnSegment &segment, ColumnScanState &state, idx_t T *result_data = FlatVector::GetData(result); result.SetVectorType(VectorType::FLAT_VECTOR); - // Fast path for when no compression was used, we can do a single memcopy - if (STANDARD_VECTOR_SIZE == BITPACKING_METADATA_GROUP_SIZE) { - if (scan_state.current_frame_of_reference == 0 && scan_state.current_width == sizeof(T) * 8 && - scan_count <= BITPACKING_METADATA_GROUP_SIZE && scan_state.position_in_group == 0) { - - memcpy(result_data + result_offset, scan_state.current_metadata_group_ptr, scan_count * sizeof(T)); - scan_state.current_metadata_group_ptr += scan_count * sizeof(T); - scan_state.LoadCurrentMetaData(); - return; - } - } - //! Because FOR offsets all our values to be 0 or above, we can always skip sign extension here bool skip_sign_extend = true; @@ -217263,21 +230338,45 @@ void BitpackingScanPartial(ColumnSegment &segment, ColumnScanState &state, idx_t while (scanned < scan_count) { // Exhausted this metadata group, move pointers to next group and load metadata for next group. - if (scan_state.position_in_group >= BITPACKING_METADATA_GROUP_SIZE) { - scan_state.position_in_group = 0; - scan_state.current_metadata_group_ptr += (scan_state.current_width * BITPACKING_METADATA_GROUP_SIZE) / 8; - scan_state.LoadCurrentMetaData(); + if (scan_state.current_group_offset >= BITPACKING_METADATA_GROUP_SIZE) { + scan_state.LoadNextGroup(); } idx_t offset_in_compression_group = - scan_state.position_in_group % BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE; + scan_state.current_group_offset % BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE; + + if (scan_state.current_group.mode == BitpackingMode::CONSTANT) { + idx_t remaining = scan_count - scanned; + idx_t to_scan = MinValue(remaining, BITPACKING_METADATA_GROUP_SIZE - scan_state.current_group_offset); + T *begin = result_data + result_offset + scanned; + T *end = begin + remaining; + std::fill(begin, end, scan_state.current_constant); + scanned += to_scan; + scan_state.current_group_offset += to_scan; + continue; + } + if (scan_state.current_group.mode == BitpackingMode::CONSTANT_DELTA) { + idx_t remaining = scan_count - scanned; + idx_t to_scan = MinValue(remaining, BITPACKING_METADATA_GROUP_SIZE - scan_state.current_group_offset); + T *target_ptr = result_data + result_offset + scanned; + + for (idx_t i = 0; i < to_scan; i++) { + target_ptr[i] = ((scan_state.current_group_offset + i) * scan_state.current_constant) + + scan_state.current_frame_of_reference; + } + + scanned += to_scan; + scan_state.current_group_offset += to_scan; + continue; + } + D_ASSERT(scan_state.current_group.mode == BitpackingMode::FOR || + scan_state.current_group.mode == BitpackingMode::DELTA_FOR); idx_t to_scan = MinValue(scan_count - scanned, BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE - offset_in_compression_group); - // Calculate start of compression algorithm group data_ptr_t current_position_ptr = - scan_state.current_metadata_group_ptr + scan_state.position_in_group * scan_state.current_width / 8; + scan_state.current_group_ptr + scan_state.current_group_offset * scan_state.current_width / 8; data_ptr_t decompression_group_start_pointer = current_position_ptr - offset_in_compression_group * scan_state.current_width / 8; @@ -217296,9 +230395,17 @@ void BitpackingScanPartial(ColumnSegment &segment, ColumnScanState &state, idx_t memcpy(current_result_ptr, scan_state.decompression_buffer + offset_in_compression_group, to_scan * sizeof(T)); } - ApplyFrameOfReference((T *)current_result_ptr, scan_state.current_frame_of_reference, to_scan); + + if (scan_state.current_group.mode == BitpackingMode::DELTA_FOR) { + ApplyFrameOfReference((T_S *)current_result_ptr, (T_S)scan_state.current_frame_of_reference, to_scan); + DeltaDecode((T_S *)current_result_ptr, (T_S)scan_state.current_delta_offset, to_scan); + scan_state.current_delta_offset = ((T *)current_result_ptr)[to_scan - 1]; + } else { + ApplyFrameOfReference(current_result_ptr, scan_state.current_frame_of_reference, to_scan); + } + scanned += to_scan; - scan_state.position_in_group += to_scan; + scan_state.current_group_offset += to_scan; } } @@ -217318,23 +230425,39 @@ void BitpackingFetchRow(ColumnSegment &segment, ColumnFetchState &state, row_t r auto result_data = FlatVector::GetData(result); T *current_result_ptr = result_data + result_idx; - // TODO clean up, is reused in partialscan idx_t offset_in_compression_group = - scan_state.position_in_group % BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE; + scan_state.current_group_offset % BitpackingPrimitives::BITPACKING_ALGORITHM_GROUP_SIZE; data_ptr_t decompression_group_start_pointer = - scan_state.current_metadata_group_ptr + - (scan_state.position_in_group - offset_in_compression_group) * scan_state.current_width / 8; + scan_state.current_group_ptr + + (scan_state.current_group_offset - offset_in_compression_group) * scan_state.current_width / 8; //! Because FOR offsets all our values to be 0 or above, we can always skip sign extension here bool skip_sign_extend = true; + if (scan_state.current_group.mode == BitpackingMode::CONSTANT) { + *current_result_ptr = scan_state.current_constant; + return; + } + + if (scan_state.current_group.mode == BitpackingMode::CONSTANT_DELTA) { + *current_result_ptr = + ((scan_state.current_group_offset) * scan_state.current_constant) + scan_state.current_frame_of_reference; + return; + } + + D_ASSERT(scan_state.current_group.mode == BitpackingMode::FOR || + scan_state.current_group.mode == BitpackingMode::DELTA_FOR); + BitpackingPrimitives::UnPackBlock((data_ptr_t)scan_state.decompression_buffer, decompression_group_start_pointer, scan_state.current_width, skip_sign_extend); *current_result_ptr = *(T *)(scan_state.decompression_buffer + offset_in_compression_group); - //! Apply FOR to result *current_result_ptr += scan_state.current_frame_of_reference; + + if (scan_state.current_group.mode == BitpackingMode::DELTA_FOR) { + *current_result_ptr += scan_state.current_delta_offset; + } } template void BitpackingSkip(ColumnSegment &segment, ColumnScanState &state, idx_t skip_count) { @@ -219017,7 +232140,7 @@ struct ChimpCompressionState : public CompressionState { auto &type = checkpointer.GetType(); auto compressed_segment = ColumnSegment::CreateTransientSegment(db, type, row_start); compressed_segment->function = function; - current_segment = move(compressed_segment); + current_segment = std::move(compressed_segment); next_group_byte_index_start = ChimpPrimitives::HEADER_SIZE; auto &buffer_manager = BufferManager::GetBufferManager(db); @@ -219048,7 +232171,7 @@ struct ChimpCompressionState : public CompressionState { current_segment->count++; if (is_valid) { - T floating_point_value = *(T *)(&value); + T floating_point_value = Load((const_data_ptr_t)&value); NumericStatistics::Update(current_segment->stats, floating_point_value); } else { //! FIXME: find a cheaper alternative to storing a NULL @@ -219150,7 +232273,7 @@ struct ChimpCompressionState : public CompressionState { // Store the offset of the metadata of the first group (which is at the highest address). Store(metadata_offset + metadata_size, dataptr); handle.Destroy(); - checkpoint_state.FlushSegment(move(current_segment), total_segment_size); + checkpoint_state.FlushSegment(std::move(current_segment), total_segment_size); } void Finalize() { @@ -219748,7 +232871,7 @@ struct DictionaryCompressionCompressState : public DictionaryCompressionState { auto &db = checkpointer.GetDatabase(); auto &type = checkpointer.GetType(); auto compressed_segment = ColumnSegment::CreateTransientSegment(db, type, row_start); - current_segment = move(compressed_segment); + current_segment = std::move(compressed_segment); current_segment->function = function; @@ -219838,7 +232961,7 @@ struct DictionaryCompressionCompressState : public DictionaryCompressionState { auto segment_size = Finalize(); auto &state = checkpointer.GetCheckpointState(); - state.FlushSegment(move(current_segment), segment_size); + state.FlushSegment(std::move(current_segment), segment_size); if (!final) { CreateEmptySegment(next_start); @@ -220045,7 +233168,7 @@ unique_ptr DictionaryCompressionStorage::StringInitScan(Column dict_child_data[i] = FetchStringFromDict(segment, dict, baseptr, index_buffer_ptr[i], str_len); } - return move(state); + return std::move(state); } //===--------------------------------------------------------------------===// @@ -220292,7 +233415,7 @@ struct UncompressedCompressState : public CompressionState { UncompressedCompressState::UncompressedCompressState(ColumnDataCheckpointer &checkpointer) : checkpointer(checkpointer) { - CreateEmptySegment(checkpointer.GetRowGroup().start); + UncompressedCompressState::CreateEmptySegment(checkpointer.GetRowGroup().start); } void UncompressedCompressState::CreateEmptySegment(idx_t row_start) { @@ -220303,13 +233426,13 @@ void UncompressedCompressState::CreateEmptySegment(idx_t row_start) { auto &state = (UncompressedStringSegmentState &)*compressed_segment->GetSegmentState(); state.overflow_writer = make_unique(checkpointer.GetColumnData().block_manager); } - current_segment = move(compressed_segment); + current_segment = std::move(compressed_segment); current_segment->InitializeAppend(append_state); } void UncompressedCompressState::FlushSegment(idx_t segment_size) { auto &state = checkpointer.GetCheckpointState(); - state.FlushSegment(move(current_segment), segment_size); + state.FlushSegment(std::move(current_segment), segment_size); } void UncompressedCompressState::Finalize(idx_t segment_size) { @@ -220361,7 +233484,7 @@ unique_ptr FixedSizeInitScan(ColumnSegment &segment) { auto result = make_unique(); auto &buffer_manager = BufferManager::GetBufferManager(segment.db); result->handle = buffer_manager.Pin(segment.block); - return move(result); + return std::move(result); } //===--------------------------------------------------------------------===// @@ -220420,7 +233543,7 @@ void FixedSizeFetchRow(ColumnSegment &segment, ColumnFetchState &state, row_t ro static unique_ptr FixedSizeInitAppend(ColumnSegment &segment) { auto &buffer_manager = BufferManager::GetBufferManager(segment.db); auto handle = buffer_manager.Pin(segment.block); - return make_unique(move(handle)); + return make_unique(std::move(handle)); } template @@ -220745,17 +233868,11 @@ class FSSTCompressionState : public CompressionState { } } - void CreateEmptySegment(idx_t row_start) { - auto &db = checkpointer.GetDatabase(); - auto &type = checkpointer.GetType(); - auto compressed_segment = ColumnSegment::CreateTransientSegment(db, type, row_start); - current_segment = move(compressed_segment); - - current_segment->function = function; - - // Reset the buffers and string map + void Reset() { index_buffer.clear(); current_width = 0; + max_compressed_string_length = 0; + last_fitting_size = 0; // Reset the pointers into the current segment auto &buffer_manager = BufferManager::GetBufferManager(current_segment->db); @@ -220764,11 +233881,21 @@ class FSSTCompressionState : public CompressionState { current_end_ptr = current_handle.Ptr() + current_dictionary.end; } - void UpdateState(string_t uncompressed_string, unsigned char *compressed_string, size_t compressed_string_len) { + void CreateEmptySegment(idx_t row_start) { + auto &db = checkpointer.GetDatabase(); + auto &type = checkpointer.GetType(); + auto compressed_segment = ColumnSegment::CreateTransientSegment(db, type, row_start); + current_segment = std::move(compressed_segment); + current_segment->function = function; + Reset(); + } + void UpdateState(string_t uncompressed_string, unsigned char *compressed_string, size_t compressed_string_len) { if (!HasEnoughSpace(compressed_string_len)) { Flush(); - D_ASSERT(HasEnoughSpace(compressed_string_len)); + if (!HasEnoughSpace(compressed_string_len)) { + throw InternalException("FSST string compression failed due to insufficient space in empty block"); + }; } UncompressedStringStorage::UpdateStringStats(current_segment->stats, uncompressed_string); @@ -220791,7 +233918,9 @@ class FSSTCompressionState : public CompressionState { void AddNull() { if (!HasEnoughSpace(0)) { Flush(); - D_ASSERT(HasEnoughSpace(0)); + if (!HasEnoughSpace(0)) { + throw InternalException("FSST string compression failed due to insufficient space in empty block"); + }; } index_buffer.push_back(0); current_segment->count++; @@ -220802,7 +233931,7 @@ class FSSTCompressionState : public CompressionState { UncompressedStringStorage::UpdateStringStats(current_segment->stats, ""); } - bool HasEnoughSpace(size_t string_len) { + size_t GetRequiredSize(size_t string_len) { bitpacking_width_t required_minimum_width; if (string_len > max_compressed_string_length) { required_minimum_width = BitpackingPrimitives::MinimumBitWidth(string_len); @@ -220817,10 +233946,19 @@ class FSSTCompressionState : public CompressionState { BitpackingPrimitives::GetRequiredSize(current_string_count + 1, required_minimum_width); // TODO switch to a symbol table per RowGroup, saves a bit of space - idx_t required_space = sizeof(fsst_compression_header_t) + current_dict_size + dict_offsets_size + string_len + - fsst_serialized_symbol_table_size; + return sizeof(fsst_compression_header_t) + current_dict_size + dict_offsets_size + string_len + + fsst_serialized_symbol_table_size; + } + + // Checks if there is enough space, if there is, sets last_fitting_size + bool HasEnoughSpace(size_t string_len) { + auto required_size = GetRequiredSize(string_len); - return required_space <= Storage::BLOCK_SIZE; + if (required_size <= Storage::BLOCK_SIZE) { + last_fitting_size = required_size; + return true; + } + return false; } void Flush(bool final = false) { @@ -220828,7 +233966,7 @@ class FSSTCompressionState : public CompressionState { auto segment_size = Finalize(); auto &state = checkpointer.GetCheckpointState(); - state.FlushSegment(move(current_segment), segment_size); + state.FlushSegment(std::move(current_segment), segment_size); if (!final) { CreateEmptySegment(next_start); @@ -220846,6 +233984,10 @@ class FSSTCompressionState : public CompressionState { auto total_size = sizeof(fsst_compression_header_t) + compressed_index_buffer_size + current_dictionary.size + fsst_serialized_symbol_table_size; + if (total_size != last_fitting_size) { + throw InternalException("FSST string compression failed due to incorrect size calculation"); + } + // calculate ptr and offsets auto base_ptr = handle.Ptr(); auto header_ptr = (fsst_compression_header_t *)base_ptr; @@ -220867,11 +234009,6 @@ class FSSTCompressionState : public CompressionState { Store(symbol_table_offset, (data_ptr_t)&header_ptr->fsst_symbol_table_offset); Store((uint32_t)current_width, (data_ptr_t)&header_ptr->bitpacking_width); - if (symbol_table_offset + fsst_serialized_symbol_table_size > - current_dictionary.end - current_dictionary.size) { - throw InternalException("FSST string compression failed due to incorrect size calculation"); - } - if (total_size >= FSSTStorage::COMPACTION_FLUSH_LIMIT) { // the block is full enough, don't bother moving around the dictionary return Storage::BLOCK_SIZE; @@ -220902,8 +234039,9 @@ class FSSTCompressionState : public CompressionState { // Buffers and map for current segment std::vector index_buffer; - size_t max_compressed_string_length = 0; - bitpacking_width_t current_width = 0; + size_t max_compressed_string_length; + bitpacking_width_t current_width; + idx_t last_fitting_size; duckdb_fsst_encoder_t *fsst_encoder = nullptr; unsigned char fsst_serialized_symbol_table[sizeof(duckdb_fsst_decoder_t)]; @@ -221048,7 +234186,7 @@ unique_ptr FSSTStorage::StringInitScan(ColumnSegment &segment) state->duckdb_fsst_decoder = nullptr; } - return move(state); + return std::move(state); } void DeltaDecodeIndices(uint32_t *buffer_in, uint32_t *buffer_out, idx_t decode_count, uint32_t last_known_value) { @@ -221934,7 +235072,7 @@ struct EmptyPatasWriter { using EXACT_TYPE = typename FloatingToExact::type; auto state_wrapper = (PatasAnalyzeState *)state_p; - state_wrapper->WriteValue(*(EXACT_TYPE *)(&uncompressed_value), is_valid); + state_wrapper->WriteValue(Load((const_data_ptr_t)&uncompressed_value), is_valid); } }; @@ -222010,7 +235148,7 @@ struct PatasCompressionState : public CompressionState { NumericStatistics::Update(state_wrapper->current_segment->stats, value); } - state_wrapper->WriteValue(*(EXACT_TYPE *)(&value)); + state_wrapper->WriteValue(Load((const_data_ptr_t)&value)); } }; @@ -222088,7 +235226,7 @@ struct PatasCompressionState : public CompressionState { auto &type = checkpointer.GetType(); auto compressed_segment = ColumnSegment::CreateTransientSegment(db, type, row_start); compressed_segment->function = function; - current_segment = move(compressed_segment); + current_segment = std::move(compressed_segment); auto &buffer_manager = BufferManager::GetBufferManager(db); handle = buffer_manager.Pin(current_segment->block); @@ -222161,7 +235299,7 @@ struct PatasCompressionState : public CompressionState { // Store the offset to the metadata Store(metadata_offset + metadata_size, dataptr); handle.Destroy(); - checkpoint_state.FlushSegment(move(current_segment), total_segment_size); + checkpoint_state.FlushSegment(std::move(current_segment), total_segment_size); } void Finalize() { @@ -222693,7 +235831,7 @@ struct RLECompressState : public CompressionState { auto &type = checkpointer.GetType(); auto column_segment = ColumnSegment::CreateTransientSegment(db, type, row_start); column_segment->function = function; - current_segment = move(column_segment); + current_segment = std::move(column_segment); auto &buffer_manager = BufferManager::GetBufferManager(db); handle = buffer_manager.Pin(current_segment->block); } @@ -222744,7 +235882,7 @@ struct RLECompressState : public CompressionState { handle.Destroy(); auto &state = checkpointer.GetCheckpointState(); - state.FlushSegment(move(current_segment), total_segment_size); + state.FlushSegment(std::move(current_segment), total_segment_size); } void Finalize() { @@ -222824,7 +235962,7 @@ struct RLEScanState : public SegmentScanState { template unique_ptr RLEInitScan(ColumnSegment &segment) { auto result = make_unique>(segment); - return move(result); + return std::move(result); } //===--------------------------------------------------------------------===// @@ -222955,7 +236093,7 @@ namespace duckdb { UncompressedStringSegmentState::~UncompressedStringSegmentState() { while (head) { // prevent deep recursion here - head = move(head->next); + head = std::move(head->next); } } @@ -223007,7 +236145,7 @@ unique_ptr UncompressedStringStorage::StringInitScan(ColumnSeg auto result = make_unique(); auto &buffer_manager = BufferManager::GetBufferManager(segment.db); result->handle = buffer_manager.Pin(segment.block); - return move(result); + return std::move(result); } //===--------------------------------------------------------------------===// @@ -223051,7 +236189,7 @@ BufferHandle &ColumnFetchState::GetOrInsertHandle(ColumnSegment &segment) { // not pinned yet: pin it auto &buffer_manager = BufferManager::GetBufferManager(segment.db); auto handle = buffer_manager.Pin(segment.block); - auto entry = handles.insert(make_pair(primary_id, move(handle))); + auto entry = handles.insert(make_pair(primary_id, std::move(handle))); return entry.first->second; } else { // already pinned: use the pinned handle @@ -223195,9 +236333,9 @@ void UncompressedStringStorage::WriteStringMemory(ColumnSegment &segment, string // allocate an in-memory buffer for it handle = buffer_manager.Allocate(alloc_size, false, &block); state.overflow_blocks[block->BlockId()] = new_block.get(); - new_block->block = move(block); - new_block->next = move(state.head); - state.head = move(new_block); + new_block->block = std::move(block); + new_block->next = std::move(state.head); + state.head = std::move(new_block); } else { // string fits, copy it into the current block handle = buffer_manager.Pin(state.head->block); @@ -223272,7 +236410,7 @@ string_t UncompressedStringStorage::ReadOverflowString(ColumnSegment &segment, V uncompressed_size); auto final_buffer = decompressed_target_handle.Ptr(); - StringVector::AddHandle(result, move(decompressed_target_handle)); + StringVector::AddHandle(result, std::move(decompressed_target_handle)); return ReadString(final_buffer, 0, uncompressed_size); } else { // read the overflow string from memory @@ -223281,7 +236419,7 @@ string_t UncompressedStringStorage::ReadOverflowString(ColumnSegment &segment, V D_ASSERT(entry != state.overflow_blocks.end()); auto handle = buffer_manager.Pin(entry->second->block); auto final_buffer = handle.Ptr(); - StringVector::AddHandle(result, move(handle)); + StringVector::AddHandle(result, std::move(handle)); return ReadStringWithLength(final_buffer, offset); } } @@ -223601,7 +236739,7 @@ unique_ptr ValidityInitScan(ColumnSegment &segment) { auto &buffer_manager = BufferManager::GetBufferManager(segment.db); result->handle = buffer_manager.Pin(segment.block); result->block_id = segment.block->BlockId(); - return move(result); + return std::move(result); } //===--------------------------------------------------------------------===// @@ -223785,7 +236923,7 @@ void ValidityFetchRow(ColumnSegment &segment, ColumnFetchState &state, row_t row static unique_ptr ValidityInitAppend(ColumnSegment &segment) { auto &buffer_manager = BufferManager::GetBufferManager(segment.db); auto handle = buffer_manager.Pin(segment.block); - return make_unique(move(handle)); + return make_unique(std::move(handle)); } unique_ptr ValidityInitSegment(ColumnSegment &segment, block_id_t block_id) { @@ -223968,7 +237106,7 @@ class StandardColumnData : public ColumnData { void DeserializeColumn(Deserializer &source) override; - void GetStorageInfo(idx_t row_group_index, vector col_path, vector> &result) override; + void GetStorageInfo(idx_t row_group_index, vector col_path, TableStorageInfo &result) override; void Verify(RowGroup &parent) override; @@ -223982,13 +237120,27 @@ class StandardColumnData : public ColumnData { + + + + namespace duckdb { -DataTable::DataTable(DatabaseInstance &db, shared_ptr table_io_manager_p, const string &schema, +DataTableInfo::DataTableInfo(AttachedDatabase &db, shared_ptr table_io_manager_p, string schema, + string table) + : db(db), table_io_manager(std::move(table_io_manager_p)), cardinality(0), schema(std::move(schema)), + table(std::move(table)) { +} + +bool DataTableInfo::IsTemporary() const { + return db.IsTemporary(); +} + +DataTable::DataTable(AttachedDatabase &db, shared_ptr table_io_manager_p, const string &schema, const string &table, vector column_definitions_p, unique_ptr data) - : info(make_shared(db, move(table_io_manager_p), schema, table)), - column_definitions(move(column_definitions_p)), db(db), is_root(true) { + : info(make_shared(db, std::move(table_io_manager_p), schema, table)), + column_definitions(std::move(column_definitions_p)), db(db), is_root(true) { // initialize the table with the existing data from disk, if any auto types = GetTypes(); this->row_groups = @@ -224015,7 +237167,7 @@ DataTable::DataTable(ClientContext &context, DataTable &parent, ColumnDefinition this->row_groups = parent.row_groups->AddColumn(context, new_column, default_value); // also add this column to client local storage - auto &local_storage = LocalStorage::Get(context); + auto &local_storage = LocalStorage::Get(context, db); local_storage.AddColumn(&parent, this, new_column, default_value); // this table replaces the previous table, hence the parent is no longer the root DataTable @@ -224060,7 +237212,7 @@ DataTable::DataTable(ClientContext &context, DataTable &parent, idx_t removed_co this->row_groups = parent.row_groups->RemoveColumn(removed_column); // scan the original table, and fill the new column with the transformed value - auto &local_storage = LocalStorage::Get(context); + auto &local_storage = LocalStorage::Get(context, db); local_storage.DropColumn(&parent, this, removed_column); // this table replaces the previous table, hence the parent is no longer the root DataTable @@ -224080,7 +237232,7 @@ DataTable::DataTable(ClientContext &context, DataTable &parent, unique_ptrrow_groups = parent.row_groups->AlterType(context, changed_idx, target_type, bound_columns, cast_expr); // scan the original table, and fill the new column with the transformed value - auto &local_storage = LocalStorage::Get(context); + auto &local_storage = LocalStorage::Get(context, db); local_storage.ChangeType(&parent, this, changed_idx, target_type, bound_columns, cast_expr); // this table replaces the previous table, hence the parent is no longer the root DataTable @@ -224140,7 +237292,7 @@ void DataTable::InitializeScan(TableScanState &state, const vector &co row_groups->InitializeScan(state.table_state, column_ids, table_filters); } -void DataTable::InitializeScan(Transaction &transaction, TableScanState &state, const vector &column_ids, +void DataTable::InitializeScan(DuckTransaction &transaction, TableScanState &state, const vector &column_ids, TableFilterSet *table_filters) { InitializeScan(state, column_ids, table_filters); auto &local_storage = LocalStorage::Get(transaction); @@ -224165,7 +237317,7 @@ idx_t DataTable::MaxThreads(ClientContext &context) { void DataTable::InitializeParallelScan(ClientContext &context, ParallelTableScanState &state) { row_groups->InitializeParallelScan(state.scan_state); - auto &local_storage = LocalStorage::Get(context); + auto &local_storage = LocalStorage::Get(context, db); local_storage.InitializeParallelScan(this, state.local_state); } @@ -224174,7 +237326,7 @@ bool DataTable::NextParallelScan(ClientContext &context, ParallelTableScanState return true; } scan_state.table_state.batch_index = state.scan_state.batch_index; - auto &local_storage = LocalStorage::Get(context); + auto &local_storage = LocalStorage::Get(context, db); if (local_storage.NextParallelScan(context, this, state.local_state, scan_state.local_state)) { return true; } else { @@ -224183,7 +237335,7 @@ bool DataTable::NextParallelScan(ClientContext &context, ParallelTableScanState } } -void DataTable::Scan(Transaction &transaction, DataChunk &result, TableScanState &state) { +void DataTable::Scan(DuckTransaction &transaction, DataChunk &result, TableScanState &state) { // scan the persistent segments if (state.table_state.Scan(transaction, result)) { D_ASSERT(result.size() > 0); @@ -224202,8 +237354,8 @@ bool DataTable::CreateIndexScan(TableScanState &state, DataChunk &result, TableS //===--------------------------------------------------------------------===// // Fetch //===--------------------------------------------------------------------===// -void DataTable::Fetch(Transaction &transaction, DataChunk &result, const vector &column_ids, - Vector &row_identifiers, idx_t fetch_count, ColumnFetchState &state) { +void DataTable::Fetch(DuckTransaction &transaction, DataChunk &result, const vector &column_ids, + const Vector &row_identifiers, idx_t fetch_count, ColumnFetchState &state) { row_groups->Fetch(transaction, result, column_ids, row_identifiers, fetch_count, state); } @@ -224211,22 +237363,25 @@ void DataTable::Fetch(Transaction &transaction, DataChunk &result, const vector< // Append //===--------------------------------------------------------------------===// static void VerifyNotNullConstraint(TableCatalogEntry &table, Vector &vector, idx_t count, const string &col_name) { - if (VectorOperations::HasNull(vector, count)) { - throw ConstraintException("NOT NULL constraint failed: %s.%s", table.name, col_name); + if (!VectorOperations::HasNull(vector, count)) { + return; } + + throw ConstraintException("NOT NULL constraint failed: %s.%s", table.name, col_name); } // To avoid throwing an error at SELECT, instead this moves the error detection to INSERT static void VerifyGeneratedExpressionSuccess(ClientContext &context, TableCatalogEntry &table, DataChunk &chunk, Expression &expr, column_t index) { - auto &col = table.columns.GetColumn(LogicalIndex(index)); + auto &col = table.GetColumn(LogicalIndex(index)); D_ASSERT(col.Generated()); ExpressionExecutor executor(context, expr); Vector result(col.Type()); try { executor.ExecuteExpression(chunk, result); + } catch (InternalException &ex) { + throw; } catch (std::exception &ex) { - throw ConstraintException("Incorrect value for generated column \"%s %s AS (%s)\" : %s", col.Name(), col.Type().ToString(), col.GeneratedExpression().ToString(), ex.what()); } @@ -224277,24 +237432,78 @@ bool DataTable::IsForeignKeyIndex(const vector &fk_keys, Index &i return true; } -static void VerifyForeignKeyConstraint(const BoundForeignKeyConstraint &bfk, ClientContext &context, DataChunk &chunk, - bool is_append) { +// Find the first index that is not null, and did not find a match +static idx_t FirstMissingMatch(const ManagedSelection &matches) { + idx_t match_idx = 0; + + for (idx_t i = 0; i < matches.Size(); i++) { + auto match = matches.IndexMapsToLocation(match_idx, i); + match_idx += match; + if (!match) { + // This index is missing in the matches vector + return i; + } + } + return DConstants::INVALID_INDEX; +} + +idx_t LocateErrorIndex(bool is_append, const ManagedSelection &matches) { + idx_t failed_index = DConstants::INVALID_INDEX; + if (!is_append) { + // We expected to find nothing, so the first error is the first match + failed_index = matches[0]; + } else { + // We expected to find matches for all of them, so the first missing match is the first error + return FirstMissingMatch(matches); + } + return failed_index; +} + +[[noreturn]] static void ThrowForeignKeyConstraintError(idx_t failed_index, bool is_append, Index *index, + DataChunk &input) { + auto verify_type = is_append ? VerifyExistenceType::APPEND_FK : VerifyExistenceType::DELETE_FK; + + D_ASSERT(failed_index != DConstants::INVALID_INDEX); + D_ASSERT(index->type == IndexType::ART); + auto &art_index = (ART &)*index; + auto key_name = art_index.GenerateErrorKeyName(input, failed_index); + auto exception_msg = art_index.GenerateConstraintErrorMessage(verify_type, key_name); + throw ConstraintException(exception_msg); +} + +bool IsForeignKeyConstraintError(bool is_append, idx_t input_count, const ManagedSelection &matches) { + if (is_append) { + // We need to find a match for all of the values + return matches.Count() != input_count; + } else { + // We should not find any matches + return matches.Count() != 0; + } +} + +static bool IsAppend(VerifyExistenceType verify_type) { + return verify_type == VerifyExistenceType::APPEND_FK; +} + +void DataTable::VerifyForeignKeyConstraint(const BoundForeignKeyConstraint &bfk, ClientContext &context, + DataChunk &chunk, VerifyExistenceType verify_type) { const vector *src_keys_ptr = &bfk.info.fk_keys; const vector *dst_keys_ptr = &bfk.info.pk_keys; + + bool is_append = IsAppend(verify_type); if (!is_append) { src_keys_ptr = &bfk.info.pk_keys; dst_keys_ptr = &bfk.info.fk_keys; } auto table_entry_ptr = - Catalog::GetCatalog(context).GetEntry(context, bfk.info.schema, bfk.info.table); + Catalog::GetEntry(context, INVALID_CATALOG, bfk.info.schema, bfk.info.table); if (table_entry_ptr == nullptr) { throw InternalException("Can't find table \"%s\" in foreign key constraint", bfk.info.table); } - // make the data chunk to check vector types; - for (auto &col : table_entry_ptr->columns.Physical()) { + for (auto &col : table_entry_ptr->GetColumns().Physical()) { types.emplace_back(col.Type()); } DataChunk dst_chunk; @@ -224303,67 +237512,114 @@ static void VerifyForeignKeyConstraint(const BoundForeignKeyConstraint &bfk, Cli dst_chunk.data[(*dst_keys_ptr)[i].index].Reference(chunk.data[(*src_keys_ptr)[i].index]); } dst_chunk.SetCardinality(chunk.size()); - auto data_table = table_entry_ptr->storage.get(); + auto data_table = table_entry_ptr->GetStoragePtr(); idx_t count = dst_chunk.size(); if (count <= 0) { return; } - // we need to look at the error messages concurrently in data table's index and transaction local storage's index - vector err_msgs, tran_err_msgs; - err_msgs.resize(count); - tran_err_msgs.resize(count); + // Set up a way to record conflicts, rather than directly throw on them + unordered_set empty_column_list; + ConflictInfo empty_conflict_info(empty_column_list, false); + ConflictManager regular_conflicts(verify_type, count, &empty_conflict_info); + ConflictManager transaction_conflicts(verify_type, count, &empty_conflict_info); + regular_conflicts.SetMode(ConflictManagerMode::SCAN); + transaction_conflicts.SetMode(ConflictManagerMode::SCAN); - data_table->info->indexes.VerifyForeignKey(*dst_keys_ptr, is_append, dst_chunk, err_msgs); + data_table->info->indexes.VerifyForeignKey(*dst_keys_ptr, dst_chunk, regular_conflicts); + regular_conflicts.Finalize(); + auto ®ular_matches = regular_conflicts.Conflicts(); // check whether or not the chunk can be inserted or deleted into the referenced table' transaction local storage - auto &local_storage = LocalStorage::Get(context); + auto &local_storage = LocalStorage::Get(context, db); + + bool error = IsForeignKeyConstraintError(is_append, count, regular_matches); + bool transaction_error = false; + bool transaction_check = local_storage.Find(data_table); if (transaction_check) { auto &transact_index = local_storage.GetIndexes(data_table); - transact_index.VerifyForeignKey(*dst_keys_ptr, is_append, dst_chunk, tran_err_msgs); + transact_index.VerifyForeignKey(*dst_keys_ptr, dst_chunk, transaction_conflicts); + transaction_conflicts.Finalize(); + auto &transaction_matches = transaction_conflicts.Conflicts(); + transaction_error = IsForeignKeyConstraintError(is_append, count, transaction_matches); } - // we need to look at the error messages concurrently in data table's index and transaction local storage's index - for (idx_t i = 0; i < count; i++) { - if (!transaction_check) { - // if there is no transaction-local data we only need to check if there is an error message in the main - // index - if (!err_msgs[i].empty()) { - throw ConstraintException(err_msgs[i]); - } else { - continue; + if (!transaction_error && !error) { + // No error occurred; + return; + } + + // Some error occurred, and we likely want to throw + Index *index; + Index *transaction_index; + + auto fk_type = is_append ? ForeignKeyType::FK_TYPE_PRIMARY_KEY_TABLE : ForeignKeyType::FK_TYPE_FOREIGN_KEY_TABLE; + // check whether or not the chunk can be inserted or deleted into the referenced table' storage + index = data_table->info->indexes.FindForeignKeyIndex(*dst_keys_ptr, fk_type); + if (transaction_check) { + auto &transact_index = local_storage.GetIndexes(data_table); + // check whether or not the chunk can be inserted or deleted into the referenced table' storage + transaction_index = transact_index.FindForeignKeyIndex(*dst_keys_ptr, fk_type); + } + + if (!transaction_check) { + // Only local state is checked, throw the error + D_ASSERT(error); + auto failed_index = LocateErrorIndex(is_append, regular_matches); + D_ASSERT(failed_index != DConstants::INVALID_INDEX); + ThrowForeignKeyConstraintError(failed_index, is_append, index, dst_chunk); + } + if (transaction_error && error && is_append) { + // When we want to do an append, we only throw if the foreign key does not exist in both transaction and local + // storage + auto &transaction_matches = transaction_conflicts.Conflicts(); + idx_t failed_index = DConstants::INVALID_INDEX; + idx_t regular_idx = 0; + idx_t transaction_idx = 0; + for (idx_t i = 0; i < count; i++) { + bool in_regular = regular_matches.IndexMapsToLocation(regular_idx, i); + regular_idx += in_regular; + bool in_transaction = transaction_matches.IndexMapsToLocation(transaction_idx, i); + transaction_idx += in_transaction; + + if (!in_regular && !in_transaction) { + // We need to find a match for all of the input values + // The failed index is i, it does not show up in either regular or transaction storage + failed_index = i; + break; } } - if (is_append) { - // if we are appending we need to check to ensure the foreign key exists in either the transaction-local - // storage or the main table - if (!err_msgs[i].empty() && !tran_err_msgs[i].empty()) { - throw ConstraintException(err_msgs[i]); - } else { - continue; - } + if (failed_index == DConstants::INVALID_INDEX) { + // We don't throw, every value was present in either regular or transaction storage + return; } - // if we are deleting we need to ensure the foreign key DOES NOT exist in EITHER the transaction-local storage - // OR the main table - if (!err_msgs[i].empty() || !tran_err_msgs[i].empty()) { - string &err_msg = err_msgs[i]; - if (err_msg.empty()) { - err_msg = tran_err_msgs[i]; - } - throw ConstraintException(err_msg); + ThrowForeignKeyConstraintError(failed_index, true, index, dst_chunk); + } + if (!is_append && transaction_check) { + auto &transaction_matches = transaction_conflicts.Conflicts(); + if (error) { + auto failed_index = LocateErrorIndex(false, regular_matches); + D_ASSERT(failed_index != DConstants::INVALID_INDEX); + ThrowForeignKeyConstraintError(failed_index, false, index, dst_chunk); + } else { + D_ASSERT(transaction_error); + D_ASSERT(transaction_matches.Count() != DConstants::INVALID_INDEX); + auto failed_index = LocateErrorIndex(false, transaction_matches); + D_ASSERT(failed_index != DConstants::INVALID_INDEX); + ThrowForeignKeyConstraintError(failed_index, false, transaction_index, dst_chunk); } } } -static void VerifyAppendForeignKeyConstraint(const BoundForeignKeyConstraint &bfk, ClientContext &context, - DataChunk &chunk) { - VerifyForeignKeyConstraint(bfk, context, chunk, true); +void DataTable::VerifyAppendForeignKeyConstraint(const BoundForeignKeyConstraint &bfk, ClientContext &context, + DataChunk &chunk) { + VerifyForeignKeyConstraint(bfk, context, chunk, VerifyExistenceType::APPEND_FK); } -static void VerifyDeleteForeignKeyConstraint(const BoundForeignKeyConstraint &bfk, ClientContext &context, - DataChunk &chunk) { - VerifyForeignKeyConstraint(bfk, context, chunk, false); +void DataTable::VerifyDeleteForeignKeyConstraint(const BoundForeignKeyConstraint &bfk, ClientContext &context, + DataChunk &chunk) { + VerifyForeignKeyConstraint(bfk, context, chunk, VerifyExistenceType::DELETE_FK); } void DataTable::VerifyNewConstraint(ClientContext &context, DataTable &parent, const BoundConstraint *constraint) { @@ -224372,16 +237628,18 @@ void DataTable::VerifyNewConstraint(ClientContext &context, DataTable &parent, c } parent.row_groups->VerifyNewConstraint(parent, *constraint); - auto &local_storage = LocalStorage::Get(context); + auto &local_storage = LocalStorage::Get(context, db); local_storage.VerifyNewConstraint(parent, *constraint); } -void DataTable::VerifyAppendConstraints(TableCatalogEntry &table, ClientContext &context, DataChunk &chunk) { +void DataTable::VerifyAppendConstraints(TableCatalogEntry &table, ClientContext &context, DataChunk &chunk, + ConflictManager *conflict_manager) { if (table.HasGeneratedColumns()) { + // Verify that the generated columns expression work with the inserted values auto binder = Binder::CreateBinder(context); physical_index_set_t bound_columns; - CheckBinder generated_check_binder(*binder, context, table.name, table.columns, bound_columns); - for (auto &col : table.columns.Logical()) { + CheckBinder generated_check_binder(*binder, context, table.name, table.GetColumns(), bound_columns); + for (auto &col : table.GetColumns().Logical()) { if (!col.Generated()) { continue; } @@ -224392,14 +237650,16 @@ void DataTable::VerifyAppendConstraints(TableCatalogEntry &table, ClientContext VerifyGeneratedExpressionSuccess(context, table, chunk, *bound_expression, col.Oid()); } } - for (idx_t i = 0; i < table.bound_constraints.size(); i++) { - auto &base_constraint = table.constraints[i]; - auto &constraint = table.bound_constraints[i]; + auto &constraints = table.GetConstraints(); + auto &bound_constraints = table.GetBoundConstraints(); + for (idx_t i = 0; i < bound_constraints.size(); i++) { + auto &base_constraint = constraints[i]; + auto &constraint = bound_constraints[i]; switch (base_constraint->type) { case ConstraintType::NOT_NULL: { auto &bound_not_null = *reinterpret_cast(constraint.get()); auto ¬_null = *reinterpret_cast(base_constraint.get()); - auto &col = table.columns.GetColumn(LogicalIndex(not_null.index)); + auto &col = table.GetColumns().GetColumn(LogicalIndex(not_null.index)); VerifyNotNullConstraint(table, chunk.data[bound_not_null.index.index], chunk.size(), col.Name()); break; } @@ -224410,10 +237670,49 @@ void DataTable::VerifyAppendConstraints(TableCatalogEntry &table, ClientContext } case ConstraintType::UNIQUE: { //! check whether or not the chunk can be inserted into the indexes - info->indexes.Scan([&](Index &index) { - index.VerifyAppend(chunk); - return false; - }); + if (conflict_manager) { + // This is only provided when a ON CONFLICT clause was provided + idx_t matching_indexes = 0; + auto &conflict_info = conflict_manager->GetConflictInfo(); + // First we figure out how many indexes match our conflict target + // So we can optimize accordingly + info->indexes.Scan([&](Index &index) { + matching_indexes += conflict_info.ConflictTargetMatches(index); + return false; + }); + conflict_manager->SetMode(ConflictManagerMode::SCAN); + conflict_manager->SetIndexCount(matching_indexes); + // First we verify only the indexes that match our conflict target + info->indexes.Scan([&](Index &index) { + if (!index.IsUnique()) { + return false; + } + if (conflict_info.ConflictTargetMatches(index)) { + index.VerifyAppend(chunk, *conflict_manager); + } + return false; + }); + + conflict_manager->SetMode(ConflictManagerMode::THROW); + // Then we scan the other indexes, throwing if they cause conflicts on tuples that were not found during + // the scan + info->indexes.Scan([&](Index &index) { + if (!index.IsUnique()) { + return false; + } + index.VerifyAppend(chunk, *conflict_manager); + return false; + }); + } else { + // Only need to verify that no unique constraints are violated + info->indexes.Scan([&](Index &index) { + if (!index.IsUnique()) { + return false; + } + index.VerifyAppend(chunk); + return false; + }); + } break; } case ConstraintType::FOREIGN_KEY: { @@ -224434,16 +237733,16 @@ void DataTable::InitializeLocalAppend(LocalAppendState &state, ClientContext &co if (!is_root) { throw TransactionException("Transaction conflict: adding entries to a table that has been altered!"); } - auto &local_storage = LocalStorage::Get(context); + auto &local_storage = LocalStorage::Get(context, db); local_storage.InitializeAppend(state, this); } -void DataTable::LocalAppend(LocalAppendState &state, TableCatalogEntry &table, ClientContext &context, - DataChunk &chunk) { +void DataTable::LocalAppend(LocalAppendState &state, TableCatalogEntry &table, ClientContext &context, DataChunk &chunk, + bool unsafe) { if (chunk.size() == 0) { return; } - D_ASSERT(chunk.ColumnCount() == table.columns.PhysicalColumnCount()); + D_ASSERT(chunk.ColumnCount() == table.GetColumns().PhysicalColumnCount()); if (!is_root) { throw TransactionException("Transaction conflict: adding entries to a table that has been altered!"); } @@ -224451,7 +237750,9 @@ void DataTable::LocalAppend(LocalAppendState &state, TableCatalogEntry &table, C chunk.Verify(); // verify any constraints on the new chunk - VerifyAppendConstraints(table, context, chunk); + if (!unsafe) { + VerifyAppendConstraints(table, context, chunk); + } // append to the transaction local data LocalStorage::Append(state, chunk); @@ -224462,29 +237763,31 @@ void DataTable::FinalizeLocalAppend(LocalAppendState &state) { } OptimisticDataWriter *DataTable::CreateOptimisticWriter(ClientContext &context) { - auto &local_storage = LocalStorage::Get(context); + auto &local_storage = LocalStorage::Get(context, db); return local_storage.CreateOptimisticWriter(this); } void DataTable::LocalMerge(ClientContext &context, RowGroupCollection &collection) { - auto &local_storage = LocalStorage::Get(context); + auto &local_storage = LocalStorage::Get(context, db); local_storage.LocalMerge(this, collection); } void DataTable::LocalAppend(TableCatalogEntry &table, ClientContext &context, DataChunk &chunk) { LocalAppendState append_state; - table.storage->InitializeLocalAppend(append_state, context); - table.storage->LocalAppend(append_state, table, context, chunk); - table.storage->FinalizeLocalAppend(append_state); + auto &storage = table.GetStorage(); + storage.InitializeLocalAppend(append_state, context); + storage.LocalAppend(append_state, table, context, chunk); + storage.FinalizeLocalAppend(append_state); } void DataTable::LocalAppend(TableCatalogEntry &table, ClientContext &context, ColumnDataCollection &collection) { LocalAppendState append_state; - table.storage->InitializeLocalAppend(append_state, context); + auto &storage = table.GetStorage(); + storage.InitializeLocalAppend(append_state, context); for (auto &chunk : collection.Chunks()) { - table.storage->LocalAppend(append_state, table, context, chunk); + storage.LocalAppend(append_state, table, context, chunk); } - table.storage->FinalizeLocalAppend(append_state); + storage.FinalizeLocalAppend(append_state); } void DataTable::AppendLock(TableAppendState &state) { @@ -224496,7 +237799,7 @@ void DataTable::AppendLock(TableAppendState &state) { state.current_row = state.row_start; } -void DataTable::InitializeAppend(Transaction &transaction, TableAppendState &state, idx_t append_count) { +void DataTable::InitializeAppend(DuckTransaction &transaction, TableAppendState &state, idx_t append_count) { // obtain the append lock for this table if (!state.append_lock) { throw InternalException("DataTable::AppendLock should be called before DataTable::InitializeAppend"); @@ -224683,8 +237986,35 @@ void DataTable::RemoveFromIndexes(Vector &row_identifiers, idx_t count) { row_groups->RemoveFromIndexes(info->indexes, row_identifiers, count); } +//===--------------------------------------------------------------------===// +// Delete +//===--------------------------------------------------------------------===// +static bool TableHasDeleteConstraints(TableCatalogEntry &table) { + auto &bound_constraints = table.GetBoundConstraints(); + for (auto &constraint : bound_constraints) { + switch (constraint->type) { + case ConstraintType::NOT_NULL: + case ConstraintType::CHECK: + case ConstraintType::UNIQUE: + break; + case ConstraintType::FOREIGN_KEY: { + auto &bfk = *reinterpret_cast(constraint.get()); + if (bfk.info.type == ForeignKeyType::FK_TYPE_PRIMARY_KEY_TABLE || + bfk.info.type == ForeignKeyType::FK_TYPE_SELF_REFERENCE_TABLE) { + return true; + } + break; + } + default: + throw NotImplementedException("Constraint type not implemented!"); + } + } + return false; +} + void DataTable::VerifyDeleteConstraints(TableCatalogEntry &table, ClientContext &context, DataChunk &chunk) { - for (auto &constraint : table.bound_constraints) { + auto &bound_constraints = table.GetBoundConstraints(); + for (auto &constraint : bound_constraints) { switch (constraint->type) { case ConstraintType::NOT_NULL: case ConstraintType::CHECK: @@ -224704,47 +238034,66 @@ void DataTable::VerifyDeleteConstraints(TableCatalogEntry &table, ClientContext } } -//===--------------------------------------------------------------------===// -// Delete -//===--------------------------------------------------------------------===// idx_t DataTable::Delete(TableCatalogEntry &table, ClientContext &context, Vector &row_identifiers, idx_t count) { D_ASSERT(row_identifiers.GetType().InternalType() == ROW_TYPE); if (count == 0) { return 0; } - auto &transaction = Transaction::GetTransaction(context); - auto &local_storage = LocalStorage::Get(context); + auto &transaction = DuckTransaction::Get(context, db); + auto &local_storage = LocalStorage::Get(transaction); + bool has_delete_constraints = TableHasDeleteConstraints(table); row_identifiers.Flatten(count); auto ids = FlatVector::GetData(row_identifiers); - auto first_id = ids[0]; - // verify any constraints on the delete rows - // FIXME: we only need to fetch in case we have a foreign key constraint - // and we only need to fetch columns that are part of this constraint DataChunk verify_chunk; - if (first_id >= MAX_ROW_ID) { - local_storage.FetchChunk(this, row_identifiers, count, verify_chunk); - } else { - ColumnFetchState fetch_state; - vector col_ids; - vector types; + vector col_ids; + vector types; + ColumnFetchState fetch_state; + if (has_delete_constraints) { + // initialize the chunk if there are any constraints to verify for (idx_t i = 0; i < column_definitions.size(); i++) { col_ids.push_back(column_definitions[i].StorageOid()); types.emplace_back(column_definitions[i].Type()); } verify_chunk.Initialize(Allocator::Get(context), types); - Fetch(transaction, verify_chunk, col_ids, row_identifiers, count, fetch_state); } - VerifyDeleteConstraints(table, context, verify_chunk); + idx_t pos = 0; + idx_t delete_count = 0; + while (pos < count) { + idx_t start = pos; + bool is_transaction_delete = ids[pos] >= MAX_ROW_ID; + // figure out which batch of rows to delete now + for (pos++; pos < count; pos++) { + bool row_is_transaction_delete = ids[pos] >= MAX_ROW_ID; + if (row_is_transaction_delete != is_transaction_delete) { + break; + } + } + idx_t current_offset = start; + idx_t current_count = pos - start; - if (first_id >= MAX_ROW_ID) { - // deletion is in transaction-local storage: push delete into local chunk collection - return local_storage.Delete(this, row_identifiers, count); - } else { - return row_groups->Delete(transaction, this, ids, count); + Vector offset_ids(row_identifiers, current_offset, pos); + if (is_transaction_delete) { + // transaction-local delete + if (has_delete_constraints) { + // perform the constraint verification + local_storage.FetchChunk(this, offset_ids, current_count, col_ids, verify_chunk, fetch_state); + VerifyDeleteConstraints(table, context, verify_chunk); + } + delete_count += local_storage.Delete(this, offset_ids, current_count); + } else { + // regular table delete + if (has_delete_constraints) { + // perform the constraint verification + Fetch(transaction, verify_chunk, col_ids, offset_ids, current_count, fetch_state); + VerifyDeleteConstraints(table, context, verify_chunk); + } + delete_count += row_groups->Delete(transaction, this, ids + current_offset, current_count); + } } + return delete_count; } //===--------------------------------------------------------------------===// @@ -224786,18 +238135,21 @@ static bool CreateMockChunk(TableCatalogEntry &table, const vector &column_ids) { - for (idx_t i = 0; i < table.bound_constraints.size(); i++) { - auto &base_constraint = table.constraints[i]; - auto &constraint = table.bound_constraints[i]; + auto &constraints = table.GetConstraints(); + auto &bound_constraints = table.GetBoundConstraints(); + for (idx_t i = 0; i < bound_constraints.size(); i++) { + auto &base_constraint = constraints[i]; + auto &constraint = bound_constraints[i]; switch (constraint->type) { case ConstraintType::NOT_NULL: { auto &bound_not_null = *reinterpret_cast(constraint.get()); auto ¬_null = *reinterpret_cast(base_constraint.get()); // check if the constraint is in the list of column_ids + // FIXME: double usage of 'i'? for (idx_t i = 0; i < column_ids.size(); i++) { if (column_ids[i] == bound_not_null.index) { // found the column id: check the data in - auto &col = table.columns.GetColumn(LogicalIndex(not_null.index)); + auto &col = table.GetColumn(LogicalIndex(not_null.index)); VerifyNotNullConstraint(table, chunk.data[i], chunk.size(), col.Name()); break; } @@ -224835,6 +238187,7 @@ void DataTable::Update(TableCatalogEntry &table, ClientContext &context, Vector const vector &column_ids, DataChunk &updates) { D_ASSERT(row_ids.GetType().InternalType() == ROW_TYPE); + D_ASSERT(column_ids.size() == updates.ColumnCount()); auto count = updates.size(); updates.Verify(); if (count == 0) { @@ -224849,7 +238202,7 @@ void DataTable::Update(TableCatalogEntry &table, ClientContext &context, Vector VerifyUpdateConstraints(context, table, updates, column_ids); // now perform the actual update - auto &transaction = Transaction::GetTransaction(context); + auto &transaction = DuckTransaction::Get(context, db); updates.Flatten(); row_ids.Flatten(count); @@ -224857,7 +238210,7 @@ void DataTable::Update(TableCatalogEntry &table, ClientContext &context, Vector auto first_id = FlatVector::GetValue(row_ids, 0); if (first_id >= MAX_ROW_ID) { // update is in transaction-local storage: push update into local storage - auto &local_storage = LocalStorage::Get(context); + auto &local_storage = LocalStorage::Get(context, db); local_storage.Update(this, row_ids, column_ids, updates); return; } @@ -224883,7 +238236,7 @@ void DataTable::UpdateColumn(TableCatalogEntry &table, ClientContext &context, V } // now perform the actual update - auto &transaction = Transaction::GetTransaction(context); + auto &transaction = DuckTransaction::Get(context, db); updates.Flatten(); row_ids.Flatten(updates.size()); @@ -224930,7 +238283,7 @@ void DataTable::Checkpoint(TableDataWriter &writer) { // row-group pointers // table pointer // index data - writer.FinalizeTable(move(global_stats), info.get()); + writer.FinalizeTable(std::move(global_stats), info.get()); } void DataTable::CommitDropColumn(idx_t index) { @@ -224949,8 +238302,8 @@ void DataTable::CommitDropTable() { //===--------------------------------------------------------------------===// // GetStorageInfo //===--------------------------------------------------------------------===// -vector> DataTable::GetStorageInfo() { - return row_groups->GetStorageInfo(); +void DataTable::GetStorageInfo(TableStorageInfo &result) { + row_groups->GetStorageInfo(result); } } // namespace duckdb @@ -224964,19 +238317,25 @@ vector> DataTable::GetStorageInfo() { namespace duckdb { -Index::Index(IndexType type, TableIOManager &table_io_manager, const vector &column_ids_p, - const vector> &unbound_expressions, IndexConstraintType constraint_type_p) - : type(type), table_io_manager(table_io_manager), column_ids(column_ids_p), constraint_type(constraint_type_p) { +Index::Index(AttachedDatabase &db, IndexType type, TableIOManager &table_io_manager, + const vector &column_ids_p, const vector> &unbound_expressions, + IndexConstraintType constraint_type_p, bool track_memory) + + : type(type), table_io_manager(table_io_manager), column_ids(column_ids_p), constraint_type(constraint_type_p), + db(db), buffer_manager(BufferManager::GetBufferManager(db)), memory_size(0), track_memory(track_memory) { + for (auto &expr : unbound_expressions) { types.push_back(expr->return_type.InternalType()); logical_types.push_back(expr->return_type); auto unbound_expression = expr->Copy(); bound_expressions.push_back(BindExpression(unbound_expression->Copy())); - this->unbound_expressions.emplace_back(move(unbound_expression)); + this->unbound_expressions.emplace_back(std::move(unbound_expression)); } for (auto &bound_expr : bound_expressions) { executor.AddExpression(*bound_expr); } + + // create the column id set for (auto column_id : column_ids) { column_id_set.insert(column_id); } @@ -225022,8 +238381,8 @@ unique_ptr Index::BindExpression(unique_ptr expr) { auto &bound_colref = (BoundColumnRefExpression &)*expr; return make_unique(expr->return_type, column_ids[bound_colref.binding.column_index]); } - ExpressionIterator::EnumerateChildren(*expr, - [&](unique_ptr &expr) { expr = BindExpression(move(expr)); }); + ExpressionIterator::EnumerateChildren( + *expr, [this](unique_ptr &expr) { expr = BindExpression(std::move(expr)); }); return expr; } @@ -225064,7 +238423,8 @@ OptimisticDataWriter::OptimisticDataWriter(DataTable *table) : table(table) { } OptimisticDataWriter::OptimisticDataWriter(DataTable *table, OptimisticDataWriter &parent) - : table(table), partial_manager(move(parent.partial_manager)), written_blocks(move(parent.written_blocks)) { + : table(table), partial_manager(std::move(parent.partial_manager)), + written_blocks(std::move(parent.written_blocks)) { if (partial_manager) { partial_manager->FlushPartialBlocks(); } @@ -225075,7 +238435,7 @@ OptimisticDataWriter::~OptimisticDataWriter() { bool OptimisticDataWriter::PrepareWrite() { // check if we should pre-emptively write the table to disk - if (table->info->IsTemporary() || StorageManager::GetStorageManager(table->db).InMemory()) { + if (table->info->IsTemporary() || StorageManager::Get(table->info->db).InMemory()) { return false; } // we should! write the second-to-last row group to disk @@ -225168,8 +238528,8 @@ LocalTableStorage::LocalTableStorage(DataTable &table) for (auto &expr : art.unbound_expressions) { unbound_expressions.push_back(expr->Copy()); } - indexes.AddIndex(make_unique(art.column_ids, art.table_io_manager, move(unbound_expressions), - art.constraint_type, art.db)); + indexes.AddIndex(make_unique(art.column_ids, art.table_io_manager, std::move(unbound_expressions), + art.constraint_type, art.db, false)); } return false; }); @@ -225179,7 +238539,7 @@ LocalTableStorage::LocalTableStorage(ClientContext &context, DataTable &new_dt, idx_t changed_idx, const LogicalType &target_type, const vector &bound_columns, Expression &cast_expr) : table(&new_dt), allocator(Allocator::Get(table->db)), deleted_rows(parent.deleted_rows), - optimistic_writer(table, parent.optimistic_writer), optimistic_writers(move(parent.optimistic_writers)) { + optimistic_writer(table, parent.optimistic_writer), optimistic_writers(std::move(parent.optimistic_writers)) { row_groups = parent.row_groups->AlterType(context, changed_idx, target_type, bound_columns, cast_expr); parent.row_groups.reset(); indexes.Move(parent.indexes); @@ -225187,7 +238547,7 @@ LocalTableStorage::LocalTableStorage(ClientContext &context, DataTable &new_dt, LocalTableStorage::LocalTableStorage(DataTable &new_dt, LocalTableStorage &parent, idx_t drop_idx) : table(&new_dt), allocator(Allocator::Get(table->db)), deleted_rows(parent.deleted_rows), - optimistic_writer(table, parent.optimistic_writer), optimistic_writers(move(parent.optimistic_writers)) { + optimistic_writer(table, parent.optimistic_writer), optimistic_writers(std::move(parent.optimistic_writers)) { row_groups = parent.row_groups->RemoveColumn(drop_idx); parent.row_groups.reset(); indexes.Move(parent.indexes); @@ -225196,7 +238556,7 @@ LocalTableStorage::LocalTableStorage(DataTable &new_dt, LocalTableStorage &paren LocalTableStorage::LocalTableStorage(ClientContext &context, DataTable &new_dt, LocalTableStorage &parent, ColumnDefinition &new_column, Expression *default_value) : table(&new_dt), allocator(Allocator::Get(table->db)), deleted_rows(parent.deleted_rows), - optimistic_writer(table, parent.optimistic_writer), optimistic_writers(move(parent.optimistic_writers)) { + optimistic_writer(table, parent.optimistic_writer), optimistic_writers(std::move(parent.optimistic_writers)) { row_groups = parent.row_groups->AddColumn(context, new_column, default_value); parent.row_groups.reset(); indexes.Move(parent.indexes); @@ -225239,7 +238599,7 @@ void LocalTableStorage::FlushToDisk() { optimistic_writer.FinalFlush(); } -bool LocalTableStorage::AppendToIndexes(Transaction &transaction, RowGroupCollection &source, +bool LocalTableStorage::AppendToIndexes(DuckTransaction &transaction, RowGroupCollection &source, TableIndexList &index_list, const vector &table_types, row_t &start_row) { // only need to scan for index append @@ -225266,8 +238626,8 @@ bool LocalTableStorage::AppendToIndexes(Transaction &transaction, RowGroupCollec return success; } -void LocalTableStorage::AppendToIndexes(Transaction &transaction, TableAppendState &append_state, idx_t append_count, - bool append_to_table) { +void LocalTableStorage::AppendToIndexes(DuckTransaction &transaction, TableAppendState &append_state, + idx_t append_count, bool append_to_table) { bool constraint_violated = false; if (append_to_table) { table->InitializeAppend(transaction, append_state, append_count); @@ -225324,7 +238684,7 @@ void LocalTableStorage::AppendToIndexes(Transaction &transaction, TableAppendSta OptimisticDataWriter *LocalTableStorage::CreateOptimisticWriter() { auto writer = make_unique(table); - optimistic_writers.push_back(move(writer)); + optimistic_writers.push_back(std::move(writer)); return optimistic_writers.back().get(); } @@ -225351,7 +238711,7 @@ LocalTableStorage *LocalTableManager::GetOrCreateStorage(DataTable *table) { if (entry == table_storage.end()) { auto new_storage = make_shared(*table); auto storage = new_storage.get(); - table_storage.insert(make_pair(table, move(new_storage))); + table_storage.insert(make_pair(table, std::move(new_storage))); return storage; } else { return entry->second.get(); @@ -225369,14 +238729,14 @@ shared_ptr LocalTableManager::MoveEntry(DataTable *table) { if (entry == table_storage.end()) { return nullptr; } - auto storage_entry = move(entry->second); + auto storage_entry = std::move(entry->second); table_storage.erase(table); return storage_entry; } unordered_map> LocalTableManager::MoveEntries() { lock_guard l(table_storage_lock); - return move(table_storage); + return std::move(table_storage); } idx_t LocalTableManager::EstimatedSize() { @@ -225391,22 +238751,26 @@ idx_t LocalTableManager::EstimatedSize() { void LocalTableManager::InsertEntry(DataTable *table, shared_ptr entry) { lock_guard l(table_storage_lock); D_ASSERT(table_storage.find(table) == table_storage.end()); - table_storage[table] = move(entry); + table_storage[table] = std::move(entry); } //===--------------------------------------------------------------------===// // LocalStorage //===--------------------------------------------------------------------===// -LocalStorage::LocalStorage(ClientContext &context, Transaction &transaction) +LocalStorage::LocalStorage(ClientContext &context, DuckTransaction &transaction) : context(context), transaction(transaction) { } -LocalStorage &LocalStorage::Get(Transaction &transaction) { +LocalStorage &LocalStorage::Get(DuckTransaction &transaction) { return transaction.GetLocalStorage(); } -LocalStorage &LocalStorage::Get(ClientContext &context) { - return Transaction::GetTransaction(context).GetLocalStorage(); +LocalStorage &LocalStorage::Get(ClientContext &context, AttachedDatabase &db) { + return DuckTransaction::Get(context, db).GetLocalStorage(); +} + +LocalStorage &LocalStorage::Get(ClientContext &context, Catalog &catalog) { + return LocalStorage::Get(context, catalog.GetAttached()); } void LocalStorage::InitializeScan(DataTable *table, CollectionScanState &state, TableFilterSet *table_filters) { @@ -225553,7 +238917,7 @@ void LocalStorage::Flush(DataTable &table, LocalTableStorage &storage) { transaction.PushAppend(&table, append_state.row_start, append_count); } -void LocalStorage::Commit(LocalStorage::CommitState &commit_state, Transaction &transaction) { +void LocalStorage::Commit(LocalStorage::CommitState &commit_state, DuckTransaction &transaction) { // commit local storage // iterate over all entries in the table storage map and commit them // after this, the local storage is no longer required and can be cleared @@ -225598,7 +238962,7 @@ void LocalStorage::MoveStorage(DataTable *old_dt, DataTable *new_dt) { } // take over the storage from the old entry new_storage->table = new_dt; - table_manager.InsertEntry(new_dt, move(new_storage)); + table_manager.InsertEntry(new_dt, std::move(new_storage)); } void LocalStorage::AddColumn(DataTable *old_dt, DataTable *new_dt, ColumnDefinition &new_column, @@ -225609,7 +238973,7 @@ void LocalStorage::AddColumn(DataTable *old_dt, DataTable *new_dt, ColumnDefinit return; } auto new_storage = make_unique(context, *new_dt, *storage, new_column, default_value); - table_manager.InsertEntry(new_dt, move(new_storage)); + table_manager.InsertEntry(new_dt, std::move(new_storage)); } void LocalStorage::DropColumn(DataTable *old_dt, DataTable *new_dt, idx_t removed_column) { @@ -225619,7 +238983,7 @@ void LocalStorage::DropColumn(DataTable *old_dt, DataTable *new_dt, idx_t remove return; } auto new_storage = make_unique(*new_dt, *storage, removed_column); - table_manager.InsertEntry(new_dt, move(new_storage)); + table_manager.InsertEntry(new_dt, std::move(new_storage)); } void LocalStorage::ChangeType(DataTable *old_dt, DataTable *new_dt, idx_t changed_idx, const LogicalType &target_type, @@ -225631,23 +238995,17 @@ void LocalStorage::ChangeType(DataTable *old_dt, DataTable *new_dt, idx_t change } auto new_storage = make_unique(context, *new_dt, *storage, changed_idx, target_type, bound_columns, cast_expr); - table_manager.InsertEntry(new_dt, move(new_storage)); + table_manager.InsertEntry(new_dt, std::move(new_storage)); } -void LocalStorage::FetchChunk(DataTable *table, Vector &row_ids, idx_t count, DataChunk &verify_chunk) { +void LocalStorage::FetchChunk(DataTable *table, Vector &row_ids, idx_t count, const vector &col_ids, + DataChunk &chunk, ColumnFetchState &fetch_state) { auto storage = table_manager.GetStorage(table); if (!storage) { throw InternalException("LocalStorage::FetchChunk - local storage not found"); } - ColumnFetchState fetch_state; - vector col_ids; - vector types = storage->table->GetTypes(); - for (idx_t i = 0; i < types.size(); i++) { - col_ids.push_back(i); - } - verify_chunk.Initialize(storage->allocator, types); - storage->row_groups->Fetch(transaction, verify_chunk, col_ids, row_ids, count, fetch_state); + storage->row_groups->Fetch(transaction, chunk, col_ids, row_ids, count, fetch_state); } TableIndexList &LocalStorage::GetIndexes(DataTable *table) { @@ -225670,6 +239028,37 @@ void LocalStorage::VerifyNewConstraint(DataTable &parent, const BoundConstraint + +namespace duckdb { + +DataFileType MagicBytes::CheckMagicBytes(FileSystem *fs_p, const string &path) { + LocalFileSystem lfs; + FileSystem &fs = fs_p ? *fs_p : lfs; + if (!fs.FileExists(path)) { + return DataFileType::FILE_DOES_NOT_EXIST; + } + auto handle = fs.OpenFile(path, FileFlags::FILE_FLAGS_READ); + + constexpr const idx_t MAGIC_BYTES_READ_SIZE = 16; + char buffer[MAGIC_BYTES_READ_SIZE]; + + handle->Read(buffer, MAGIC_BYTES_READ_SIZE); + if (memcmp(buffer, "SQLite format 3\0\0\0", 16) == 0) { + return DataFileType::SQLITE_FILE; + } + if (memcmp(buffer, "PAR1", 4) == 0) { + return DataFileType::PARQUET_FILE; + } + if (memcmp(buffer + MainHeader::MAGIC_BYTE_OFFSET, MainHeader::MAGIC_BYTES, MainHeader::MAGIC_BYTE_SIZE) == 0) { + return DataFileType::DUCKDB_FILE; + } + return DataFileType::FILE_DOES_NOT_EXIST; +} + +} // namespace duckdb + + + #include namespace duckdb { @@ -225713,7 +239102,7 @@ void MetaBlockReader::ReadNewBlock(block_id_t id) { if (free_blocks_on_read) { block_manager.MarkBlockAsModified(id); } - block = block_manager.RegisterBlock(id); + block = block_manager.RegisterBlock(id, true); handle = buffer_manager.Pin(block); next_block = Load(handle.Ptr()); @@ -225731,7 +239120,7 @@ namespace duckdb { MetaBlockWriter::MetaBlockWriter(BlockManager &block_manager, block_id_t initial_block_id) : block_manager(block_manager) { if (initial_block_id == INVALID_BLOCK) { - initial_block_id = GetNextBlockId(); + initial_block_id = MetaBlockWriter::GetNextBlockId(); } block = block_manager.CreateBlock(initial_block_id, nullptr); Store(-1, block->buffer); @@ -225845,7 +239234,7 @@ bool PartialBlockManager::GetPartialBlock(idx_t segment_size, unique_ptrsecond); + partial_block = std::move(entry->second); partially_filled_blocks.erase(entry); D_ASSERT(partial_block->state.offset_in_block > 0); @@ -225862,14 +239251,14 @@ void PartialBlockManager::RegisterPartialBlock(PartialBlockAllocation &&allocati // check if the block is STILL partially filled after adding the segment_size if (new_space_left >= Storage::BLOCK_SIZE - max_partial_block_size) { // the block is still partially filled: add it to the partially_filled_blocks list - partially_filled_blocks.insert(make_pair(new_space_left, move(allocation.partial_block))); + partially_filled_blocks.insert(make_pair(new_space_left, std::move(allocation.partial_block))); } } - auto block_to_free = move(allocation.partial_block); + auto block_to_free = std::move(allocation.partial_block); if (!block_to_free && partially_filled_blocks.size() > MAX_BLOCK_MAP_SIZE) { // Free the page with the least space free. auto itr = partially_filled_blocks.begin(); - block_to_free = move(itr->second); + block_to_free = std::move(itr->second); partially_filled_blocks.erase(itr); } // Flush any block that we're not going to reuse. @@ -225912,6 +239301,7 @@ void PartialBlockManager::Clear() { namespace duckdb { + class DatabaseInstance; //! SingleFileBlockManager is an implementation for a BlockManager which manages blocks in a single file @@ -225920,7 +239310,11 @@ class SingleFileBlockManager : public BlockManager { static constexpr uint64_t BLOCK_START = Storage::FILE_HEADER_SIZE * 3; public: - SingleFileBlockManager(DatabaseInstance &db, string path, bool read_only, bool create_new, bool use_direct_io); + SingleFileBlockManager(AttachedDatabase &db, string path, bool read_only, bool use_direct_io); + + void GetFileFlags(uint8_t &flags, FileLockType &lock, bool create_new); + void CreateNewDatabase(); + void LoadExistingDatabase(); //! Creates a new Block using the specified block_id and returns a pointer unique_ptr CreateBlock(block_id_t block_id, FileBuffer *source_buffer) override; @@ -225954,11 +239348,14 @@ class SingleFileBlockManager : public BlockManager { void Initialize(DatabaseHeader &header); + void ReadAndChecksum(FileBuffer &handle, uint64_t location) const; + void ChecksumAndWrite(FileBuffer &handle, uint64_t location) const; + //! Return the blocks to which we will write the free list and modified blocks vector GetFreeListBlocks(); private: - DatabaseInstance &db; + AttachedDatabase &db; //! The active DatabaseHeader, either 0 (h1) or 1 (h2) uint8_t active_header; //! The path where the file is stored @@ -226003,6 +239400,7 @@ class SingleFileBlockManager : public BlockManager { + #include #include @@ -226023,11 +239421,11 @@ void MainHeader::Serialize(Serializer &ser) { void MainHeader::CheckMagicBytes(FileHandle &handle) { data_t magic_bytes[MAGIC_BYTE_SIZE]; if (handle.GetFileSize() < MainHeader::MAGIC_BYTE_SIZE + MainHeader::MAGIC_BYTE_OFFSET) { - throw IOException("The file is not a valid DuckDB database file!"); + throw IOException("The file \"%s\" exists, but it is not a valid DuckDB database file!", handle.path); } handle.Read(magic_bytes, MainHeader::MAGIC_BYTE_SIZE, MainHeader::MAGIC_BYTE_OFFSET); if (memcmp(magic_bytes, MainHeader::MAGIC_BYTES, MainHeader::MAGIC_BYTE_SIZE) != 0) { - throw IOException("The file is not a valid DuckDB database file!"); + throw IOException("The file \"%s\" exists, but it is not a valid DuckDB database file!", handle.path); } } @@ -226039,6 +239437,29 @@ MainHeader MainHeader::Deserialize(Deserializer &source) { throw IOException("The file is not a valid DuckDB database file!"); } header.version_number = source.Read(); + // check the version number + if (header.version_number != VERSION_NUMBER) { + auto version = GetDuckDBVersion(header.version_number); + string version_text; + if (version) { + // known version + version_text = "DuckDB version " + string(version); + } else { + version_text = string("an ") + (VERSION_NUMBER > header.version_number ? "older development" : "newer") + + string(" version of DuckDB"); + } + throw IOException( + "Trying to read a database file with version number %lld, but we can only read version %lld.\n" + "The database file was created with %s.\n\n" + "The storage of DuckDB is not yet stable; newer versions of DuckDB cannot read old database files and " + "vice versa.\n" + "The storage will be stabilized when version 1.0 releases.\n\n" + "For now, we recommend that you load the database file in a supported version of DuckDB, and use the " + "EXPORT DATABASE command " + "followed by IMPORT DATABASE on the current version of DuckDB.\n\n" + "See the storage page for more information: https://duckdb.org/internals/storage", + header.version_number, VERSION_NUMBER, version_text); + } // read the flags FieldReader reader(source); for (idx_t i = 0; i < FLAG_COUNT; i++) { @@ -226076,14 +239497,14 @@ T DeserializeHeaderStructure(data_ptr_t ptr) { return T::Deserialize(source); } -SingleFileBlockManager::SingleFileBlockManager(DatabaseInstance &db, string path_p, bool read_only, bool create_new, - bool use_direct_io) - : BlockManager(BufferManager::GetBufferManager(db)), db(db), path(move(path_p)), +SingleFileBlockManager::SingleFileBlockManager(AttachedDatabase &db, string path_p, bool read_only, bool use_direct_io) + : BlockManager(BufferManager::GetBufferManager(db)), db(db), path(std::move(path_p)), header_buffer(Allocator::Get(db), FileBufferType::MANAGED_BUFFER, Storage::FILE_HEADER_SIZE - Storage::BLOCK_HEADER_SIZE), iteration_count(0), read_only(read_only), use_direct_io(use_direct_io) { - uint8_t flags; - FileLockType lock; +} + +void SingleFileBlockManager::GetFileFlags(uint8_t &flags, FileLockType &lock, bool create_new) { if (read_only) { D_ASSERT(!create_new); flags = FileFlags::FILE_FLAGS_READ; @@ -226098,86 +239519,110 @@ SingleFileBlockManager::SingleFileBlockManager(DatabaseInstance &db, string path if (use_direct_io) { flags |= FileFlags::FILE_FLAGS_DIRECT_IO; } +} + +void SingleFileBlockManager::CreateNewDatabase() { + uint8_t flags; + FileLockType lock; + GetFileFlags(flags, lock, true); + // open the RDBMS handle - auto &fs = FileSystem::GetFileSystem(db); + auto &fs = FileSystem::Get(db); handle = fs.OpenFile(path, flags, lock); - if (create_new) { - // if we create a new file, we fill the metadata of the file - // first fill in the new header - header_buffer.Clear(); - - MainHeader main_header; - main_header.version_number = VERSION_NUMBER; - memset(main_header.flags, 0, sizeof(uint64_t) * 4); - - SerializeHeaderStructure(main_header, header_buffer.buffer); - // now write the header to the file - header_buffer.ChecksumAndWrite(*handle, 0); - header_buffer.Clear(); - - // write the database headers - // initialize meta_block and free_list to INVALID_BLOCK because the database file does not contain any actual - // content yet - DatabaseHeader h1, h2; - // header 1 - h1.iteration = 0; - h1.meta_block = INVALID_BLOCK; - h1.free_list = INVALID_BLOCK; - h1.block_count = 0; - SerializeHeaderStructure(h1, header_buffer.buffer); - header_buffer.ChecksumAndWrite(*handle, Storage::FILE_HEADER_SIZE); - // header 2 - h2.iteration = 0; - h2.meta_block = INVALID_BLOCK; - h2.free_list = INVALID_BLOCK; - h2.block_count = 0; - SerializeHeaderStructure(h2, header_buffer.buffer); - header_buffer.ChecksumAndWrite(*handle, Storage::FILE_HEADER_SIZE * 2); - // ensure that writing to disk is completed before returning - handle->Sync(); - // we start with h2 as active_header, this way our initial write will be in h1 - iteration_count = 0; - active_header = 1; - max_block = 0; + + // if we create a new file, we fill the metadata of the file + // first fill in the new header + header_buffer.Clear(); + + MainHeader main_header; + main_header.version_number = VERSION_NUMBER; + memset(main_header.flags, 0, sizeof(uint64_t) * 4); + + SerializeHeaderStructure(main_header, header_buffer.buffer); + // now write the header to the file + ChecksumAndWrite(header_buffer, 0); + header_buffer.Clear(); + + // write the database headers + // initialize meta_block and free_list to INVALID_BLOCK because the database file does not contain any actual + // content yet + DatabaseHeader h1, h2; + // header 1 + h1.iteration = 0; + h1.meta_block = INVALID_BLOCK; + h1.free_list = INVALID_BLOCK; + h1.block_count = 0; + SerializeHeaderStructure(h1, header_buffer.buffer); + ChecksumAndWrite(header_buffer, Storage::FILE_HEADER_SIZE); + // header 2 + h2.iteration = 0; + h2.meta_block = INVALID_BLOCK; + h2.free_list = INVALID_BLOCK; + h2.block_count = 0; + SerializeHeaderStructure(h2, header_buffer.buffer); + ChecksumAndWrite(header_buffer, Storage::FILE_HEADER_SIZE * 2); + // ensure that writing to disk is completed before returning + handle->Sync(); + // we start with h2 as active_header, this way our initial write will be in h1 + iteration_count = 0; + active_header = 1; + max_block = 0; +} + +void SingleFileBlockManager::LoadExistingDatabase() { + uint8_t flags; + FileLockType lock; + GetFileFlags(flags, lock, false); + + // open the RDBMS handle + auto &fs = FileSystem::Get(db); + handle = fs.OpenFile(path, flags, lock); + + MainHeader::CheckMagicBytes(*handle); + // otherwise, we check the metadata of the file + ReadAndChecksum(header_buffer, 0); + DeserializeHeaderStructure(header_buffer.buffer); + + // read the database headers from disk + DatabaseHeader h1, h2; + ReadAndChecksum(header_buffer, Storage::FILE_HEADER_SIZE); + h1 = DeserializeHeaderStructure(header_buffer.buffer); + ReadAndChecksum(header_buffer, Storage::FILE_HEADER_SIZE * 2); + h2 = DeserializeHeaderStructure(header_buffer.buffer); + // check the header with the highest iteration count + if (h1.iteration > h2.iteration) { + // h1 is active header + active_header = 0; + Initialize(h1); } else { - MainHeader::CheckMagicBytes(*handle); - // otherwise, we check the metadata of the file - header_buffer.ReadAndChecksum(*handle, 0); - MainHeader header = DeserializeHeaderStructure(header_buffer.buffer); - // check the version number - if (header.version_number != VERSION_NUMBER) { - throw IOException( - "Trying to read a database file with version number %lld, but we can only read version %lld.\n" - "The database file was created with an %s version of DuckDB.\n\n" - "The storage of DuckDB is not yet stable; newer versions of DuckDB cannot read old database files and " - "vice versa.\n" - "The storage will be stabilized when version 1.0 releases.\n\n" - "For now, we recommend that you load the database file in a supported version of DuckDB, and use the " - "EXPORT DATABASE command " - "followed by IMPORT DATABASE on the current version of DuckDB.", - header.version_number, VERSION_NUMBER, VERSION_NUMBER > header.version_number ? "older" : "newer"); - } - - // read the database headers from disk - DatabaseHeader h1, h2; - header_buffer.ReadAndChecksum(*handle, Storage::FILE_HEADER_SIZE); - h1 = DeserializeHeaderStructure(header_buffer.buffer); - header_buffer.ReadAndChecksum(*handle, Storage::FILE_HEADER_SIZE * 2); - h2 = DeserializeHeaderStructure(header_buffer.buffer); - // check the header with the highest iteration count - if (h1.iteration > h2.iteration) { - // h1 is active header - active_header = 0; - Initialize(h1); - } else { - // h2 is active header - active_header = 1; - Initialize(h2); - } - LoadFreeList(); + // h2 is active header + active_header = 1; + Initialize(h2); + } + LoadFreeList(); +} + +void SingleFileBlockManager::ReadAndChecksum(FileBuffer &block, uint64_t location) const { + // read the buffer from disk + block.Read(*handle, location); + // compute the checksum + auto stored_checksum = Load(block.InternalBuffer()); + uint64_t computed_checksum = Checksum(block.buffer, block.size); + // verify the checksum + if (stored_checksum != computed_checksum) { + throw IOException("Corrupt database file: computed checksum %llu does not match stored checksum %llu in block", + computed_checksum, stored_checksum); } } +void SingleFileBlockManager::ChecksumAndWrite(FileBuffer &block, uint64_t location) const { + // compute the checksum and write it to the start of the buffer (if not temp buffer) + uint64_t checksum = Checksum(block.buffer, block.size); + Store(checksum, block.InternalBuffer()); + // now write the buffer + block.Write(*handle, location); +} + void SingleFileBlockManager::Initialize(DatabaseHeader &header) { free_list_id = header.free_list; meta_block = header.meta_block; @@ -226300,12 +239745,12 @@ unique_ptr SingleFileBlockManager::CreateBlock(block_id_t block_id, FileB void SingleFileBlockManager::Read(Block &block) { D_ASSERT(block.id >= 0); D_ASSERT(std::find(free_list.begin(), free_list.end(), block.id) == free_list.end()); - block.ReadAndChecksum(*handle, BLOCK_START + block.id * Storage::BLOCK_ALLOC_SIZE); + ReadAndChecksum(block, BLOCK_START + block.id * Storage::BLOCK_ALLOC_SIZE); } void SingleFileBlockManager::Write(FileBuffer &buffer, block_id_t block_id) { D_ASSERT(block_id >= 0); - buffer.ChecksumAndWrite(*handle, BLOCK_START + block_id * Storage::BLOCK_ALLOC_SIZE); + ChecksumAndWrite(buffer, BLOCK_START + block_id * Storage::BLOCK_ALLOC_SIZE); } vector SingleFileBlockManager::GetFreeListBlocks() { @@ -226399,7 +239844,7 @@ void SingleFileBlockManager::WriteHeader(DatabaseHeader header) { } header.block_count = max_block; - auto &config = DBConfig::GetConfig(db); + auto &config = DBConfig::Get(db); if (config.options.checkpoint_abort == CheckpointAbort::DEBUG_ABORT_AFTER_FREE_LIST_WRITE) { throw FatalException("Checkpoint aborted after free list write because of PRAGMA checkpoint_abort flag"); } @@ -226414,8 +239859,7 @@ void SingleFileBlockManager::WriteHeader(DatabaseHeader header) { Store(header, header_buffer.buffer); // now write the header to the file, active_header determines whether we write to h1 or h2 // note that if active_header is h1 we write to h2, and vice versa - header_buffer.ChecksumAndWrite(*handle, - active_header == 1 ? Storage::FILE_HEADER_SIZE : Storage::FILE_HEADER_SIZE * 2); + ChecksumAndWrite(header_buffer, active_header == 1 ? Storage::FILE_HEADER_SIZE : Storage::FILE_HEADER_SIZE * 2); // switch active header to the other header active_header = 1 - active_header; //! Ensure the header write ends up on disk @@ -226436,7 +239880,8 @@ void SingleFileBlockManager::WriteHeader(DatabaseHeader header) { namespace duckdb { -BaseStatistics::BaseStatistics(LogicalType type, StatisticsType stats_type) : type(move(type)), stats_type(stats_type) { +BaseStatistics::BaseStatistics(LogicalType type, StatisticsType stats_type) + : type(std::move(type)), stats_type(stats_type) { } BaseStatistics::~BaseStatistics() { @@ -226518,20 +239963,20 @@ unique_ptr BaseStatistics::CreateEmpty(LogicalType type, Statist case PhysicalType::INT128: case PhysicalType::FLOAT: case PhysicalType::DOUBLE: - result = make_unique(move(type), stats_type); + result = make_unique(std::move(type), stats_type); break; case PhysicalType::VARCHAR: - result = make_unique(move(type), stats_type); + result = make_unique(std::move(type), stats_type); break; case PhysicalType::STRUCT: - result = make_unique(move(type)); + result = make_unique(std::move(type)); break; case PhysicalType::LIST: - result = make_unique(move(type)); + result = make_unique(std::move(type)); break; case PhysicalType::INTERVAL: default: - result = make_unique(move(type), stats_type); + result = make_unique(std::move(type), stats_type); } result->InitializeBase(); return result; @@ -226588,26 +240033,26 @@ unique_ptr BaseStatistics::Deserialize(Deserializer &source, Log case PhysicalType::INT128: case PhysicalType::FLOAT: case PhysicalType::DOUBLE: - result = NumericStatistics::Deserialize(reader, move(type)); + result = NumericStatistics::Deserialize(reader, std::move(type)); break; case PhysicalType::VARCHAR: - result = StringStatistics::Deserialize(reader, move(type)); + result = StringStatistics::Deserialize(reader, std::move(type)); break; case PhysicalType::STRUCT: - result = StructStatistics::Deserialize(reader, move(type)); + result = StructStatistics::Deserialize(reader, std::move(type)); break; case PhysicalType::LIST: - result = ListStatistics::Deserialize(reader, move(type)); + result = ListStatistics::Deserialize(reader, std::move(type)); break; case PhysicalType::INTERVAL: - result = make_unique(move(type), StatisticsType::LOCAL_STATS); + result = make_unique(std::move(type), StatisticsType::LOCAL_STATS); break; default: throw InternalException("Unimplemented type for statistics deserialization"); } if (ptype != PhysicalType::BIT) { - result->validity_stats = move(validity_stats); + result->validity_stats = std::move(validity_stats); result->stats_type = reader.ReadField(StatisticsType::LOCAL_STATS); result->distinct_stats = reader.ReadOptional(nullptr); } @@ -226638,12 +240083,12 @@ void BaseStatistics::Verify(Vector &vector, idx_t count) const { namespace duckdb { -ColumnStatistics::ColumnStatistics(unique_ptr stats_p) : stats(move(stats_p)) { +ColumnStatistics::ColumnStatistics(unique_ptr stats_p) : stats(std::move(stats_p)) { } shared_ptr ColumnStatistics::CreateEmptyStats(const LogicalType &type) { auto col_stats = BaseStatistics::CreateEmpty(type, StatisticsType::GLOBAL_STATS); - return make_shared(move(col_stats)); + return make_shared(std::move(col_stats)); } } // namespace duckdb @@ -226662,8 +240107,8 @@ DistinctStatistics::DistinctStatistics() } DistinctStatistics::DistinctStatistics(unique_ptr log, idx_t sample_count, idx_t total_count) - : BaseStatistics(LogicalType::INVALID, StatisticsType::LOCAL_STATS), log(move(log)), sample_count(sample_count), - total_count(total_count) { + : BaseStatistics(LogicalType::INVALID, StatisticsType::LOCAL_STATS), log(std::move(log)), + sample_count(sample_count), total_count(total_count) { } unique_ptr DistinctStatistics::Copy() const { @@ -226757,7 +240202,7 @@ idx_t DistinctStatistics::GetCount() const { namespace duckdb { -ListStatistics::ListStatistics(LogicalType type_p) : BaseStatistics(move(type_p), StatisticsType::LOCAL_STATS) { +ListStatistics::ListStatistics(LogicalType type_p) : BaseStatistics(std::move(type_p), StatisticsType::LOCAL_STATS) { D_ASSERT(type.InternalType() == PhysicalType::LIST); InitializeBase(); auto &child_type = ListType::GetChildType(type); @@ -226786,7 +240231,7 @@ unique_ptr ListStatistics::Copy() const { result->CopyBase(*this); result->child_stats = child_stats ? child_stats->Copy() : nullptr; - return move(result); + return std::move(result); } void ListStatistics::Serialize(FieldWriter &writer) const { @@ -226795,10 +240240,10 @@ void ListStatistics::Serialize(FieldWriter &writer) const { unique_ptr ListStatistics::Deserialize(FieldReader &reader, LogicalType type) { D_ASSERT(type.InternalType() == PhysicalType::LIST); - auto result = make_unique(move(type)); + auto result = make_unique(std::move(type)); auto &child_type = ListType::GetChildType(result->type); result->child_stats = reader.ReadRequiredSerializable(child_type); - return move(result); + return std::move(result); } string ListStatistics::ToString() const { @@ -226860,14 +240305,14 @@ void NumericStatistics::Update(SegmentStatistics &stats, list_entr } NumericStatistics::NumericStatistics(LogicalType type_p, StatisticsType stats_type) - : BaseStatistics(move(type_p), stats_type) { + : BaseStatistics(std::move(type_p), stats_type) { InitializeBase(); min = Value::MaximumValue(type); max = Value::MinimumValue(type); } NumericStatistics::NumericStatistics(LogicalType type_p, Value min_p, Value max_p, StatisticsType stats_type) - : BaseStatistics(move(type_p), stats_type), min(move(min_p)), max(move(max_p)) { + : BaseStatistics(std::move(type_p), stats_type), min(std::move(min_p)), max(std::move(max_p)) { InitializeBase(); } @@ -226962,22 +240407,120 @@ FilterPropagateResult NumericStatistics::CheckZonemap(ExpressionType comparison_ unique_ptr NumericStatistics::Copy() const { auto result = make_unique(type, min, max, stats_type); result->CopyBase(*this); - return move(result); + return std::move(result); } bool NumericStatistics::IsConstant() const { return max <= min; } +void SerializeNumericStatsValue(const Value &val, FieldWriter &writer) { + writer.WriteField(val.IsNull()); + if (val.IsNull()) { + return; + } + switch (val.type().InternalType()) { + case PhysicalType::BOOL: + writer.WriteField(BooleanValue::Get(val)); + break; + case PhysicalType::INT8: + writer.WriteField(TinyIntValue::Get(val)); + break; + case PhysicalType::INT16: + writer.WriteField(SmallIntValue::Get(val)); + break; + case PhysicalType::INT32: + writer.WriteField(IntegerValue::Get(val)); + break; + case PhysicalType::INT64: + writer.WriteField(BigIntValue::Get(val)); + break; + case PhysicalType::UINT8: + writer.WriteField(UTinyIntValue::Get(val)); + break; + case PhysicalType::UINT16: + writer.WriteField(USmallIntValue::Get(val)); + break; + case PhysicalType::UINT32: + writer.WriteField(UIntegerValue::Get(val)); + break; + case PhysicalType::UINT64: + writer.WriteField(UBigIntValue::Get(val)); + break; + case PhysicalType::INT128: + writer.WriteField(HugeIntValue::Get(val)); + break; + case PhysicalType::FLOAT: + writer.WriteField(FloatValue::Get(val)); + break; + case PhysicalType::DOUBLE: + writer.WriteField(DoubleValue::Get(val)); + break; + default: + throw InternalException("Unsupported type for serializing numeric statistics"); + } +} + void NumericStatistics::Serialize(FieldWriter &writer) const { - writer.WriteSerializable(min); - writer.WriteSerializable(max); + SerializeNumericStatsValue(min, writer); + SerializeNumericStatsValue(max, writer); +} + +Value DeserializeNumericStatsValue(const LogicalType &type, FieldReader &reader) { + auto is_null = reader.ReadRequired(); + if (is_null) { + return Value(type); + } + Value result; + switch (type.InternalType()) { + case PhysicalType::BOOL: + result = Value::BOOLEAN(reader.ReadRequired()); + break; + case PhysicalType::INT8: + result = Value::TINYINT(reader.ReadRequired()); + break; + case PhysicalType::INT16: + result = Value::SMALLINT(reader.ReadRequired()); + break; + case PhysicalType::INT32: + result = Value::INTEGER(reader.ReadRequired()); + break; + case PhysicalType::INT64: + result = Value::BIGINT(reader.ReadRequired()); + break; + case PhysicalType::UINT8: + result = Value::UTINYINT(reader.ReadRequired()); + break; + case PhysicalType::UINT16: + result = Value::USMALLINT(reader.ReadRequired()); + break; + case PhysicalType::UINT32: + result = Value::UINTEGER(reader.ReadRequired()); + break; + case PhysicalType::UINT64: + result = Value::UBIGINT(reader.ReadRequired()); + break; + case PhysicalType::INT128: + result = Value::HUGEINT(reader.ReadRequired()); + break; + case PhysicalType::FLOAT: + result = Value::FLOAT(reader.ReadRequired()); + break; + case PhysicalType::DOUBLE: + result = Value::DOUBLE(reader.ReadRequired()); + break; + default: + throw InternalException("Unsupported type for deserializing numeric statistics"); + } + result.Reinterpret(type); + return result; } unique_ptr NumericStatistics::Deserialize(FieldReader &reader, LogicalType type) { - auto min = reader.ReadRequiredSerializable(); - auto max = reader.ReadRequiredSerializable(); - return make_unique_base(move(type), min, max, StatisticsType::LOCAL_STATS); + auto min = DeserializeNumericStatsValue(type, reader); + auto max = DeserializeNumericStatsValue(type, reader); + return make_unique_base(std::move(type), std::move(min), std::move(max), + StatisticsType::LOCAL_STATS); } string NumericStatistics::ToString() const { @@ -227058,12 +240601,12 @@ void NumericStatistics::Verify(Vector &vector, const SelectionVector &sel, idx_t namespace duckdb { -SegmentStatistics::SegmentStatistics(LogicalType type) : type(move(type)) { +SegmentStatistics::SegmentStatistics(LogicalType type) : type(std::move(type)) { Reset(); } SegmentStatistics::SegmentStatistics(LogicalType type, unique_ptr stats) - : type(move(type)), statistics(move(stats)) { + : type(std::move(type)), statistics(std::move(stats)) { if (!statistics) { Reset(); } @@ -227084,7 +240627,7 @@ void SegmentStatistics::Reset() { namespace duckdb { StringStatistics::StringStatistics(LogicalType type_p, StatisticsType stats_type) - : BaseStatistics(move(type_p), stats_type) { + : BaseStatistics(std::move(type_p), stats_type) { InitializeBase(); for (idx_t i = 0; i < MAX_STRING_MINMAX_SIZE; i++) { min[i] = 0xFF; @@ -227103,7 +240646,7 @@ unique_ptr StringStatistics::Copy() const { memcpy(result->max, max, MAX_STRING_MINMAX_SIZE); result->has_unicode = has_unicode; result->max_string_length = max_string_length; - return move(result); + return std::move(result); } void StringStatistics::Serialize(FieldWriter &writer) const { @@ -227115,13 +240658,13 @@ void StringStatistics::Serialize(FieldWriter &writer) const { } unique_ptr StringStatistics::Deserialize(FieldReader &reader, LogicalType type) { - auto stats = make_unique(move(type), StatisticsType::LOCAL_STATS); + auto stats = make_unique(std::move(type), StatisticsType::LOCAL_STATS); reader.ReadBlob(stats->min, MAX_STRING_MINMAX_SIZE); reader.ReadBlob(stats->max, MAX_STRING_MINMAX_SIZE); stats->has_unicode = reader.ReadRequired(); stats->max_string_length = reader.ReadRequired(); stats->has_overflow_strings = reader.ReadRequired(); - return move(stats); + return std::move(stats); } static int StringValueComparison(const_data_ptr_t data, idx_t len, const_data_ptr_t comparison) { @@ -227301,7 +240844,8 @@ void StringStatistics::Verify(Vector &vector, const SelectionVector &sel, idx_t namespace duckdb { -StructStatistics::StructStatistics(LogicalType type_p) : BaseStatistics(move(type_p), StatisticsType::LOCAL_STATS) { +StructStatistics::StructStatistics(LogicalType type_p) + : BaseStatistics(std::move(type_p), StatisticsType::LOCAL_STATS) { D_ASSERT(type.InternalType() == PhysicalType::STRUCT); InitializeBase(); @@ -227339,7 +240883,7 @@ unique_ptr StructStatistics::Copy() const { for (idx_t i = 0; i < child_stats.size(); i++) { result->child_stats[i] = child_stats[i] ? child_stats[i]->Copy() : nullptr; } - return move(result); + return std::move(result); } void StructStatistics::Serialize(FieldWriter &writer) const { @@ -227355,7 +240899,7 @@ void StructStatistics::Serialize(FieldWriter &writer) const { unique_ptr StructStatistics::Deserialize(FieldReader &reader, LogicalType type) { D_ASSERT(type.InternalType() == PhysicalType::STRUCT); - auto result = make_unique(move(type)); + auto result = make_unique(std::move(type)); auto &child_types = StructType::GetChildTypes(result->type); auto child_type_count = reader.ReadRequired(); @@ -227371,7 +240915,7 @@ unique_ptr StructStatistics::Deserialize(FieldReader &reader, Lo result->child_stats[i].reset(); } } - return move(result); + return std::move(result); } string StructStatistics::ToString() const { @@ -227496,7 +241040,38 @@ string ValidityStatistics::ToString() const { namespace duckdb { -const uint64_t VERSION_NUMBER = 39; +const uint64_t VERSION_NUMBER = 43; + +struct StorageVersionInfo { + const char *version_name; + idx_t storage_version; +}; + +static StorageVersionInfo storage_version_info[] = {{"v0.6.0 or v0.6.1", 39}, + {"v0.5.0 or v0.5.1", 38}, + {"v0.3.3, v0.3.4 or v0.4.0", 33}, + {"v0.3.2", 31}, + {"v0.3.1", 27}, + {"v0.3.0", 25}, + {"v0.2.9", 21}, + {"v0.2.8", 18}, + {"v0.2.7", 17}, + {"v0.2.6", 15}, + {"v0.2.5", 13}, + {"v0.2.4", 11}, + {"v0.2.3", 6}, + {"v0.2.2", 4}, + {"v0.2.1 and prior", 1}, + {nullptr, 0}}; + +const char *GetDuckDBVersion(idx_t version_number) { + for (idx_t i = 0; storage_version_info[i].version_name; i++) { + if (version_number == storage_version_info[i].storage_version) { + return storage_version_info[i].version_name; + } + } + return nullptr; +} } // namespace duckdb @@ -227558,18 +241133,27 @@ void StorageLock::ReleaseSharedLock() { - namespace duckdb { -StorageManager::StorageManager(DatabaseInstance &db, string path, bool read_only) - : db(db), path(move(path)), read_only(read_only) { +StorageManager::StorageManager(AttachedDatabase &db, string path_p, bool read_only) + : db(db), path(std::move(path_p)), read_only(read_only) { + if (path.empty()) { + path = ":memory:"; + } } StorageManager::~StorageManager() { } -StorageManager &StorageManager::GetStorageManager(ClientContext &context) { - return StorageManager::GetStorageManager(*context.db); +StorageManager &StorageManager::Get(AttachedDatabase &db) { + return db.GetStorageManager(); +} +StorageManager &StorageManager::Get(Catalog &catalog) { + return StorageManager::Get(catalog.GetAttached()); +} + +DatabaseInstance &StorageManager::GetDatabase() { + return db.GetDatabase(); } BufferManager &BufferManager::GetBufferManager(ClientContext &context) { @@ -227585,12 +241169,8 @@ bool ObjectCache::ObjectCacheEnabled(ClientContext &context) { } bool StorageManager::InMemory() { - return path.empty() || path == ":memory:"; -} - -void StorageManager::CreateBufferManager() { - auto &config = DBConfig::GetConfig(db); - buffer_manager = make_unique(db, config.options.temporary_directory, config.options.maximum_memory); + D_ASSERT(!path.empty()); + return path == ":memory:"; } void StorageManager::Initialize() { @@ -227598,30 +241178,6 @@ void StorageManager::Initialize() { if (in_memory && read_only) { throw CatalogException("Cannot launch in-memory database in read-only mode!"); } - CreateBufferManager(); - - auto &config = DBConfig::GetConfig(db); - auto &catalog = Catalog::GetCatalog(db); - - // first initialize the base system catalogs - // these are never written to the WAL - Connection con(db); - con.BeginTransaction(); - - // create the default schema - CreateSchemaInfo info; - info.schema = DEFAULT_SCHEMA; - info.internal = true; - catalog.CreateSchema(*con.context, &info); - - if (config.options.initialize_default_database) { - // initialize default functions - BuiltinFunctions builtin(*con.context, catalog); - builtin.Initialize(); - } - - // commit transactions - con.Commit(); // create or load the database from disk, if not in-memory mode LoadDatabase(); @@ -227644,20 +241200,20 @@ class SingleFileTableIOManager : public TableIOManager { } }; -SingleFileStorageManager::SingleFileStorageManager(DatabaseInstance &db, string path, bool read_only) - : StorageManager(db, move(path), read_only) { +SingleFileStorageManager::SingleFileStorageManager(AttachedDatabase &db, string path, bool read_only) + : StorageManager(db, std::move(path), read_only) { } void SingleFileStorageManager::LoadDatabase() { if (InMemory()) { - block_manager = make_unique(*buffer_manager); + block_manager = make_unique(BufferManager::GetBufferManager(db)); table_io_manager = make_unique(*block_manager); return; } string wal_path = path + ".wal"; - auto &fs = db.GetFileSystem(); - auto &config = db.config; + auto &fs = FileSystem::Get(db); + auto &config = DBConfig::Get(db); bool truncate_wal = false; // first check if the database exists if (!fs.FileExists(path)) { @@ -227671,16 +241227,22 @@ void SingleFileStorageManager::LoadDatabase() { fs.RemoveFile(wal_path); } // initialize the block manager while creating a new db file - block_manager = make_unique(db, path, read_only, true, config.options.use_direct_io); + auto sf_block_manager = make_unique(db, path, read_only, config.options.use_direct_io); + sf_block_manager->CreateNewDatabase(); + block_manager = std::move(sf_block_manager); table_io_manager = make_unique(*block_manager); } else { // initialize the block manager while loading the current db file - block_manager = make_unique(db, path, read_only, false, config.options.use_direct_io); + auto sf_block_manager = make_unique(db, path, read_only, config.options.use_direct_io); + sf_block_manager->LoadExistingDatabase(); + block_manager = std::move(sf_block_manager); table_io_manager = make_unique(*block_manager); //! Load from storage auto checkpointer = SingleFileCheckpointReader(*this); checkpointer.LoadFromStorage(); + // finish load checkpoint, clear the cached handles of meta blocks + block_manager->ClearMetaBlockHandles(); // check if the WAL file exists if (fs.FileExists(wal_path)) { // replay the WAL @@ -227771,7 +241333,8 @@ void SingleFileStorageManager::CreateCheckpoint(bool delete_wal, bool force_chec if (InMemory() || read_only || !wal) { return; } - if (wal->GetWALSize() > 0 || db.config.options.force_checkpoint || force_checkpoint) { + auto &config = DBConfig::Get(db); + if (wal->GetWALSize() > 0 || config.options.force_checkpoint || force_checkpoint) { // we only need to checkpoint if there is anything in the WAL SingleFileCheckpointWriter checkpointer(db, *block_manager); checkpointer.CreateCheckpoint(); @@ -227804,9 +241367,10 @@ bool SingleFileStorageManager::AutomaticCheckpoint(idx_t estimated_wal_bytes) { return false; } + auto &config = DBConfig::Get(db); auto initial_size = log->GetWALSize(); idx_t expected_wal_size = initial_size + estimated_wal_bytes; - return expected_wal_size > db.config.options.checkpoint_wal_size; + return expected_wal_size > config.options.checkpoint_wal_size; } shared_ptr SingleFileStorageManager::GetTableIOManager(BoundCreateTableInfo *info /*info*/) { @@ -227913,7 +241477,7 @@ unique_ptr ChunkConstantInfo::Deserialize(Deserializer &source) { auto info = make_unique(start); info->insert_id = 0; info->delete_id = 0; - return move(info); + return std::move(info); } //===--------------------------------------------------------------------===// @@ -228074,7 +241638,7 @@ unique_ptr ChunkVectorInfo::Deserialize(Deserializer &source) { result->deleted[i] = 0; } } - return move(result); + return std::move(result); } } // namespace duckdb @@ -228145,7 +241709,7 @@ class ListColumnData : public ColumnData { void DeserializeColumn(Deserializer &source) override; - void GetStorageInfo(idx_t row_group_index, vector col_path, vector> &result) override; + void GetStorageInfo(idx_t row_group_index, vector col_path, TableStorageInfo &result) override; private: list_entry_t FetchListEntry(idx_t row_idx); @@ -228171,7 +241735,7 @@ ColumnCheckpointState::~ColumnCheckpointState() { unique_ptr ColumnCheckpointState::GetStatistics() { D_ASSERT(global_stats); - return move(global_stats); + return std::move(global_stats); } struct PartialBlockForCheckpoint : PartialBlock { @@ -228281,7 +241845,7 @@ void ColumnCheckpointState::FlushSegment(unique_ptr segment, idx_ &column_data, segment.get(), *allocation.block_manager, allocation.state); } // Writer will decide whether to reuse this block. - partial_block_manager.RegisterPartialBlock(move(allocation)); + partial_block_manager.RegisterPartialBlock(std::move(allocation)); } else { // constant block: no need to write anything to disk besides the stats // set up the compression function to constant @@ -228305,8 +241869,8 @@ void ColumnCheckpointState::FlushSegment(unique_ptr segment, idx_ data_pointer.statistics = segment->stats.statistics->Copy(); // append the segment to the new segment tree - new_tree.AppendSegment(move(segment)); - data_pointers.push_back(move(data_pointer)); + new_tree.AppendSegment(std::move(segment)); + data_pointers.push_back(std::move(data_pointer)); } void ColumnCheckpointState::WriteDataPointers(RowGroupWriter &writer) { @@ -228398,7 +241962,7 @@ class StructColumnData : public ColumnData { void DeserializeColumn(Deserializer &source) override; - void GetStorageInfo(idx_t row_group_index, vector col_path, vector> &result) override; + void GetStorageInfo(idx_t row_group_index, vector col_path, TableStorageInfo &result) override; void Verify(RowGroup &parent) override; }; @@ -228515,17 +242079,20 @@ struct UpdateNode { } // namespace duckdb + + namespace duckdb { ColumnData::ColumnData(BlockManager &block_manager, DataTableInfo &info, idx_t column_index, idx_t start_row, LogicalType type, ColumnData *parent) - : block_manager(block_manager), info(info), column_index(column_index), start(start_row), type(move(type)), + : block_manager(block_manager), info(info), column_index(column_index), start(start_row), type(std::move(type)), parent(parent), version(0) { } ColumnData::ColumnData(ColumnData &other, idx_t start, ColumnData *parent) : block_manager(other.block_manager), info(other.info), column_index(other.column_index), start(start), - type(move(other.type)), parent(parent), updates(move(other.updates)), version(parent ? parent->version + 1 : 0) { + type(std::move(other.type)), parent(parent), updates(std::move(other.updates)), + version(parent ? parent->version + 1 : 0) { idx_t offset = 0; for (auto segment = other.data.GetRootSegment(); segment; segment = segment->Next()) { auto &other = (ColumnSegment &)*segment; @@ -228538,7 +242105,7 @@ ColumnData::~ColumnData() { } DatabaseInstance &ColumnData::GetDatabase() const { - return info.db; + return info.db.GetDatabase(); } DataTableInfo &ColumnData::GetTableInfo() const { @@ -228623,7 +242190,7 @@ idx_t ColumnData::ScanVector(ColumnScanState &state, Vector &result, idx_t remai if (!state.current->next) { break; } - state.previous_states.emplace_back(move(state.scan_state)); + state.previous_states.emplace_back(std::move(state.scan_state)); state.current = (ColumnSegment *)state.current->Next(); state.current->InitializeScan(state); state.segment_checked = false; @@ -228848,7 +242415,7 @@ void ColumnData::AppendTransientSegment(SegmentLock &l, idx_t start_row) { #endif } auto new_segment = ColumnSegment::CreateTransientSegment(GetDatabase(), type, start_row, segment_size); - data.AppendSegment(l, move(new_segment)); + data.AppendSegment(l, std::move(new_segment)); } void ColumnData::CommitDropColumn() { @@ -228895,7 +242462,7 @@ unique_ptr ColumnData::Checkpoint(RowGroup &row_group, lock_guard update_guard(update_lock); ColumnDataCheckpointer checkpointer(*this, row_group, *checkpoint_state, checkpoint_info); - checkpointer.Checkpoint(move(nodes)); + checkpointer.Checkpoint(std::move(nodes)); // replace the old tree with the new one data.Replace(l, checkpoint_state->new_tree); @@ -228921,8 +242488,8 @@ void ColumnData::DeserializeColumn(Deserializer &source) { auto segment = ColumnSegment::CreatePersistentSegment( GetDatabase(), block_manager, data_pointer.block_pointer.block_id, data_pointer.block_pointer.offset, type, data_pointer.row_start, data_pointer.tuple_count, data_pointer.compression_type, - move(data_pointer.statistics)); - data.AppendSegment(move(segment)); + std::move(data_pointer.statistics)); + data.AppendSegment(std::move(segment)); } } @@ -228934,7 +242501,7 @@ shared_ptr ColumnData::Deserialize(BlockManager &block_manager, Data return entry; } -void ColumnData::GetStorageInfo(idx_t row_group_index, vector col_path, vector> &result) { +void ColumnData::GetStorageInfo(idx_t row_group_index, vector col_path, TableStorageInfo &result) { D_ASSERT(!col_path.empty()); // convert the column path to a string @@ -228951,42 +242518,30 @@ void ColumnData::GetStorageInfo(idx_t row_group_index, vector col_path, v idx_t segment_idx = 0; auto segment = (ColumnSegment *)data.GetRootSegment(); while (segment) { - vector column_info; - // row_group_id - column_info.push_back(Value::BIGINT(row_group_index)); - // column_id - column_info.push_back(Value::BIGINT(col_path[0])); - // column_path - column_info.emplace_back(col_path_str); - // segment_id - column_info.push_back(Value::BIGINT(segment_idx)); - // segment_type - column_info.emplace_back(type.ToString()); - // start - column_info.push_back(Value::BIGINT(segment->start)); - // count - column_info.push_back(Value::BIGINT(segment->count)); - // compression - column_info.emplace_back(CompressionTypeToString(segment->function->type)); - // stats - column_info.emplace_back(segment->stats.statistics ? segment->stats.statistics->ToString() - : string("No Stats")); - // has_updates - column_info.push_back(Value::BOOLEAN(updates ? true : false)); + ColumnSegmentInfo column_info; + column_info.row_group_index = row_group_index; + ; + column_info.column_id = col_path[0]; + column_info.column_path = col_path_str; + column_info.segment_idx = segment_idx; + column_info.segment_type = type.ToString(); + column_info.segment_start = segment->start; + column_info.segment_count = segment->count; + column_info.compression_type = CompressionTypeToString(segment->function->type); + column_info.segment_stats = + segment->stats.statistics ? segment->stats.statistics->ToString() : string("No Stats"); + column_info.has_updates = updates ? true : false; // persistent // block_id // block_offset if (segment->segment_type == ColumnSegmentType::PERSISTENT) { - column_info.push_back(Value::BOOLEAN(true)); - column_info.push_back(Value::BIGINT(segment->GetBlockId())); - column_info.push_back(Value::BIGINT(segment->GetBlockOffset())); + column_info.persistent = true; + column_info.block_id = segment->GetBlockId(); + column_info.block_offset = segment->GetBlockOffset(); } else { - column_info.push_back(Value::BOOLEAN(false)); - column_info.emplace_back(); - column_info.emplace_back(); + column_info.persistent = false; } - - result.push_back(move(column_info)); + result.column_segments.push_back(std::move(column_info)); segment_idx++; segment = (ColumnSegment *)segment->Next(); @@ -229207,7 +242762,7 @@ unique_ptr ColumnDataCheckpointer::DetectBestCompressionMethod(idx if (score < best_score || forced_method_found) { compression_idx = i; best_score = score; - state = move(analyze_states[i]); + state = std::move(analyze_states[i]); } //! If we have found the forced method, we're done if (forced_method_found) { @@ -229247,7 +242802,7 @@ void ColumnDataCheckpointer::WriteToDisk() { // now that we have analyzed the compression functions we can start writing to disk auto best_function = compression_functions[compression_idx]; - auto compress_state = best_function->init_compression(*this, move(analyze_state)); + auto compress_state = best_function->init_compression(*this, std::move(analyze_state)); ScanSegments( [&](Vector &scan_vector, idx_t count) { best_function->compress(*compress_state, scan_vector, count); }); best_function->compress_finalize(*compress_state); @@ -229293,15 +242848,15 @@ void ColumnDataCheckpointer::WritePersistentSegments() { state.global_stats->Merge(*segment->stats.statistics); // directly append the current segment to the new tree - state.new_tree.AppendSegment(move(nodes[segment_idx].node)); + state.new_tree.AppendSegment(std::move(nodes[segment_idx].node)); - state.data_pointers.push_back(move(pointer)); + state.data_pointers.push_back(std::move(pointer)); } } void ColumnDataCheckpointer::Checkpoint(vector nodes) { D_ASSERT(!nodes.empty()); - this->nodes = move(nodes); + this->nodes = std::move(nodes); // first check if any of the segments have changes if (!HasChanges()) { // no changes: only need to write the metadata for this column @@ -229346,8 +242901,8 @@ unique_ptr ColumnSegment::CreatePersistentSegment(DatabaseInstanc block = block_manager.RegisterBlock(block_id); } auto segment_size = Storage::BLOCK_SIZE; - return make_unique(db, move(block), type, ColumnSegmentType::PERSISTENT, start, count, function, - move(statistics), block_id, offset, segment_size); + return make_unique(db, std::move(block), type, ColumnSegmentType::PERSISTENT, start, count, function, + std::move(statistics), block_id, offset, segment_size); } unique_ptr ColumnSegment::CreateTransientSegment(DatabaseInstance &db, const LogicalType &type, @@ -229362,8 +242917,8 @@ unique_ptr ColumnSegment::CreateTransientSegment(DatabaseInstance } else { buffer_manager.Allocate(segment_size, false, &block); } - return make_unique(db, move(block), type, ColumnSegmentType::TRANSIENT, start, 0, function, nullptr, - INVALID_BLOCK, 0, segment_size); + return make_unique(db, std::move(block), type, ColumnSegmentType::TRANSIENT, start, 0, function, + nullptr, INVALID_BLOCK, 0, segment_size); } unique_ptr ColumnSegment::CreateSegment(ColumnSegment &other, idx_t start) { @@ -229374,8 +242929,8 @@ ColumnSegment::ColumnSegment(DatabaseInstance &db, shared_ptr block ColumnSegmentType segment_type, idx_t start, idx_t count, CompressionFunction *function_p, unique_ptr statistics, block_id_t block_id_p, idx_t offset_p, idx_t segment_size_p) - : SegmentBase(start, count), db(db), type(move(type_p)), type_size(GetTypeIdSize(type.InternalType())), - segment_type(segment_type), function(function_p), stats(type, move(statistics)), block(move(block)), + : SegmentBase(start, count), db(db), type(std::move(type_p)), type_size(GetTypeIdSize(type.InternalType())), + segment_type(segment_type), function(function_p), stats(type, std::move(statistics)), block(std::move(block)), block_id(block_id_p), offset(offset_p), segment_size(segment_size_p) { D_ASSERT(function); if (function->init_segment) { @@ -229384,10 +242939,10 @@ ColumnSegment::ColumnSegment(DatabaseInstance &db, shared_ptr block } ColumnSegment::ColumnSegment(ColumnSegment &other, idx_t start) - : SegmentBase(start, other.count), db(other.db), type(move(other.type)), type_size(other.type_size), - segment_type(other.segment_type), function(other.function), stats(move(other.stats)), block(move(other.block)), - block_id(other.block_id), offset(other.offset), segment_size(other.segment_size), - segment_state(move(other.segment_state)) { + : SegmentBase(start, other.count), db(other.db), type(std::move(other.type)), type_size(other.type_size), + segment_type(other.segment_type), function(other.function), stats(std::move(other.stats)), + block(std::move(other.block)), block_id(other.block_id), offset(other.offset), segment_size(other.segment_size), + segment_state(std::move(other.segment_state)) { } ColumnSegment::~ColumnSegment() { @@ -229448,7 +243003,7 @@ void ColumnSegment::Resize(idx_t new_size) { auto new_handle = buffer_manager.Allocate(Storage::BLOCK_SIZE, false, &new_block); memcpy(new_handle.Ptr(), old_handle.Ptr(), segment_size); this->block_id = new_block->BlockId(); - this->block = move(new_block); + this->block = std::move(new_block); this->segment_size = new_size; } @@ -229506,7 +243061,7 @@ void ColumnSegment::ConvertToPersistent(BlockManager *block_manager, block_id_t // non-constant block: write the block to disk // the data for the block already exists in-memory of our block // instead of copying the data we alter some metadata so the buffer points to an on-disk block - block = block_manager->ConvertToPersistent(block_id, move(block)); + block = block_manager->ConvertToPersistent(block_id, std::move(block)); } segment_state.reset(); @@ -229521,7 +243076,7 @@ void ColumnSegment::MarkAsPersistent(shared_ptr block_p, uint32_t o block_id = block_p->BlockId(); offset = offset_p; - block = move(block_p); + block = std::move(block_p); segment_state.reset(); if (function->init_segment) { @@ -229649,7 +243204,7 @@ idx_t ColumnSegment::FilterSelection(SelectionVector &sel, Vector &result, const // similar to the CONJUNCTION_AND, but we need to take care of the SelectionVectors (OR all of them) idx_t count_total = 0; SelectionVector result_sel(approved_tuple_count); - auto &conjunction_or = (ConjunctionOrFilter &)filter; + auto &conjunction_or = (const ConjunctionOrFilter &)filter; for (auto &child_filter : conjunction_or.child_filters) { SelectionVector temp_sel; temp_sel.Initialize(sel); @@ -229675,14 +243230,14 @@ idx_t ColumnSegment::FilterSelection(SelectionVector &sel, Vector &result, const return approved_tuple_count; } case TableFilterType::CONJUNCTION_AND: { - auto &conjunction_and = (ConjunctionAndFilter &)filter; + auto &conjunction_and = (const ConjunctionAndFilter &)filter; for (auto &child_filter : conjunction_and.child_filters) { FilterSelection(sel, result, *child_filter, approved_tuple_count, mask); } return approved_tuple_count; } case TableFilterType::CONSTANT_COMPARISON: { - auto &constant_filter = (ConstantFilter &)filter; + auto &constant_filter = (const ConstantFilter &)filter; // the inplace loops take the result as the last parameter switch (result.GetType().InternalType()) { case PhysicalType::UINT8: { @@ -229812,7 +243367,7 @@ namespace duckdb { ListColumnData::ListColumnData(BlockManager &block_manager, DataTableInfo &info, idx_t column_index, idx_t start_row, LogicalType type_p, ColumnData *parent) - : ColumnData(block_manager, info, column_index, start_row, move(type_p), parent), + : ColumnData(block_manager, info, column_index, start_row, std::move(type_p), parent), validity(block_manager, info, 0, start_row, this) { D_ASSERT(type.InternalType() == PhysicalType::LIST); auto &child_type = ListType::GetChildType(type); @@ -229837,12 +243392,12 @@ void ListColumnData::InitializeScan(ColumnScanState &state) { // initialize the validity segment ColumnScanState validity_state; validity.InitializeScan(validity_state); - state.child_states.push_back(move(validity_state)); + state.child_states.push_back(std::move(validity_state)); // initialize the child scan ColumnScanState child_state; child_column->InitializeScan(child_state); - state.child_states.push_back(move(child_state)); + state.child_states.push_back(std::move(child_state)); } list_entry_t ListColumnData::FetchListEntry(idx_t row_idx) { @@ -229866,7 +243421,7 @@ void ListColumnData::InitializeScanWithOffset(ColumnScanState &state, idx_t row_ // initialize the validity segment ColumnScanState validity_state; validity.InitializeScanWithOffset(validity_state, row_idx); - state.child_states.push_back(move(validity_state)); + state.child_states.push_back(std::move(validity_state)); // we need to read the list at position row_idx to get the correct row offset of the child auto list_entry = FetchListEntry(row_idx); @@ -229877,7 +243432,7 @@ void ListColumnData::InitializeScanWithOffset(ColumnScanState &state, idx_t row_ if (child_offset < child_column->GetMaxEntry()) { child_column->InitializeScanWithOffset(child_state, start + child_offset); } - state.child_states.push_back(move(child_state)); + state.child_states.push_back(std::move(child_state)); } idx_t ListColumnData::Scan(TransactionData transaction, idx_t vector_index, ColumnScanState &state, Vector &result) { @@ -229961,12 +243516,12 @@ void ListColumnData::InitializeAppend(ColumnAppendState &state) { // initialize the validity append ColumnAppendState validity_append_state; validity.InitializeAppend(validity_append_state); - state.child_appends.push_back(move(validity_append_state)); + state.child_appends.push_back(std::move(validity_append_state)); // initialize the child column append ColumnAppendState child_append_state; child_column->InitializeAppend(child_append_state); - state.child_appends.push_back(move(child_append_state)); + state.child_appends.push_back(std::move(child_append_state)); } void ListColumnData::Append(BaseStatistics &stats_p, ColumnAppendState &state, Vector &vector, idx_t count) { @@ -230085,7 +243640,7 @@ void ListColumnData::FetchRow(TransactionData transaction, ColumnFetchState &sta // this is because we will (potentially) fetch more than one tuple from the list child if (state.child_states.empty()) { auto child_state = make_unique(); - state.child_states.push_back(move(child_state)); + state.child_states.push_back(std::move(child_state)); } // fetch the list_entry_t and the validity mask for that list auto segment = (ColumnSegment *)data.GetSegment(row_id); @@ -230170,8 +243725,8 @@ unique_ptr ListColumnData::Checkpoint(RowGroup &row_group auto child_state = child_column->Checkpoint(row_group, partial_block_manager, checkpoint_info); auto &checkpoint_state = (ListColumnCheckpointState &)*base_state; - checkpoint_state.validity_state = move(validity_state); - checkpoint_state.child_state = move(child_state); + checkpoint_state.validity_state = std::move(validity_state); + checkpoint_state.child_state = std::move(child_state); return base_state; } @@ -230181,7 +243736,7 @@ void ListColumnData::DeserializeColumn(Deserializer &source) { child_column->DeserializeColumn(source); } -void ListColumnData::GetStorageInfo(idx_t row_group_index, vector col_path, vector> &result) { +void ListColumnData::GetStorageInfo(idx_t row_group_index, vector col_path, TableStorageInfo &result) { col_path.push_back(0); validity.GetStorageInfo(row_group_index, col_path, result); col_path.back() = 1; @@ -230217,19 +243772,21 @@ PersistentTableData::~PersistentTableData() { + + namespace duckdb { constexpr const idx_t RowGroup::ROW_GROUP_VECTOR_COUNT; constexpr const idx_t RowGroup::ROW_GROUP_SIZE; -RowGroup::RowGroup(DatabaseInstance &db, BlockManager &block_manager, DataTableInfo &table_info, idx_t start, +RowGroup::RowGroup(AttachedDatabase &db, BlockManager &block_manager, DataTableInfo &table_info, idx_t start, idx_t count) : SegmentBase(start, count), db(db), block_manager(block_manager), table_info(table_info) { Verify(); } -RowGroup::RowGroup(DatabaseInstance &db, BlockManager &block_manager, DataTableInfo &table_info, +RowGroup::RowGroup(AttachedDatabase &db, BlockManager &block_manager, DataTableInfo &table_info, const vector &types, RowGroupPointer &&pointer) : SegmentBase(pointer.row_start, pointer.tuple_count), db(db), block_manager(block_manager), table_info(table_info) { @@ -230248,16 +243805,17 @@ RowGroup::RowGroup(DatabaseInstance &db, BlockManager &block_manager, DataTableI // set up the statistics for (auto &stats : pointer.statistics) { auto stats_type = stats->type; - this->stats.push_back(make_shared(stats_type, move(stats))); + this->stats.push_back(make_shared(stats_type, std::move(stats))); } - this->version_info = move(pointer.versions); + this->version_info = std::move(pointer.versions); Verify(); } RowGroup::RowGroup(RowGroup &row_group, idx_t start) : SegmentBase(start, row_group.count), db(row_group.db), block_manager(row_group.block_manager), - table_info(row_group.table_info), version_info(move(row_group.version_info)), stats(move(row_group.stats)) { + table_info(row_group.table_info), version_info(std::move(row_group.version_info)), + stats(std::move(row_group.stats)) { for (auto &column : row_group.columns) { this->columns.push_back(ColumnData::CreateColumn(*column, start)); } @@ -230280,12 +243838,16 @@ void VersionNode::SetStart(idx_t start) { RowGroup::~RowGroup() { } +DatabaseInstance &RowGroup::GetDatabase() { + return db.GetDatabase(); +} + void RowGroup::InitializeEmpty(const vector &types) { // set up the segment trees for the column segments for (idx_t i = 0; i < types.size(); i++) { auto column_data = ColumnData::CreateColumn(block_manager, GetTableInfo(), i, start, types[i]); stats.push_back(make_shared(types[i])); - columns.push_back(move(column_data)); + columns.push_back(std::move(column_data)); } } @@ -230373,8 +243935,8 @@ unique_ptr RowGroup::AlterType(const LogicalType &target_type, idx_t c for (idx_t i = 0; i < columns.size(); i++) { if (i == changed_idx) { // this is the altered column: use the new column - row_group->columns.push_back(move(column_data)); - row_group->stats.push_back(move(altered_col_stats)); + row_group->columns.push_back(std::move(column_data)); + row_group->stats.push_back(std::move(altered_col_stats)); } else { // this column was not altered: use the data directly row_group->columns.push_back(columns[i]); @@ -230417,8 +243979,8 @@ unique_ptr RowGroup::AddColumn(ColumnDefinition &new_column, Expressio row_group->columns = columns; row_group->stats = stats; // now add the new column - row_group->columns.push_back(move(added_column)); - row_group->stats.push_back(move(added_col_stats)); + row_group->columns.push_back(std::move(added_column)); + row_group->stats.push_back(std::move(added_col_stats)); row_group->Verify(); return row_group; @@ -230657,7 +244219,8 @@ void RowGroup::Scan(TransactionData transaction, RowGroupScanState &state, DataC } void RowGroup::ScanCommitted(RowGroupScanState &state, DataChunk &result, TableScanType type) { - auto &transaction_manager = TransactionManager::Get(db); + auto &transaction_manager = DuckTransactionManager::Get(db); + auto lowest_active_start = transaction_manager.LowestActiveStart(); auto lowest_active_id = transaction_manager.LowestActiveId(); TransactionData data(lowest_active_id, lowest_active_start); @@ -230757,7 +244320,7 @@ void RowGroup::AppendVersionInfo(TransactionData transaction, idx_t count) { auto constant_info = make_unique(this->start + vector_idx * STANDARD_VECTOR_SIZE); constant_info->insert_id = transaction.transaction_id; constant_info->delete_id = NOT_DELETED_ID; - version_info->info[vector_idx] = move(constant_info); + version_info->info[vector_idx] = std::move(constant_info); } else { // part of a vector is encapsulated: append to that part ChunkVectorInfo *info; @@ -230765,7 +244328,7 @@ void RowGroup::AppendVersionInfo(TransactionData transaction, idx_t count) { // first time appending to this vector: create new info auto insert_info = make_unique(this->start + vector_idx * STANDARD_VECTOR_SIZE); info = insert_info.get(); - version_info->info[vector_idx] = move(insert_info); + version_info->info[vector_idx] = std::move(insert_info); } else { D_ASSERT(version_info->info[vector_idx]->type == ChunkInfoType::VECTOR_INFO); // use existing vector @@ -230906,8 +244469,8 @@ RowGroupWriteData RowGroup::WriteToDisk(PartialBlockManager &manager, auto stats = checkpoint_state->GetStatistics(); D_ASSERT(stats); - result.statistics.push_back(move(stats)); - result.states.push_back(move(checkpoint_state)); + result.statistics.push_back(std::move(stats)); + result.states.push_back(std::move(checkpoint_state)); } D_ASSERT(result.states.size() == result.statistics.size()); return result; @@ -230925,7 +244488,7 @@ RowGroupPointer RowGroup::Checkpoint(RowGroupWriter &writer, vectorMerge(*result.statistics[column_idx]); } - row_group_pointer.statistics = move(result.statistics); + row_group_pointer.statistics = std::move(result.statistics); // construct the row group pointer and write the column meta data to disk D_ASSERT(result.states.size() == columns.size()); @@ -231024,7 +244587,7 @@ RowGroupPointer RowGroup::Deserialize(Deserializer &main_source, const ColumnLis auto &source = reader.GetSource(); for (auto &col : columns.Physical()) { auto stats = BaseStatistics::Deserialize(source, col.Type()); - result.statistics.push_back(move(stats)); + result.statistics.push_back(std::move(stats)); } for (idx_t i = 0; i < columns.PhysicalColumnCount(); i++) { BlockPointer pointer; @@ -231041,7 +244604,7 @@ RowGroupPointer RowGroup::Deserialize(Deserializer &main_source, const ColumnLis //===--------------------------------------------------------------------===// // GetStorageInfo //===--------------------------------------------------------------------===// -void RowGroup::GetStorageInfo(idx_t row_group_index, vector> &result) { +void RowGroup::GetStorageInfo(idx_t row_group_index, TableStorageInfo &result) { for (idx_t col_idx = 0; col_idx < columns.size(); col_idx++) { columns[col_idx]->GetStorageInfo(row_group_index, {col_idx}, result); } @@ -231118,7 +244681,7 @@ void VersionDeleteState::Delete(row_t row_id) { for (idx_t i = 0; i < STANDARD_VECTOR_SIZE; i++) { new_info->inserted[i] = constant.insert_id.load(); } - info.version_info->info[vector_idx] = move(new_info); + info.version_info->info[vector_idx] = std::move(new_info); } D_ASSERT(info.version_info->info[vector_idx]->type == ChunkInfoType::VECTOR_INFO); current_info = (ChunkVectorInfo *)info.version_info->info[vector_idx].get(); @@ -231158,7 +244721,7 @@ namespace duckdb { RowGroupCollection::RowGroupCollection(shared_ptr info_p, BlockManager &block_manager, vector types_p, idx_t row_start_p, idx_t total_rows_p) - : block_manager(block_manager), total_rows(total_rows_p), info(move(info_p)), types(move(types_p)), + : block_manager(block_manager), total_rows(total_rows_p), info(std::move(info_p)), types(std::move(types_p)), row_start(row_start_p) { row_groups = make_shared(); } @@ -231182,12 +244745,12 @@ void RowGroupCollection::Initialize(PersistentTableData &data) { D_ASSERT(this->row_start == 0); auto l = row_groups->Lock(); for (auto &row_group_pointer : data.row_groups) { - auto new_row_group = make_unique(info->db, block_manager, *info, types, move(row_group_pointer)); + auto new_row_group = make_unique(info->db, block_manager, *info, types, std::move(row_group_pointer)); auto row_group_count = new_row_group->start + new_row_group->count; if (row_group_count > this->total_rows) { this->total_rows = row_group_count; } - row_groups->AppendSegment(l, move(new_row_group)); + row_groups->AppendSegment(l, std::move(new_row_group)); } stats.Initialize(types, data); } @@ -231200,7 +244763,7 @@ void RowGroupCollection::AppendRowGroup(SegmentLock &l, idx_t start_row) { D_ASSERT(start_row >= row_start); auto new_row_group = make_unique(info->db, block_manager, *info, start_row, 0); new_row_group->InitializeEmpty(types); - row_groups->AppendSegment(l, move(new_row_group)); + row_groups->AppendSegment(l, std::move(new_row_group)); } RowGroup *RowGroupCollection::GetRowGroup(int64_t index) { @@ -231298,7 +244861,7 @@ bool RowGroupCollection::NextParallelScan(ClientContext &context, ParallelCollec return false; } -bool RowGroupCollection::Scan(Transaction &transaction, const vector &column_ids, +bool RowGroupCollection::Scan(DuckTransaction &transaction, const vector &column_ids, const std::function &fun) { vector scan_types; for (idx_t i = 0; i < column_ids.size(); i++) { @@ -231324,7 +244887,7 @@ bool RowGroupCollection::Scan(Transaction &transaction, const vector & } } -bool RowGroupCollection::Scan(Transaction &transaction, const std::function &fun) { +bool RowGroupCollection::Scan(DuckTransaction &transaction, const std::function &fun) { vector column_ids; column_ids.reserve(types.size()); for (idx_t i = 0; i < types.size(); i++) { @@ -231337,7 +244900,7 @@ bool RowGroupCollection::Scan(Transaction &transaction, const std::function &column_ids, - Vector &row_identifiers, idx_t fetch_count, ColumnFetchState &state) { + const Vector &row_identifiers, idx_t fetch_count, ColumnFetchState &state) { // figure out which row_group to fetch from auto row_ids = FlatVector::GetData(row_identifiers); idx_t count = 0; @@ -231538,7 +245101,7 @@ void RowGroupCollection::MergeStorage(RowGroupCollection &data) { auto &row_group = (RowGroup &)*segment; auto new_group = make_unique(row_group, index); index += new_group->count; - row_groups->AppendSegment(move(new_group)); + row_groups->AppendSegment(std::move(new_group)); } stats.MergeStats(data.stats); total_rows += data.total_rows.load(); @@ -231556,7 +245119,7 @@ idx_t RowGroupCollection::Delete(TransactionData transaction, DataTable *table, idx_t pos = 0; do { idx_t start = pos; - auto row_group = (RowGroup *)row_groups->GetSegment(ids[pos]); + auto row_group = (RowGroup *)row_groups->GetSegment(ids[start]); for (pos++; pos < count; pos++) { D_ASSERT(ids[pos] >= 0); // check if this id still belongs to this row group @@ -231634,7 +245197,7 @@ void RowGroupCollection::RemoveFromIndexes(TableIndexList &indexes, Vector &row_ for (idx_t i = 0; i < types.size(); i++) { column_ids.push_back(i); } - state.Initialize(move(column_ids)); + state.Initialize(std::move(column_ids)); DataChunk result; result.Initialize(GetAllocator(), types); @@ -231671,7 +245234,7 @@ void RowGroupCollection::Checkpoint(TableDataWriter &writer, vectorNext()) { auto rowg_writer = writer.GetRowGroupWriter(*row_group); auto pointer = row_group->Checkpoint(*rowg_writer, global_stats); - writer.AddRowGroup(move(pointer), move(rowg_writer)); + writer.AddRowGroup(std::move(pointer), std::move(rowg_writer)); } } @@ -231697,9 +245260,7 @@ void RowGroupCollection::CommitDropTable() { //===--------------------------------------------------------------------===// // GetStorageInfo //===--------------------------------------------------------------------===// -vector> RowGroupCollection::GetStorageInfo() { - vector> result; - +void RowGroupCollection::GetStorageInfo(TableStorageInfo &result) { auto row_group = (RowGroup *)row_groups->GetRootSegment(); idx_t row_group_index = 0; while (row_group) { @@ -231708,8 +245269,6 @@ vector> RowGroupCollection::GetStorageInfo() { row_group = (RowGroup *)row_group->Next(); } - - return result; } //===--------------------------------------------------------------------===// @@ -231720,7 +245279,8 @@ shared_ptr RowGroupCollection::AddColumn(ClientContext &cont idx_t new_column_idx = types.size(); auto new_types = types; new_types.push_back(new_column.GetType()); - auto result = make_shared(info, block_manager, move(new_types), row_start, total_rows.load()); + auto result = + make_shared(info, block_manager, std::move(new_types), row_start, total_rows.load()); ExpressionExecutor executor(context); DataChunk dummy_chunk; @@ -231742,7 +245302,7 @@ shared_ptr RowGroupCollection::AddColumn(ClientContext &cont // merge in the statistics new_row_group->MergeIntoStatistics(new_column_idx, *new_column_stats.stats); - result->row_groups->AppendSegment(move(new_row_group)); + result->row_groups->AppendSegment(std::move(new_row_group)); current_row_group = (RowGroup *)current_row_group->Next(); } return result; @@ -231753,13 +245313,14 @@ shared_ptr RowGroupCollection::RemoveColumn(idx_t col_idx) { auto new_types = types; new_types.erase(new_types.begin() + col_idx); - auto result = make_shared(info, block_manager, move(new_types), row_start, total_rows.load()); + auto result = + make_shared(info, block_manager, std::move(new_types), row_start, total_rows.load()); result->stats.InitializeRemoveColumn(stats, col_idx); auto current_row_group = (RowGroup *)row_groups->GetRootSegment(); while (current_row_group) { auto new_row_group = current_row_group->RemoveColumn(col_idx); - result->row_groups->AppendSegment(move(new_row_group)); + result->row_groups->AppendSegment(std::move(new_row_group)); current_row_group = (RowGroup *)current_row_group->Next(); } return result; @@ -231772,7 +245333,8 @@ shared_ptr RowGroupCollection::AlterType(ClientContext &cont auto new_types = types; new_types[changed_idx] = target_type; - auto result = make_shared(info, block_manager, move(new_types), row_start, total_rows.load()); + auto result = + make_shared(info, block_manager, std::move(new_types), row_start, total_rows.load()); result->stats.InitializeAlterType(stats, changed_idx, target_type); vector scan_types; @@ -231800,7 +245362,7 @@ shared_ptr RowGroupCollection::AlterType(ClientContext &cont auto new_row_group = current_row_group->AlterType(target_type, changed_idx, executor, scan_state.table_state.row_group_state, scan_chunk); new_row_group->MergeIntoStatistics(changed_idx, *changed_stats.stats); - result->row_groups->AppendSegment(move(new_row_group)); + result->row_groups->AppendSegment(std::move(new_row_group)); current_row_group = (RowGroup *)current_row_group->Next(); } @@ -231863,7 +245425,7 @@ void RowGroupCollection::SetStatistics(column_t column_id, const std::function column_ids, TableFilterSet *table_filters) { - this->column_ids = move(column_ids); + this->column_ids = std::move(column_ids); this->table_filters = table_filters; if (table_filters) { D_ASSERT(table_filters->filters.size() > 0); @@ -231941,7 +245503,7 @@ AdaptiveFilter *CollectionScanState::GetAdaptiveFilter() { return parent.GetAdaptiveFilter(); } -bool CollectionScanState::Scan(Transaction &transaction, DataChunk &result) { +bool CollectionScanState::Scan(DuckTransaction &transaction, DataChunk &result) { auto current_row_group = row_group_state.row_group; while (current_row_group) { current_row_group->Scan(transaction, row_group_state, result); @@ -231999,7 +245561,7 @@ SegmentBase *SegmentTree::GetRootSegment(SegmentLock &l) { } vector SegmentTree::MoveSegments(SegmentLock &) { - return move(nodes); + return std::move(nodes); } SegmentBase *SegmentTree::GetRootSegment() { @@ -232115,13 +245677,13 @@ void SegmentTree::AppendSegment(SegmentLock &, unique_ptr segment) } SegmentNode node; node.row_start = segment->start; - node.node = move(segment); - nodes.push_back(move(node)); + node.node = std::move(segment); + nodes.push_back(std::move(node)); } void SegmentTree::AppendSegment(unique_ptr segment) { auto l = Lock(); - AppendSegment(l, move(segment)); + AppendSegment(l, std::move(segment)); } void SegmentTree::EraseSegments(SegmentLock &, idx_t segment_start) { @@ -232132,7 +245694,7 @@ void SegmentTree::EraseSegments(SegmentLock &, idx_t segment_start) { } void SegmentTree::Replace(SegmentLock &, SegmentTree &other) { - nodes = move(other.nodes); + nodes = std::move(other.nodes); } void SegmentTree::Replace(SegmentTree &other) { @@ -232171,7 +245733,7 @@ namespace duckdb { StandardColumnData::StandardColumnData(BlockManager &block_manager, DataTableInfo &info, idx_t column_index, idx_t start_row, LogicalType type, ColumnData *parent) - : ColumnData(block_manager, info, column_index, start_row, move(type), parent), + : ColumnData(block_manager, info, column_index, start_row, std::move(type), parent), validity(block_manager, info, 0, start_row, this) { } @@ -232207,7 +245769,7 @@ void StandardColumnData::InitializeScan(ColumnScanState &state) { // initialize the validity segment ColumnScanState child_state; validity.InitializeScan(child_state); - state.child_states.push_back(move(child_state)); + state.child_states.push_back(std::move(child_state)); } void StandardColumnData::InitializeScanWithOffset(ColumnScanState &state, idx_t row_idx) { @@ -232216,7 +245778,7 @@ void StandardColumnData::InitializeScanWithOffset(ColumnScanState &state, idx_t // initialize the validity segment ColumnScanState child_state; validity.InitializeScanWithOffset(child_state, row_idx); - state.child_states.push_back(move(child_state)); + state.child_states.push_back(std::move(child_state)); } idx_t StandardColumnData::Scan(TransactionData transaction, idx_t vector_index, ColumnScanState &state, @@ -232246,7 +245808,7 @@ void StandardColumnData::InitializeAppend(ColumnAppendState &state) { ColumnAppendState child_append; validity.InitializeAppend(child_append); - state.child_appends.push_back(move(child_append)); + state.child_appends.push_back(std::move(child_append)); } void StandardColumnData::AppendData(BaseStatistics &stats, ColumnAppendState &state, UnifiedVectorFormat &vdata, @@ -232266,7 +245828,7 @@ idx_t StandardColumnData::Fetch(ColumnScanState &state, row_t row_id, Vector &re // fetch validity mask if (state.child_states.empty()) { ColumnScanState child_state; - state.child_states.push_back(move(child_state)); + state.child_states.push_back(std::move(child_state)); } auto scan_count = ColumnData::Fetch(state, row_id, result); validity.Fetch(state.child_states[0], row_id, result); @@ -232299,7 +245861,7 @@ unique_ptr StandardColumnData::GetUpdateStatistics() { if (!stats) { stats = BaseStatistics::CreateEmpty(type, StatisticsType::GLOBAL_STATS); } - stats->validity_stats = move(validity_stats); + stats->validity_stats = std::move(validity_stats); return stats; } @@ -232308,7 +245870,7 @@ void StandardColumnData::FetchRow(TransactionData transaction, ColumnFetchState // find the segment the row belongs to if (state.child_states.empty()) { auto child_state = make_unique(); - state.child_states.push_back(move(child_state)); + state.child_states.push_back(std::move(child_state)); } validity.FetchRow(transaction, *state.child_states[0], row_id, result, result_idx); ColumnData::FetchRow(transaction, state, row_id, result, result_idx); @@ -232331,7 +245893,7 @@ struct StandardColumnCheckpointState : public ColumnCheckpointState { unique_ptr GetStatistics() override { D_ASSERT(global_stats); global_stats->validity_stats = validity_state->GetStatistics(); - return move(global_stats); + return std::move(global_stats); } void WriteDataPointers(RowGroupWriter &writer) override { @@ -232356,7 +245918,7 @@ unique_ptr StandardColumnData::Checkpoint(RowGroup &row_g auto validity_state = validity.Checkpoint(row_group, partial_block_manager, checkpoint_info); auto base_state = ColumnData::Checkpoint(row_group, partial_block_manager, checkpoint_info); auto &checkpoint_state = (StandardColumnCheckpointState &)*base_state; - checkpoint_state.validity_state = move(validity_state); + checkpoint_state.validity_state = std::move(validity_state); return base_state; } @@ -232373,10 +245935,10 @@ void StandardColumnData::DeserializeColumn(Deserializer &source) { validity.DeserializeColumn(source); } -void StandardColumnData::GetStorageInfo(idx_t row_group_index, vector col_path, vector> &result) { +void StandardColumnData::GetStorageInfo(idx_t row_group_index, vector col_path, TableStorageInfo &result) { ColumnData::GetStorageInfo(row_group_index, col_path, result); col_path.push_back(0); - validity.GetStorageInfo(row_group_index, move(col_path), result); + validity.GetStorageInfo(row_group_index, std::move(col_path), result); } void StandardColumnData::Verify(RowGroup &parent) { @@ -232395,7 +245957,7 @@ namespace duckdb { StructColumnData::StructColumnData(BlockManager &block_manager, DataTableInfo &info, idx_t column_index, idx_t start_row, LogicalType type_p, ColumnData *parent) - : ColumnData(block_manager, info, column_index, start_row, move(type_p), parent), + : ColumnData(block_manager, info, column_index, start_row, std::move(type_p), parent), validity(block_manager, info, 0, start_row, this) { D_ASSERT(type.InternalType() == PhysicalType::STRUCT); auto &child_types = StructType::GetChildTypes(type); @@ -232435,13 +245997,13 @@ void StructColumnData::InitializeScan(ColumnScanState &state) { // initialize the validity segment ColumnScanState validity_state; validity.InitializeScan(validity_state); - state.child_states.push_back(move(validity_state)); + state.child_states.push_back(std::move(validity_state)); // initialize the sub-columns for (auto &sub_column : sub_columns) { ColumnScanState child_state; sub_column->InitializeScan(child_state); - state.child_states.push_back(move(child_state)); + state.child_states.push_back(std::move(child_state)); } } @@ -232454,13 +246016,13 @@ void StructColumnData::InitializeScanWithOffset(ColumnScanState &state, idx_t ro // initialize the validity segment ColumnScanState validity_state; validity.InitializeScanWithOffset(validity_state, row_idx); - state.child_states.push_back(move(validity_state)); + state.child_states.push_back(std::move(validity_state)); // initialize the sub-columns for (auto &sub_column : sub_columns) { ColumnScanState child_state; sub_column->InitializeScanWithOffset(child_state, row_idx); - state.child_states.push_back(move(child_state)); + state.child_states.push_back(std::move(child_state)); } } @@ -232503,12 +246065,12 @@ void StructColumnData::Skip(ColumnScanState &state, idx_t count) { void StructColumnData::InitializeAppend(ColumnAppendState &state) { ColumnAppendState validity_append; validity.InitializeAppend(validity_append); - state.child_appends.push_back(move(validity_append)); + state.child_appends.push_back(std::move(validity_append)); for (auto &sub_column : sub_columns) { ColumnAppendState child_append; sub_column->InitializeAppend(child_append); - state.child_appends.push_back(move(child_append)); + state.child_appends.push_back(std::move(child_append)); } } @@ -232518,19 +246080,9 @@ void StructColumnData::Append(BaseStatistics &stats, ColumnAppendState &state, V // append the null values validity.Append(*stats.validity_stats, state.child_appends[0], vector, count); - auto &struct_validity = FlatVector::Validity(vector); - auto &struct_stats = (StructStatistics &)stats; auto &child_entries = StructVector::GetEntries(vector); for (idx_t i = 0; i < child_entries.size(); i++) { - if (!struct_validity.AllValid()) { - // we set the child entries of the struct to NULL - // for any values in which the struct itself is NULL - child_entries[i]->Flatten(count); - - auto &child_validity = FlatVector::Validity(*child_entries[i]); - child_validity.Combine(struct_validity, count); - } sub_columns[i]->Append(*struct_stats.child_stats[i], state.child_appends[i + 1], *child_entries[i], count); } } @@ -232548,7 +246100,7 @@ idx_t StructColumnData::Fetch(ColumnScanState &state, row_t row_id, Vector &resu // insert any child states that are required for (idx_t i = state.child_states.size(); i < child_entries.size() + 1; i++) { ColumnScanState child_state; - state.child_states.push_back(move(child_state)); + state.child_states.push_back(std::move(child_state)); } // fetch the validity state idx_t scan_count = validity.Fetch(state.child_states[0], row_id, result); @@ -232595,7 +246147,7 @@ unique_ptr StructColumnData::GetUpdateStatistics() { for (idx_t i = 0; i < sub_columns.size(); i++) { auto child_stats = sub_columns[i]->GetUpdateStatistics(); if (child_stats) { - struct_stats.child_stats[i] = move(child_stats); + struct_stats.child_stats[i] = std::move(child_stats); } } return stats; @@ -232608,7 +246160,7 @@ void StructColumnData::FetchRow(TransactionData transaction, ColumnFetchState &s // insert any child states that are required for (idx_t i = state.child_states.size(); i < child_entries.size() + 1; i++) { auto child_state = make_unique(); - state.child_states.push_back(move(child_state)); + state.child_states.push_back(std::move(child_state)); } // fetch the validity state validity.FetchRow(transaction, *state.child_states[0], row_id, result, result_idx); @@ -232644,7 +246196,7 @@ struct StructColumnCheckpointState : public ColumnCheckpointState { stats->child_stats[i] = child_states[i]->GetStatistics(); D_ASSERT(stats->child_stats[i]); } - return move(stats); + return std::move(stats); } void WriteDataPointers(RowGroupWriter &writer) override { @@ -232675,7 +246227,7 @@ unique_ptr StructColumnData::Checkpoint(RowGroup &row_gro checkpoint_state->child_states.push_back( sub_column->Checkpoint(row_group, partial_block_manager, checkpoint_info)); } - return move(checkpoint_state); + return std::move(checkpoint_state); } void StructColumnData::DeserializeColumn(Deserializer &source) { @@ -232685,7 +246237,7 @@ void StructColumnData::DeserializeColumn(Deserializer &source) { } } -void StructColumnData::GetStorageInfo(idx_t row_group_index, vector col_path, vector> &result) { +void StructColumnData::GetStorageInfo(idx_t row_group_index, vector col_path, TableStorageInfo &result) { col_path.push_back(0); validity.GetStorageInfo(row_group_index, col_path, result); for (idx_t i = 0; i < sub_columns.size(); i++) { @@ -232715,7 +246267,7 @@ void TableStatistics::Initialize(const vector &types, PersistentTab column_stats.reserve(data.column_stats.size()); for (auto &stats : data.column_stats) { - column_stats.push_back(make_shared(move(stats))); + column_stats.push_back(make_shared(std::move(stats))); } if (column_stats.size() != types.size()) { // LCOV_EXCL_START throw IOException("Table statistics column count is not aligned with table column count. Corrupt file?"); @@ -233489,7 +247041,7 @@ struct UpdateSelectElement { template <> string_t UpdateSelectElement::Operation(UpdateSegment *segment, string_t element) { - return element.IsInlined() ? element : segment->GetStringHeap().AddString(element); + return element.IsInlined() ? element : segment->GetStringHeap().AddBlob(element); } template @@ -233815,7 +247367,7 @@ idx_t UpdateStringStatistics(UpdateSegment *segment, SegmentStatistics &stats, V for (idx_t i = 0; i < count; i++) { ((StringStatistics &)*stats.statistics).Update(update_data[i]); if (!update_data[i].IsInlined()) { - update_data[i] = segment->GetStringHeap().AddString(update_data[i]); + update_data[i] = segment->GetStringHeap().AddBlob(update_data[i]); } } sel.Initialize(nullptr); @@ -233828,7 +247380,7 @@ idx_t UpdateStringStatistics(UpdateSegment *segment, SegmentStatistics &stats, V sel.set_index(not_null_count++, i); ((StringStatistics &)*stats.statistics).Update(update_data[i]); if (!update_data[i].IsInlined()) { - update_data[i] = segment->GetStringHeap().AddString(update_data[i]); + update_data[i] = segment->GetStringHeap().AddBlob(update_data[i]); } } } @@ -233991,7 +247543,8 @@ void UpdateSegment::Update(TransactionData transaction, idx_t column_index, Vect if (!node) { // no updates made yet by this transaction: initially the update info to empty if (transaction.transaction) { - node = transaction.transaction->CreateUpdateInfo(type_size, count); + auto &dtransaction = (DuckTransaction &)*transaction.transaction; + node = dtransaction.CreateUpdateInfo(type_size, count); } else { node = CreateEmptyUpdateInfo(transaction, type_size, count, update_info_data); } @@ -234052,7 +247605,7 @@ void UpdateSegment::Update(TransactionData transaction, idx_t column_index, Vect transaction_node->Verify(); result->info->Verify(); - root->info[vector_index] = move(result); + root->info[vector_index] = std::move(result); } } @@ -234118,11 +247671,13 @@ bool ValidityColumnData::CheckZonemap(ColumnScanState &state, TableFilter &filte + + namespace duckdb { void TableIndexList::AddIndex(unique_ptr index) { D_ASSERT(index); lock_guard lock(indexes_lock); - indexes.push_back(move(index)); + indexes.push_back(std::move(index)); } void TableIndexList::RemoveIndex(Index *index) { D_ASSERT(index); @@ -234149,7 +247704,7 @@ idx_t TableIndexList::Count() { void TableIndexList::Move(TableIndexList &other) { D_ASSERT(indexes.empty()); - indexes = move(other.indexes); + indexes = std::move(other.indexes); } Index *TableIndexList::FindForeignKeyIndex(const vector &fk_keys, ForeignKeyType fk_type) { @@ -234163,20 +247718,20 @@ Index *TableIndexList::FindForeignKeyIndex(const vector &fk_keys, return result; } -void TableIndexList::VerifyForeignKey(const vector &fk_keys, bool is_append, DataChunk &chunk, - vector &err_msgs) { - auto fk_type = is_append ? ForeignKeyType::FK_TYPE_PRIMARY_KEY_TABLE : ForeignKeyType::FK_TYPE_FOREIGN_KEY_TABLE; +void TableIndexList::VerifyForeignKey(const vector &fk_keys, DataChunk &chunk, + ConflictManager &conflict_manager) { + auto fk_type = conflict_manager.LookupType() == VerifyExistenceType::APPEND_FK + ? ForeignKeyType::FK_TYPE_PRIMARY_KEY_TABLE + : ForeignKeyType::FK_TYPE_FOREIGN_KEY_TABLE; // check whether or not the chunk can be inserted or deleted into the referenced table' storage auto index = FindForeignKeyIndex(fk_keys, fk_type); if (!index) { throw InternalException("Internal Foreign Key error: could not find index to verify..."); } - if (is_append) { - index->VerifyAppendForeignKey(chunk, err_msgs.data()); - } else { - index->VerifyDeleteForeignKey(chunk, err_msgs.data()); - } + conflict_manager.SetIndexCount(1); + + index->LookupValues(chunk, conflict_manager); } vector TableIndexList::GetRequiredColumns() { @@ -234223,16 +247778,17 @@ vector TableIndexList::SerializeIndexes(duckdb::MetaBlockWriter &w + namespace duckdb { -bool WriteAheadLog::Replay(DatabaseInstance &database, string &path) { - auto initial_reader = make_unique(database.GetFileSystem(), path.c_str()); +bool WriteAheadLog::Replay(AttachedDatabase &database, string &path) { + auto initial_reader = make_unique(FileSystem::Get(database), path.c_str()); if (initial_reader->Finished()) { // WAL is empty return false; } - Connection con(database); + Connection con(database.GetDatabase()); con.BeginTransaction(); // first deserialize the WAL to look for a checkpoint flag @@ -234264,7 +247820,7 @@ bool WriteAheadLog::Replay(DatabaseInstance &database, string &path) { initial_reader.reset(); if (checkpoint_state.checkpoint_id != INVALID_BLOCK) { // there is a checkpoint flag: check if we need to deserialize the WAL - auto &manager = StorageManager::GetStorageManager(database); + auto &manager = database.GetStorageManager(); if (manager.IsCheckpointClean(checkpoint_state.checkpoint_id)) { // the contents of the WAL have already been checkpointed // we can safely truncate the WAL and ignore its contents @@ -234273,7 +247829,7 @@ bool WriteAheadLog::Replay(DatabaseInstance &database, string &path) { } // we need to recover from the WAL: actually set up the replay state - BufferedFileReader reader(database.GetFileSystem(), path.c_str()); + BufferedFileReader reader(FileSystem::Get(database), path.c_str()); ReplayState state(database, *con.context, reader); // replay the WAL @@ -234396,9 +247952,8 @@ void ReplayState::ReplayCreateTable() { // bind the constraints to the table again auto binder = Binder::CreateBinder(context); - auto bound_info = binder->BindCreateTableInfo(move(info)); + auto bound_info = binder->BindCreateTableInfo(std::move(info)); - auto &catalog = Catalog::GetCatalog(context); catalog.CreateTable(context, bound_info.get()); } @@ -234412,7 +247967,6 @@ void ReplayState::ReplayDropTable() { return; } - auto &catalog = Catalog::GetCatalog(context); catalog.DropEntry(context, &info); } @@ -234421,7 +247975,6 @@ void ReplayState::ReplayAlter() { if (deserialize_only) { return; } - auto &catalog = Catalog::GetCatalog(context); catalog.Alter(context, info.get()); } @@ -234434,7 +247987,6 @@ void ReplayState::ReplayCreateView() { return; } - auto &catalog = Catalog::GetCatalog(context); catalog.CreateView(context, entry.get()); } @@ -234446,7 +247998,6 @@ void ReplayState::ReplayDropView() { if (deserialize_only) { return; } - auto &catalog = Catalog::GetCatalog(context); catalog.DropEntry(context, &info); } @@ -234460,7 +248011,6 @@ void ReplayState::ReplayCreateSchema() { return; } - auto &catalog = Catalog::GetCatalog(context); catalog.CreateSchema(context, &info); } @@ -234473,7 +248023,6 @@ void ReplayState::ReplayDropSchema() { return; } - auto &catalog = Catalog::GetCatalog(context); catalog.DropEntry(context, &info); } @@ -234486,7 +248035,6 @@ void ReplayState::ReplayCreateType() { return; } - auto &catalog = Catalog::GetCatalog(context); catalog.CreateType(context, info.get()); } @@ -234500,7 +248048,6 @@ void ReplayState::ReplayDropType() { return; } - auto &catalog = Catalog::GetCatalog(context); catalog.DropEntry(context, &info); } @@ -234513,7 +248060,6 @@ void ReplayState::ReplayCreateSequence() { return; } - auto &catalog = Catalog::GetCatalog(context); catalog.CreateSequence(context, entry.get()); } @@ -234526,7 +248072,6 @@ void ReplayState::ReplayDropSequence() { return; } - auto &catalog = Catalog::GetCatalog(context); catalog.DropEntry(context, &info); } @@ -234540,7 +248085,6 @@ void ReplayState::ReplaySequenceValue() { } // fetch the sequence from the catalog - auto &catalog = Catalog::GetCatalog(context); auto seq = catalog.GetEntry(context, schema, name); if (usage_count > seq->usage_count) { seq->usage_count = usage_count; @@ -234557,7 +248101,6 @@ void ReplayState::ReplayCreateMacro() { return; } - auto &catalog = Catalog::GetCatalog(context); catalog.CreateFunction(context, entry.get()); } @@ -234570,7 +248113,6 @@ void ReplayState::ReplayDropMacro() { return; } - auto &catalog = Catalog::GetCatalog(context); catalog.DropEntry(context, &info); } @@ -234583,7 +248125,6 @@ void ReplayState::ReplayCreateTableMacro() { return; } - auto &catalog = Catalog::GetCatalog(context); catalog.CreateFunction(context, entry.get()); } @@ -234596,7 +248137,6 @@ void ReplayState::ReplayDropTableMacro() { return; } - auto &catalog = Catalog::GetCatalog(context); catalog.DropEntry(context, &info); } @@ -234609,7 +248149,6 @@ void ReplayState::ReplayUseTable() { if (deserialize_only) { return; } - auto &catalog = Catalog::GetCatalog(context); current_table = catalog.GetEntry(context, schema_name, table_name); } @@ -234624,7 +248163,7 @@ void ReplayState::ReplayInsert() { } // append to the current table - current_table->storage->LocalAppend(*current_table, context, chunk); + current_table->GetStorage().LocalAppend(*current_table, context, chunk); } void ReplayState::ReplayDelete() { @@ -234645,7 +248184,7 @@ void ReplayState::ReplayDelete() { // delete the tuples from the current table for (idx_t i = 0; i < chunk.size(); i++) { row_ids[0] = source_ids[i]; - current_table->storage->Delete(*current_table, context, row_identifiers, 1); + current_table->GetStorage().Delete(*current_table, context, row_identifiers, 1); } } @@ -234665,16 +248204,16 @@ void ReplayState::ReplayUpdate() { throw InternalException("Corrupt WAL: update without table"); } - if (column_path[0] >= current_table->columns.PhysicalColumnCount()) { + if (column_path[0] >= current_table->GetColumns().PhysicalColumnCount()) { throw InternalException("Corrupt WAL: column index for update out of bounds"); } // remove the row id vector from the chunk - auto row_ids = move(chunk.data.back()); + auto row_ids = std::move(chunk.data.back()); chunk.data.pop_back(); // now perform the update - current_table->storage->UpdateColumn(*current_table, context, row_ids, column_path, chunk); + current_table->GetStorage().UpdateColumn(*current_table, context, row_ids, column_path, chunk); } void ReplayState::ReplayCheckpoint() { @@ -234695,9 +248234,9 @@ void ReplayState::ReplayCheckpoint() { namespace duckdb { -WriteAheadLog::WriteAheadLog(DatabaseInstance &database, const string &path) : skip_writing(false), database(database) { +WriteAheadLog::WriteAheadLog(AttachedDatabase &database, const string &path) : skip_writing(false), database(database) { wal_path = path; - writer = make_unique(database.GetFileSystem(), path.c_str(), + writer = make_unique(FileSystem::Get(database), path.c_str(), FileFlags::FILE_FLAGS_WRITE | FileFlags::FILE_FLAGS_FILE_CREATE | FileFlags::FILE_FLAGS_APPEND); } @@ -234725,7 +248264,7 @@ void WriteAheadLog::Delete() { } writer.reset(); - auto &fs = FileSystem::GetFileSystem(database); + auto &fs = FileSystem::Get(database); fs.RemoveFile(wal_path); } @@ -235190,6 +248729,8 @@ class CommitState { + + //===----------------------------------------------------------------------===// // DuckDB // @@ -235241,7 +248782,8 @@ void CommitState::WriteCatalogEntry(CatalogEntry *entry, data_ptr_t dataptr) { switch (parent->type) { case CatalogType::TABLE_ENTRY: if (entry->type == CatalogType::TABLE_ENTRY) { - auto table_entry = (TableCatalogEntry *)entry; + auto table_entry = (DuckTableEntry *)entry; + D_ASSERT(table_entry->IsDuckTable()); // ALTER TABLE statement, read the extra data after the entry auto extra_data_size = Load(dataptr); auto extra_data = (data_ptr_t)(dataptr + sizeof(idx_t)); @@ -235293,7 +248835,8 @@ void CommitState::WriteCatalogEntry(CatalogEntry *entry, data_ptr_t dataptr) { case CatalogType::DELETED_ENTRY: switch (entry->type) { case CatalogType::TABLE_ENTRY: { - auto table_entry = (TableCatalogEntry *)entry; + auto table_entry = (DuckTableEntry *)entry; + D_ASSERT(table_entry->IsDuckTable()); table_entry->CommitDrop(); log->WriteDropTable(table_entry); break; @@ -235419,6 +248962,14 @@ void CommitState::CommitEntry(UndoFlags type, data_ptr_t data) { // set the commit timestamp of the catalog entry to the given id auto catalog_entry = Load(data); D_ASSERT(catalog_entry->parent); + + auto &catalog = catalog_entry->catalog; + D_ASSERT(catalog); + D_ASSERT(catalog->IsDuckCatalog()); + + // Grab a write lock on the catalog + auto &duck_catalog = (DuckCatalog &)*catalog; + lock_guard write_lock(duck_catalog.GetWriteLock()); catalog_entry->set->UpdateTimestamp(catalog_entry->parent, commit_id); if (catalog_entry->name != catalog_entry->parent->name) { catalog_entry->set->UpdateTimestamp(catalog_entry, commit_id); @@ -235505,80 +249056,6 @@ template void CommitState::CommitEntry(UndoFlags type, data_ptr_t data); template void CommitState::CommitEntry(UndoFlags type, data_ptr_t data); } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/transaction/rollback_state.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { -class DataChunk; -class DataTable; -class WriteAheadLog; - -class RollbackState { -public: - RollbackState() { - } - -public: - void RollbackEntry(UndoFlags type, data_ptr_t data); -}; - -} // namespace duckdb - - - - - - - - - - - - -namespace duckdb { - -void RollbackState::RollbackEntry(UndoFlags type, data_ptr_t data) { - switch (type) { - case UndoFlags::CATALOG_ENTRY: { - // undo this catalog entry - auto catalog_entry = Load(data); - D_ASSERT(catalog_entry->set); - catalog_entry->set->Undo(catalog_entry); - break; - } - case UndoFlags::INSERT_TUPLE: { - auto info = (AppendInfo *)data; - // revert the append in the base table - info->table->RevertAppend(info->start_row, info->count); - break; - } - case UndoFlags::DELETE_TUPLE: { - auto info = (DeleteInfo *)data; - // reset the deleted flag on rollback - info->vinfo->CommitDelete(NOT_DELETED_ID, info->rows, info->count); - break; - } - case UndoFlags::UPDATE_TUPLE: { - auto info = (UpdateInfo *)data; - info->segment->RollbackUpdate(info); - break; - } - default: // LCOV_EXCL_START - D_ASSERT(type == UndoFlags::EMPTY_ENTRY); - break; - } // LCOV_EXCL_STOP -} - -} // namespace duckdb @@ -235597,37 +249074,42 @@ void RollbackState::RollbackEntry(UndoFlags type, data_ptr_t data) { -#include namespace duckdb { -TransactionData::TransactionData(Transaction &transaction_p) // NOLINT +TransactionData::TransactionData(DuckTransaction &transaction_p) // NOLINT : transaction(&transaction_p), transaction_id(transaction_p.transaction_id), start_time(transaction_p.start_time) { } TransactionData::TransactionData(transaction_t transaction_id_p, transaction_t start_time_p) : transaction(nullptr), transaction_id(transaction_id_p), start_time(start_time_p) { } -Transaction::Transaction(ClientContext &context_p, transaction_t start_time, transaction_t transaction_id, - timestamp_t start_timestamp, idx_t catalog_version) - : context(context_p.shared_from_this()), start_time(start_time), transaction_id(transaction_id), commit_id(0), - highest_active_query(0), active_query(MAXIMUM_QUERY_ID), start_timestamp(start_timestamp), - catalog_version(catalog_version), temporary_objects(context_p.client_data->temporary_objects), - undo_buffer(context.lock()), storage(make_unique(context_p, *this)) { +DuckTransaction::DuckTransaction(TransactionManager &manager, ClientContext &context_p, transaction_t start_time, + transaction_t transaction_id) + : Transaction(manager, context_p), start_time(start_time), transaction_id(transaction_id), commit_id(0), + highest_active_query(0), undo_buffer(context_p), storage(make_unique(context_p, *this)) { } -Transaction::~Transaction() { +DuckTransaction::~DuckTransaction() { +} + +DuckTransaction &DuckTransaction::Get(ClientContext &context, AttachedDatabase &db) { + return DuckTransaction::Get(context, db.GetCatalog()); } -Transaction &Transaction::GetTransaction(ClientContext &context) { - return context.ActiveTransaction(); +DuckTransaction &DuckTransaction::Get(ClientContext &context, Catalog &catalog) { + auto &transaction = Transaction::Get(context, catalog); + if (!transaction.IsDuckTransaction()) { + throw InternalException("DuckTransaction::Get called on non-DuckDB transaction"); + } + return (DuckTransaction &)transaction; } -LocalStorage &Transaction::GetLocalStorage() { +LocalStorage &DuckTransaction::GetLocalStorage() { return *storage; } -void Transaction::PushCatalogEntry(CatalogEntry *entry, data_ptr_t extra_data, idx_t extra_data_size) { +void DuckTransaction::PushCatalogEntry(CatalogEntry *entry, data_ptr_t extra_data, idx_t extra_data_size) { idx_t alloc_size = sizeof(CatalogEntry *); if (extra_data_size > 0) { alloc_size += extra_data_size + sizeof(idx_t); @@ -235646,7 +249128,7 @@ void Transaction::PushCatalogEntry(CatalogEntry *entry, data_ptr_t extra_data, i } } -void Transaction::PushDelete(DataTable *table, ChunkVectorInfo *vinfo, row_t rows[], idx_t count, idx_t base_row) { +void DuckTransaction::PushDelete(DataTable *table, ChunkVectorInfo *vinfo, row_t rows[], idx_t count, idx_t base_row) { auto delete_info = (DeleteInfo *)undo_buffer.CreateEntry(UndoFlags::DELETE_TUPLE, sizeof(DeleteInfo) + sizeof(row_t) * count); delete_info->vinfo = vinfo; @@ -235656,14 +249138,14 @@ void Transaction::PushDelete(DataTable *table, ChunkVectorInfo *vinfo, row_t row memcpy(delete_info->rows, rows, sizeof(row_t) * count); } -void Transaction::PushAppend(DataTable *table, idx_t start_row, idx_t row_count) { +void DuckTransaction::PushAppend(DataTable *table, idx_t start_row, idx_t row_count) { auto append_info = (AppendInfo *)undo_buffer.CreateEntry(UndoFlags::INSERT_TUPLE, sizeof(AppendInfo)); append_info->table = table; append_info->start_row = start_row; append_info->count = row_count; } -UpdateInfo *Transaction::CreateUpdateInfo(idx_t type_size, idx_t entries) { +UpdateInfo *DuckTransaction::CreateUpdateInfo(idx_t type_size, idx_t entries) { auto update_info = (UpdateInfo *)undo_buffer.CreateEntry( UndoFlags::UPDATE_TUPLE, sizeof(UpdateInfo) + (sizeof(sel_t) + type_size) * STANDARD_VECTOR_SIZE); update_info->max = STANDARD_VECTOR_SIZE; @@ -235673,27 +249155,33 @@ UpdateInfo *Transaction::CreateUpdateInfo(idx_t type_size, idx_t entries) { return update_info; } -bool Transaction::ChangesMade() { +bool DuckTransaction::ChangesMade() { return undo_buffer.ChangesMade() || storage->ChangesMade(); } -bool Transaction::AutomaticCheckpoint(DatabaseInstance &db) { - auto &storage_manager = StorageManager::GetStorageManager(db); +bool DuckTransaction::AutomaticCheckpoint(AttachedDatabase &db) { + auto &storage_manager = db.GetStorageManager(); return storage_manager.AutomaticCheckpoint(storage->EstimatedSize() + undo_buffer.EstimatedSize()); } -string Transaction::Commit(DatabaseInstance &db, transaction_t commit_id, bool checkpoint) noexcept { +string DuckTransaction::Commit(AttachedDatabase &db, transaction_t commit_id, bool checkpoint) noexcept { // "checkpoint" parameter indicates if the caller will checkpoint. If checkpoint == // true: Then this function will NOT write to the WAL or flush/persist. // This method only makes commit in memory, expecting caller to checkpoint/flush. // false: Then this function WILL write to the WAL and Flush/Persist it. this->commit_id = commit_id; - auto &storage_manager = StorageManager::GetStorageManager(db); - auto log = storage_manager.GetWriteAheadLog(); UndoBuffer::IteratorState iterator_state; LocalStorage::CommitState commit_state; - auto storage_commit_state = storage_manager.GenStorageCommitState(*this, checkpoint); + unique_ptr storage_commit_state; + WriteAheadLog *log; + if (!db.IsSystem()) { + auto &storage_manager = db.GetStorageManager(); + log = storage_manager.GetWriteAheadLog(); + storage_commit_state = storage_manager.GenStorageCommitState(*this, checkpoint); + } else { + log = nullptr; + } try { storage->Commit(commit_state, *this); undo_buffer.Commit(iterator_state, log, commit_id); @@ -235703,7 +249191,9 @@ string Transaction::Commit(DatabaseInstance &db, transaction_t commit_id, bool c log->WriteSequenceValue(entry.first, entry.second); } } - storage_commit_state->FlushCommit(); + if (storage_commit_state) { + storage_commit_state->FlushCommit(); + } return string(); } catch (std::exception &ex) { undo_buffer.RevertCommit(iterator_state, transaction_id); @@ -235711,19 +249201,15 @@ string Transaction::Commit(DatabaseInstance &db, transaction_t commit_id, bool c } } -void Transaction::Rollback() noexcept { +void DuckTransaction::Rollback() noexcept { storage->Rollback(); undo_buffer.Rollback(); } -void Transaction::Cleanup() { +void DuckTransaction::Cleanup() { undo_buffer.Cleanup(); } -ValidChecker &ValidChecker::Get(Transaction &transaction) { - return transaction.transaction_validity; -} - } // namespace duckdb @@ -235731,63 +249217,6 @@ ValidChecker &ValidChecker::Get(Transaction &transaction) { -namespace duckdb { - -TransactionContext::~TransactionContext() { - if (current_transaction) { - try { - Rollback(); - } catch (...) { - } - } -} - -void TransactionContext::BeginTransaction() { - if (current_transaction) { - throw TransactionException("cannot start a transaction within a transaction"); - } - current_transaction = transaction_manager.StartTransaction(context); -} - -void TransactionContext::Commit() { - if (!current_transaction) { - throw TransactionException("failed to commit: no transaction active"); - } - auto transaction = current_transaction; - SetAutoCommit(true); - current_transaction = nullptr; - string error = transaction_manager.CommitTransaction(context, transaction); - if (!error.empty()) { - throw TransactionException("Failed to commit: %s", error); - } -} - -void TransactionContext::SetAutoCommit(bool value) { - auto_commit = value; - if (!auto_commit && !current_transaction) { - BeginTransaction(); - } -} - -void TransactionContext::Rollback() { - if (!current_transaction) { - throw TransactionException("failed to rollback: no transaction active"); - } - auto transaction = current_transaction; - ClearTransaction(); - transaction_manager.RollbackTransaction(transaction); -} - -void TransactionContext::ClearTransaction() { - SetAutoCommit(true); - current_transaction = nullptr; -} - -} // namespace duckdb - - - - @@ -235800,13 +249229,13 @@ void TransactionContext::ClearTransaction() { namespace duckdb { struct CheckpointLock { - explicit CheckpointLock(TransactionManager &manager) : manager(manager), is_locked(false) { + explicit CheckpointLock(DuckTransactionManager &manager) : manager(manager), is_locked(false) { } ~CheckpointLock() { Unlock(); } - TransactionManager &manager; + DuckTransactionManager &manager; bool is_locked; void Lock() { @@ -235824,24 +249253,31 @@ struct CheckpointLock { } }; -TransactionManager::TransactionManager(DatabaseInstance &db) : db(db), thread_is_checkpointing(false) { - // start timestamp starts at zero - current_start_timestamp = 0; +DuckTransactionManager::DuckTransactionManager(AttachedDatabase &db) + : TransactionManager(db), thread_is_checkpointing(false) { + // start timestamp starts at two + current_start_timestamp = 2; // transaction ID starts very high: // it should be much higher than the current start timestamp // if transaction_id < start_timestamp for any set of active transactions // uncommited data could be read by current_transaction_id = TRANSACTION_ID_START; - // the current active query id - current_query_number = 1; lowest_active_id = TRANSACTION_ID_START; lowest_active_start = MAX_TRANSACTION_ID; } -TransactionManager::~TransactionManager() { +DuckTransactionManager::~DuckTransactionManager() { +} + +DuckTransactionManager &DuckTransactionManager::Get(AttachedDatabase &db) { + auto &transaction_manager = TransactionManager::Get(db); + if (!transaction_manager.IsDuckTransactionManager()) { + throw InternalException("Calling DuckTransactionManager::Get on non-DuckDB transaction manager"); + } + return (DuckTransactionManager &)transaction_manager; } -Transaction *TransactionManager::StartTransaction(ClientContext &context) { +Transaction *DuckTransactionManager::StartTransaction(ClientContext &context) { // obtain the transaction lock during this function lock_guard lock(transaction_lock); if (current_start_timestamp >= TRANSACTION_ID_START) { // LCOV_EXCL_START @@ -235852,33 +249288,30 @@ Transaction *TransactionManager::StartTransaction(ClientContext &context) { // obtain the start time and transaction ID of this transaction transaction_t start_time = current_start_timestamp++; transaction_t transaction_id = current_transaction_id++; - timestamp_t start_timestamp = Timestamp::GetCurrentTimestamp(); if (active_transactions.empty()) { lowest_active_start = start_time; lowest_active_id = transaction_id; } // create the actual transaction - auto &catalog = Catalog::GetCatalog(db); - auto transaction = - make_unique(context, start_time, transaction_id, start_timestamp, catalog.GetCatalogVersion()); + auto transaction = make_unique(*this, context, start_time, transaction_id); auto transaction_ptr = transaction.get(); // store it in the set of active transactions - active_transactions.push_back(move(transaction)); + active_transactions.push_back(std::move(transaction)); return transaction_ptr; } struct ClientLockWrapper { ClientLockWrapper(mutex &client_lock, shared_ptr connection) - : connection(move(connection)), connection_lock(make_unique>(client_lock)) { + : connection(std::move(connection)), connection_lock(make_unique>(client_lock)) { } shared_ptr connection; unique_ptr> connection_lock; }; -void TransactionManager::LockClients(vector &client_locks, ClientContext &context) { +void DuckTransactionManager::LockClients(vector &client_locks, ClientContext &context) { auto &connection_manager = ConnectionManager::Get(context); client_locks.emplace_back(connection_manager.connections_lock, nullptr); auto connection_list = connection_manager.GetConnectionList(); @@ -235887,24 +249320,24 @@ void TransactionManager::LockClients(vector &client_locks, Cl continue; } auto &context_lock = con->context_lock; - client_locks.emplace_back(context_lock, move(con)); + client_locks.emplace_back(context_lock, std::move(con)); } } -void TransactionManager::Checkpoint(ClientContext &context, bool force) { - auto &storage_manager = StorageManager::GetStorageManager(db); +void DuckTransactionManager::Checkpoint(ClientContext &context, bool force) { + auto &storage_manager = db.GetStorageManager(); if (storage_manager.InMemory()) { return; } // first check if no other thread is checkpointing right now - auto lock = make_unique>(transaction_lock); + auto lock = unique_lock(transaction_lock); if (thread_is_checkpointing) { throw TransactionException("Cannot CHECKPOINT: another thread is checkpointing right now"); } CheckpointLock checkpoint_lock(*this); checkpoint_lock.Lock(); - lock.reset(); + lock.unlock(); // lock all the clients AND the connection manager now // this ensures no new queries can be started, and no new connections to the database can be made @@ -235912,8 +249345,8 @@ void TransactionManager::Checkpoint(ClientContext &context, bool force) { vector client_locks; LockClients(client_locks, context); - lock = make_unique>(transaction_lock); - auto current = &Transaction::GetTransaction(context); + auto current = &DuckTransaction::Get(context, db); + lock.lock(); if (current->ChangesMade()) { throw TransactionException("Cannot CHECKPOINT: the current transaction has transaction local changes"); } @@ -235941,12 +249374,14 @@ void TransactionManager::Checkpoint(ClientContext &context, bool force) { D_ASSERT(CanCheckpoint(nullptr)); } } - auto &storage = StorageManager::GetStorageManager(context); - storage.CreateCheckpoint(); + storage_manager.CreateCheckpoint(); } -bool TransactionManager::CanCheckpoint(Transaction *current) { - auto &storage_manager = StorageManager::GetStorageManager(db); +bool DuckTransactionManager::CanCheckpoint(DuckTransaction *current) { + if (db.IsSystem()) { + return false; + } + auto &storage_manager = db.GetStorageManager(); if (storage_manager.InMemory()) { return false; } @@ -235961,7 +249396,8 @@ bool TransactionManager::CanCheckpoint(Transaction *current) { return true; } -string TransactionManager::CommitTransaction(ClientContext &context, Transaction *transaction) { +string DuckTransactionManager::CommitTransaction(ClientContext &context, Transaction *transaction_p) { + auto transaction = (DuckTransaction *)transaction_p; vector client_locks; auto lock = make_unique>(transaction_lock); CheckpointLock checkpoint_lock(*this); @@ -236009,13 +249445,14 @@ string TransactionManager::CommitTransaction(ClientContext &context, Transaction // checkpoint if (checkpoint) { // checkpoint the database to disk - auto &storage_manager = StorageManager::GetStorageManager(db); + auto &storage_manager = db.GetStorageManager(); storage_manager.CreateCheckpoint(false, true); } return error; } -void TransactionManager::RollbackTransaction(Transaction *transaction) { +void DuckTransactionManager::RollbackTransaction(Transaction *transaction_p) { + auto transaction = (DuckTransaction *)transaction_p; // obtain the transaction lock during this function lock_guard lock(transaction_lock); @@ -236027,7 +249464,7 @@ void TransactionManager::RollbackTransaction(Transaction *transaction) { RemoveTransaction(transaction); } -void TransactionManager::RemoveTransaction(Transaction *transaction) noexcept { +void DuckTransactionManager::RemoveTransaction(DuckTransaction *transaction) noexcept { // remove the transaction from the list of active transactions idx_t t_index = active_transactions.size(); // check for the lowest and highest start time in the list of transactions @@ -236049,16 +249486,17 @@ void TransactionManager::RemoveTransaction(Transaction *transaction) noexcept { transaction_t lowest_stored_query = lowest_start_time; D_ASSERT(t_index != active_transactions.size()); - auto current_transaction = move(active_transactions[t_index]); + auto current_transaction = std::move(active_transactions[t_index]); + auto current_query = DatabaseManager::Get(db).ActiveQueryNumber(); if (transaction->commit_id != 0) { // the transaction was committed, add it to the list of recently // committed transactions - recently_committed_transactions.push_back(move(current_transaction)); + recently_committed_transactions.push_back(std::move(current_transaction)); } else { // the transaction was aborted, but we might still need its information // add it to the set of transactions awaiting GC - current_transaction->highest_active_query = current_query_number; - old_transactions.push_back(move(current_transaction)); + current_transaction->highest_active_query = current_query; + old_transactions.push_back(std::move(current_transaction)); } // remove the transaction from the set of currently active transactions active_transactions.erase(active_transactions.begin() + t_index); @@ -236082,9 +249520,9 @@ void TransactionManager::RemoveTransaction(Transaction *transaction) noexcept { // when all the currently active scans have finished running...) recently_committed_transactions[i]->Cleanup(); // store the current highest active query - recently_committed_transactions[i]->highest_active_query = current_query_number; + recently_committed_transactions[i]->highest_active_query = current_query; // move it to the list of transactions awaiting GC - old_transactions.push_back(move(recently_committed_transactions[i])); + old_transactions.push_back(std::move(recently_committed_transactions[i])); } else { // recently_committed_transactions is ordered on commit_id // implicitly thus if the current one is bigger than @@ -236120,6 +249558,319 @@ void TransactionManager::RemoveTransaction(Transaction *transaction) noexcept { +namespace duckdb { + +MetaTransaction::MetaTransaction(ClientContext &context_p, timestamp_t start_timestamp_p, idx_t catalog_version_p) + : context(context_p), start_timestamp(start_timestamp_p), catalog_version(catalog_version_p), read_only(true), + active_query(MAXIMUM_QUERY_ID), modified_database(nullptr) { +} + +MetaTransaction &MetaTransaction::Get(ClientContext &context) { + return context.transaction.ActiveTransaction(); +} + +ValidChecker &ValidChecker::Get(MetaTransaction &transaction) { + return transaction.transaction_validity; +} + +Transaction &Transaction::Get(ClientContext &context, AttachedDatabase &db) { + auto &meta_transaction = MetaTransaction::Get(context); + return meta_transaction.GetTransaction(&db); +} + +Transaction &MetaTransaction::GetTransaction(AttachedDatabase *db) { + auto entry = transactions.find(db); + if (entry == transactions.end()) { + auto new_transaction = db->GetTransactionManager().StartTransaction(context); + if (!new_transaction) { + throw InternalException("StartTransaction did not return a valid transaction"); + } + new_transaction->active_query = active_query; + all_transactions.push_back(db); + transactions[db] = new_transaction; + return *new_transaction; + } else { + D_ASSERT(entry->second->active_query == active_query); + return *entry->second; + } +} + +Transaction &Transaction::Get(ClientContext &context, Catalog &catalog) { + return Transaction::Get(context, catalog.GetAttached()); +} + +string MetaTransaction::Commit() { + string error; + // commit transactions in reverse order + for (idx_t i = all_transactions.size(); i > 0; i--) { + auto db = all_transactions[i - 1]; + auto entry = transactions.find(db); + if (entry == transactions.end()) { + throw InternalException("Could not find transaction corresponding to database in MetaTransaction"); + } + auto &transaction_manager = db->GetTransactionManager(); + auto transaction = entry->second; + if (error.empty()) { + // commit + error = transaction_manager.CommitTransaction(context, transaction); + } else { + // we have encountered an error previously - roll back subsequent entries + transaction_manager.RollbackTransaction(transaction); + } + } + return error; +} + +void MetaTransaction::Rollback() { + // rollback transactions in reverse order + for (idx_t i = all_transactions.size(); i > 0; i--) { + auto db = all_transactions[i - 1]; + auto &transaction_manager = db->GetTransactionManager(); + auto entry = transactions.find(db); + D_ASSERT(entry != transactions.end()); + auto transaction = entry->second; + transaction_manager.RollbackTransaction(transaction); + } +} + +idx_t MetaTransaction::GetActiveQuery() { + return active_query; +} + +void MetaTransaction::SetActiveQuery(transaction_t query_number) { + active_query = query_number; + for (auto &entry : transactions) { + entry.second->active_query = query_number; + } +} + +void MetaTransaction::ModifyDatabase(AttachedDatabase *db) { + if (db->IsSystem() || db->IsTemporary()) { + // we can always modify the system and temp databases + return; + } + if (!modified_database) { + modified_database = db; + return; + } + if (db != modified_database) { + throw TransactionException( + "Attempting to write to database \"%s\" in a transaction that has already modified database \"%s\" - a " + "single transaction can only write to a single attached database.", + db->GetName(), modified_database->GetName()); + } +} + +} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/transaction/rollback_state.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { +class DataChunk; +class DataTable; +class WriteAheadLog; + +class RollbackState { +public: + RollbackState() { + } + +public: + void RollbackEntry(UndoFlags type, data_ptr_t data); +}; + +} // namespace duckdb + + + + + + + + + + + + +namespace duckdb { + +void RollbackState::RollbackEntry(UndoFlags type, data_ptr_t data) { + switch (type) { + case UndoFlags::CATALOG_ENTRY: { + // undo this catalog entry + auto catalog_entry = Load(data); + D_ASSERT(catalog_entry->set); + catalog_entry->set->Undo(catalog_entry); + break; + } + case UndoFlags::INSERT_TUPLE: { + auto info = (AppendInfo *)data; + // revert the append in the base table + info->table->RevertAppend(info->start_row, info->count); + break; + } + case UndoFlags::DELETE_TUPLE: { + auto info = (DeleteInfo *)data; + // reset the deleted flag on rollback + info->vinfo->CommitDelete(NOT_DELETED_ID, info->rows, info->count); + break; + } + case UndoFlags::UPDATE_TUPLE: { + auto info = (UpdateInfo *)data; + info->segment->RollbackUpdate(info); + break; + } + default: // LCOV_EXCL_START + D_ASSERT(type == UndoFlags::EMPTY_ENTRY); + break; + } // LCOV_EXCL_STOP +} + +} // namespace duckdb + + + + + +namespace duckdb { + +Transaction::Transaction(TransactionManager &manager_p, ClientContext &context_p) + : manager(manager_p), context(context_p.shared_from_this()), active_query(MAXIMUM_QUERY_ID) { +} + +Transaction::~Transaction() { +} + +bool Transaction::IsReadOnly() { + auto ctxt = context.lock(); + if (!ctxt) { + throw InternalException("Transaction::IsReadOnly() called after client context has been destroyed"); + } + auto &db = manager.GetDB(); + return MetaTransaction::Get(*ctxt).ModifiedDatabase() != &db; +} + +} // namespace duckdb + + + + + + + + +namespace duckdb { + +TransactionContext::TransactionContext(ClientContext &context) + : context(context), auto_commit(true), current_transaction(nullptr) { +} + +TransactionContext::~TransactionContext() { + if (current_transaction) { + try { + Rollback(); + } catch (...) { + } + } +} + +void TransactionContext::BeginTransaction() { + if (current_transaction) { + throw TransactionException("cannot start a transaction within a transaction"); + } + auto start_timestamp = Timestamp::GetCurrentTimestamp(); + auto catalog_version = Catalog::GetSystemCatalog(context).GetCatalogVersion(); + current_transaction = make_unique(context, start_timestamp, catalog_version); + + auto &config = DBConfig::GetConfig(context); + if (config.options.immediate_transaction_mode) { + // if immediate transaction mode is enabled then start all transactions immediately + auto databases = DatabaseManager::Get(context).GetDatabases(context); + for (auto db : databases) { + current_transaction->GetTransaction(db); + } + } +} + +void TransactionContext::Commit() { + if (!current_transaction) { + throw TransactionException("failed to commit: no transaction active"); + } + auto transaction = std::move(current_transaction); + ClearTransaction(); + string error = transaction->Commit(); + if (!error.empty()) { + throw TransactionException("Failed to commit: %s", error); + } +} + +void TransactionContext::SetAutoCommit(bool value) { + auto_commit = value; + if (!auto_commit && !current_transaction) { + BeginTransaction(); + } +} + +void TransactionContext::Rollback() { + if (!current_transaction) { + throw TransactionException("failed to rollback: no transaction active"); + } + auto transaction = std::move(current_transaction); + ClearTransaction(); + transaction->Rollback(); +} + +void TransactionContext::ClearTransaction() { + SetAutoCommit(true); + current_transaction = nullptr; +} + +idx_t TransactionContext::GetActiveQuery() { + if (!current_transaction) { + throw InternalException("GetActiveQuery called without active transaction"); + } + return current_transaction->GetActiveQuery(); +} + +void TransactionContext::ResetActiveQuery() { + if (current_transaction) { + SetActiveQuery(MAXIMUM_QUERY_ID); + } +} + +void TransactionContext::SetActiveQuery(transaction_t query_number) { + if (!current_transaction) { + throw InternalException("SetActiveQuery called without active transaction"); + } + current_transaction->SetActiveQuery(query_number); +} + +} // namespace duckdb + + +namespace duckdb { + +TransactionManager::TransactionManager(AttachedDatabase &db) : db(db) { +} + +TransactionManager::~TransactionManager() { +} + +} // namespace duckdb + + + + + @@ -236133,9 +249884,7 @@ void TransactionManager::RemoveTransaction(Transaction *transaction) noexcept { namespace duckdb { constexpr uint32_t UNDO_ENTRY_HEADER_SIZE = sizeof(UndoFlags) + sizeof(uint32_t); -UndoBuffer::UndoBuffer(const shared_ptr &context_p) - : context(*context_p), allocator(BufferAllocator::Get(*context_p)) { - D_ASSERT(context_p); +UndoBuffer::UndoBuffer(ClientContext &context_p) : context(context_p), allocator(BufferAllocator::Get(context_p)) { } data_ptr_t UndoBuffer::CreateEntry(UndoFlags type, idx_t len) { @@ -236296,7 +250045,7 @@ class CopiedStatementVerifier : public StatementVerifier { namespace duckdb { CopiedStatementVerifier::CopiedStatementVerifier(unique_ptr statement_p) - : StatementVerifier(VerificationType::COPIED, "Copied", move(statement_p)) { + : StatementVerifier(VerificationType::COPIED, "Copied", std::move(statement_p)) { } unique_ptr CopiedStatementVerifier::Create(const SQLStatement &statement) { @@ -236332,7 +250081,7 @@ class DeserializedStatementVerifier : public StatementVerifier { namespace duckdb { DeserializedStatementVerifier::DeserializedStatementVerifier(unique_ptr statement_p) - : StatementVerifier(VerificationType::DESERIALIZED, "Deserialized", move(statement_p)) { + : StatementVerifier(VerificationType::DESERIALIZED, "Deserialized", std::move(statement_p)) { } unique_ptr DeserializedStatementVerifier::Create(const SQLStatement &statement) { @@ -236374,7 +250123,7 @@ class ExternalStatementVerifier : public StatementVerifier { namespace duckdb { ExternalStatementVerifier::ExternalStatementVerifier(unique_ptr statement_p) - : StatementVerifier(VerificationType::EXTERNAL, "External", move(statement_p)) { + : StatementVerifier(VerificationType::EXTERNAL, "External", std::move(statement_p)) { } unique_ptr ExternalStatementVerifier::Create(const SQLStatement &statement) { @@ -236414,7 +250163,7 @@ class ParsedStatementVerifier : public StatementVerifier { namespace duckdb { ParsedStatementVerifier::ParsedStatementVerifier(unique_ptr statement_p) - : StatementVerifier(VerificationType::PARSED, "Parsed", move(statement_p)) { + : StatementVerifier(VerificationType::PARSED, "Parsed", std::move(statement_p)) { } unique_ptr ParsedStatementVerifier::Create(const SQLStatement &statement) { @@ -236427,7 +250176,7 @@ unique_ptr ParsedStatementVerifier::Create(const SQLStatement } D_ASSERT(parser.statements.size() == 1); D_ASSERT(parser.statements[0]->type == StatementType::SELECT_STATEMENT); - return make_unique(move(parser.statements[0])); + return make_unique(std::move(parser.statements[0])); } } // namespace duckdb @@ -236477,7 +250226,7 @@ class PreparedStatementVerifier : public StatementVerifier { namespace duckdb { PreparedStatementVerifier::PreparedStatementVerifier(unique_ptr statement_p) - : StatementVerifier(VerificationType::PREPARED, "Prepared", move(statement_p)) { + : StatementVerifier(VerificationType::PREPARED, "Prepared", std::move(statement_p)) { } unique_ptr PreparedStatementVerifier::Create(const SQLStatement &statement) { @@ -236494,19 +250243,19 @@ void PreparedStatementVerifier::Extract() { string name = "__duckdb_verification_prepared_statement"; auto prepare = make_unique(); prepare->name = name; - prepare->statement = move(statement); + prepare->statement = std::move(statement); auto execute = make_unique(); execute->name = name; - execute->values = move(values); + execute->values = std::move(values); auto dealloc = make_unique(); dealloc->info->type = CatalogType::PREPARED_STATEMENT; dealloc->info->name = string(name); - prepare_statement = move(prepare); - execute_statement = move(execute); - dealloc_statement = move(dealloc); + prepare_statement = std::move(prepare); + execute_statement = std::move(execute); + dealloc_statement = std::move(dealloc); } void PreparedStatementVerifier::ConvertConstants(unique_ptr &child) { @@ -236524,13 +250273,13 @@ void PreparedStatementVerifier::ConvertConstants(unique_ptr &c } } if (index == values.size()) { - values.push_back(move(child)); + values.push_back(std::move(child)); } // replace it with an expression auto parameter = make_unique(); parameter->parameter_nr = index + 1; parameter->alias = alias; - child = move(parameter); + child = std::move(parameter); return; } ParsedExpressionIterator::EnumerateChildren(*child, @@ -236546,15 +250295,15 @@ bool PreparedStatementVerifier::Run( Extract(); // execute the prepared statements try { - auto prepare_result = run(string(), move(prepare_statement)); + auto prepare_result = run(string(), std::move(prepare_statement)); if (prepare_result->HasError()) { prepare_result->ThrowError("Failed prepare during verify: "); } - auto execute_result = run(string(), move(execute_statement)); + auto execute_result = run(string(), std::move(execute_statement)); if (execute_result->HasError()) { execute_result->ThrowError("Failed execute during verify: "); } - materialized_result = unique_ptr_cast(move(execute_result)); + materialized_result = unique_ptr_cast(std::move(execute_result)); } catch (const Exception &ex) { if (ex.type != ExceptionType::PARAMETER_NOT_ALLOWED) { materialized_result = make_unique(PreservedError(ex)); @@ -236564,7 +250313,7 @@ bool PreparedStatementVerifier::Run( materialized_result = make_unique(PreservedError(ex)); failed = true; } - run(string(), move(dealloc_statement)); + run(string(), std::move(dealloc_statement)); context.interrupted = false; return failed; @@ -236611,12 +250360,13 @@ class UnoptimizedStatementVerifier : public StatementVerifier { namespace duckdb { StatementVerifier::StatementVerifier(VerificationType type, string name, unique_ptr statement_p) - : type(type), name(move(name)), statement(unique_ptr_cast(move(statement_p))), + : type(type), name(std::move(name)), + statement(unique_ptr_cast(std::move(statement_p))), select_list(statement->node->GetSelectList()) { } StatementVerifier::StatementVerifier(unique_ptr statement_p) - : StatementVerifier(VerificationType::ORIGINAL, "Original", move(statement_p)) { + : StatementVerifier(VerificationType::ORIGINAL, "Original", std::move(statement_p)) { } StatementVerifier::~StatementVerifier() noexcept { @@ -236703,11 +250453,11 @@ bool StatementVerifier::Run( context.config.enable_optimizer = !DisableOptimizer(); context.config.force_external = ForceExternal(); try { - auto result = run(query, move(statement)); + auto result = run(query, std::move(statement)); if (result->HasError()) { failed = true; } - materialized_result = unique_ptr_cast(move(result)); + materialized_result = unique_ptr_cast(std::move(result)); } catch (const Exception &ex) { failed = true; materialized_result = make_unique(PreservedError(ex)); @@ -236750,7 +250500,7 @@ string StatementVerifier::CompareResults(const StatementVerifier &other) { namespace duckdb { UnoptimizedStatementVerifier::UnoptimizedStatementVerifier(unique_ptr statement_p) - : StatementVerifier(VerificationType::UNOPTIMIZED, "Unoptimized", move(statement_p)) { + : StatementVerifier(VerificationType::UNOPTIMIZED, "Unoptimized", std::move(statement_p)) { } unique_ptr UnoptimizedStatementVerifier::Create(const SQLStatement &statement_p) { @@ -239844,21 +253594,24 @@ static inline size_t compressBulk(SymbolTable &symbolTable, size_t nlines, size_ #define FSST_SAMPLELINE ((size_t) 512) // quickly select a uniformly random set of lines such that we have between [FSST_SAMPLETARGET,FSST_SAMPLEMAXSZ) string bytes -vector makeSample(u8* sampleBuf, u8* strIn[], size_t **lenRef, size_t nlines) { - size_t totSize = 0, *lenIn = *lenRef; +vector makeSample(u8* sampleBuf, u8* strIn[], size_t *lenIn, size_t nlines, + unique_ptr>& sample_len_out) { + size_t totSize = 0; vector sample; for(size_t i=0; i>(new vector()); + sample_len_out->reserve(nlines + FSST_SAMPLEMAXSZ/FSST_SAMPLELINE); + + // This fails if we have a lot of small strings and a few big ones? while(sampleBuf < sampleLim) { // choose a non-empty line sampleRnd = FSST_HASH(sampleRnd); @@ -239875,7 +253628,9 @@ vector makeSample(u8* sampleBuf, u8* strIn[], size_t **lenRef, size_t nline size_t len = min(lenIn[linenr]-chunk,FSST_SAMPLELINE); memcpy(sampleBuf, strIn[linenr]+chunk, len); sample.push_back(sampleBuf); - sampleBuf += *sampleLen++ = len; + + sample_len_out->push_back(len); + sampleBuf += len; } } return sample; @@ -239883,11 +253638,11 @@ vector makeSample(u8* sampleBuf, u8* strIn[], size_t **lenRef, size_t nline extern "C" duckdb_fsst_encoder_t* duckdb_fsst_create(size_t n, size_t lenIn[], u8 *strIn[], int zeroTerminated) { u8* sampleBuf = new u8[FSST_SAMPLEMAXSZ]; - size_t *sampleLen = lenIn; - vector sample = makeSample(sampleBuf, strIn, &sampleLen, n?n:1); // careful handling of input to get a right-size and representative sample + unique_ptr> sample_sizes; + vector sample = makeSample(sampleBuf, strIn, lenIn, n?n:1, sample_sizes); // careful handling of input to get a right-size and representative sample Encoder *encoder = new Encoder(); + size_t* sampleLen = sample_sizes ? sample_sizes->data() : &lenIn[0]; encoder->symbolTable = shared_ptr(buildSymbolTable(encoder->counters, sample, sampleLen, zeroTerminated)); - if (sampleLen != lenIn) delete[] sampleLen; delete[] sampleBuf; return (duckdb_fsst_encoder_t*) encoder; } @@ -259550,6 +273305,13 @@ void Prog::ComputeByteMap() { builder.Build(bytemap_, &bytemap_range_); } +int TotalInstructions(int inst_count_[]) { + int total = 0; + for (int i = 0; i < kNumInst; i++) + total += inst_count_[i]; + return total; +} + // Prog::Flatten() implements a graph rewriting algorithm. // // The overall process is similar to epsilon removal, but retains some epsilon @@ -259642,10 +273404,7 @@ void Prog::Flatten() { inst_count_[ip->opcode()]++; } - int total = 0; - for (int i = 0; i < kNumInst; i++) - total += inst_count_[i]; - DCHECK_EQ(total, static_cast(flat.size())); + DCHECK_EQ(TotalInstructions(inst_count_), static_cast(flat.size())); // Remap start_unanchored and start. if (start_unanchored() == 0) { @@ -292502,180 +306261,182 @@ PGValue *makeString(const char *str) { PLANS = 566, POLICY = 567, POSITION = 568, - PRAGMA_P = 569, - PRECEDING = 570, - PRECISION = 571, - PREPARE = 572, - PREPARED = 573, - PRESERVE = 574, - PRIMARY = 575, - PRIOR = 576, - PRIVILEGES = 577, - PROCEDURAL = 578, - PROCEDURE = 579, - PROGRAM = 580, - PUBLICATION = 581, - QUALIFY = 582, - QUOTE = 583, - RANGE = 584, - READ_P = 585, - REAL = 586, - REASSIGN = 587, - RECHECK = 588, - RECURSIVE = 589, - REF = 590, - REFERENCES = 591, - REFERENCING = 592, - REFRESH = 593, - REINDEX = 594, - RELATIVE_P = 595, - RELEASE = 596, - RENAME = 597, - REPEATABLE = 598, - REPLACE = 599, - REPLICA = 600, - RESET = 601, - RESPECT_P = 602, - RESTART = 603, - RESTRICT = 604, - RETURNING = 605, - RETURNS = 606, - REVOKE = 607, - RIGHT = 608, - ROLE = 609, - ROLLBACK = 610, - ROLLUP = 611, - ROW = 612, - ROWS = 613, - RULE = 614, - SAMPLE = 615, - SAVEPOINT = 616, - SCHEMA = 617, - SCHEMAS = 618, - SCROLL = 619, - SEARCH = 620, - SECOND_P = 621, - SECONDS_P = 622, - SECURITY = 623, - SELECT = 624, - SEQUENCE = 625, - SEQUENCES = 626, - SERIALIZABLE = 627, - SERVER = 628, - SESSION = 629, - SESSION_USER = 630, - SET = 631, - SETOF = 632, - SETS = 633, - SHARE = 634, - SHOW = 635, - SIMILAR = 636, - SIMPLE = 637, - SKIP = 638, - SMALLINT = 639, - SNAPSHOT = 640, - SOME = 641, - SQL_P = 642, - STABLE = 643, - STANDALONE_P = 644, - START = 645, - STATEMENT = 646, - STATISTICS = 647, - STDIN = 648, - STDOUT = 649, - STORAGE = 650, - STORED = 651, - STRICT_P = 652, - STRIP_P = 653, - STRUCT = 654, - SUBSCRIPTION = 655, - SUBSTRING = 656, - SUMMARIZE = 657, - SYMMETRIC = 658, - SYSID = 659, - SYSTEM_P = 660, - TABLE = 661, - TABLES = 662, - TABLESAMPLE = 663, - TABLESPACE = 664, - TEMP = 665, - TEMPLATE = 666, - TEMPORARY = 667, - TEXT_P = 668, - THEN = 669, - TIME = 670, - TIMESTAMP = 671, - TO = 672, - TRAILING = 673, - TRANSACTION = 674, - TRANSFORM = 675, - TREAT = 676, - TRIGGER = 677, - TRIM = 678, - TRUE_P = 679, - TRUNCATE = 680, - TRUSTED = 681, - TRY_CAST = 682, - TYPE_P = 683, - TYPES_P = 684, - UNBOUNDED = 685, - UNCOMMITTED = 686, - UNENCRYPTED = 687, - UNION = 688, - UNIQUE = 689, - UNKNOWN = 690, - UNLISTEN = 691, - UNLOGGED = 692, - UNTIL = 693, - UPDATE = 694, - USER = 695, - USING = 696, - VACUUM = 697, - VALID = 698, - VALIDATE = 699, - VALIDATOR = 700, - VALUE_P = 701, - VALUES = 702, - VARCHAR = 703, - VARIADIC = 704, - VARYING = 705, - VERBOSE = 706, - VERSION_P = 707, - VIEW = 708, - VIEWS = 709, - VIRTUAL = 710, - VOLATILE = 711, - WHEN = 712, - WHERE = 713, - WHITESPACE_P = 714, - WINDOW = 715, - WITH = 716, - WITHIN = 717, - WITHOUT = 718, - WORK = 719, - WRAPPER = 720, - WRITE_P = 721, - XML_P = 722, - XMLATTRIBUTES = 723, - XMLCONCAT = 724, - XMLELEMENT = 725, - XMLEXISTS = 726, - XMLFOREST = 727, - XMLNAMESPACES = 728, - XMLPARSE = 729, - XMLPI = 730, - XMLROOT = 731, - XMLSERIALIZE = 732, - XMLTABLE = 733, - YEAR_P = 734, - YEARS_P = 735, - YES_P = 736, - ZONE = 737, - NOT_LA = 738, - NULLS_LA = 739, - WITH_LA = 740, - POSTFIXOP = 741, - UMINUS = 742 + POSITIONAL = 569, + PRAGMA_P = 570, + PRECEDING = 571, + PRECISION = 572, + PREPARE = 573, + PREPARED = 574, + PRESERVE = 575, + PRIMARY = 576, + PRIOR = 577, + PRIVILEGES = 578, + PROCEDURAL = 579, + PROCEDURE = 580, + PROGRAM = 581, + PUBLICATION = 582, + QUALIFY = 583, + QUOTE = 584, + RANGE = 585, + READ_P = 586, + REAL = 587, + REASSIGN = 588, + RECHECK = 589, + RECURSIVE = 590, + REF = 591, + REFERENCES = 592, + REFERENCING = 593, + REFRESH = 594, + REINDEX = 595, + RELATIVE_P = 596, + RELEASE = 597, + RENAME = 598, + REPEATABLE = 599, + REPLACE = 600, + REPLICA = 601, + RESET = 602, + RESPECT_P = 603, + RESTART = 604, + RESTRICT = 605, + RETURNING = 606, + RETURNS = 607, + REVOKE = 608, + RIGHT = 609, + ROLE = 610, + ROLLBACK = 611, + ROLLUP = 612, + ROW = 613, + ROWS = 614, + RULE = 615, + SAMPLE = 616, + SAVEPOINT = 617, + SCHEMA = 618, + SCHEMAS = 619, + SCROLL = 620, + SEARCH = 621, + SECOND_P = 622, + SECONDS_P = 623, + SECURITY = 624, + SELECT = 625, + SEQUENCE = 626, + SEQUENCES = 627, + SERIALIZABLE = 628, + SERVER = 629, + SESSION = 630, + SESSION_USER = 631, + SET = 632, + SETOF = 633, + SETS = 634, + SHARE = 635, + SHOW = 636, + SIMILAR = 637, + SIMPLE = 638, + SKIP = 639, + SMALLINT = 640, + SNAPSHOT = 641, + SOME = 642, + SQL_P = 643, + STABLE = 644, + STANDALONE_P = 645, + START = 646, + STATEMENT = 647, + STATISTICS = 648, + STDIN = 649, + STDOUT = 650, + STORAGE = 651, + STORED = 652, + STRICT_P = 653, + STRIP_P = 654, + STRUCT = 655, + SUBSCRIPTION = 656, + SUBSTRING = 657, + SUMMARIZE = 658, + SYMMETRIC = 659, + SYSID = 660, + SYSTEM_P = 661, + TABLE = 662, + TABLES = 663, + TABLESAMPLE = 664, + TABLESPACE = 665, + TEMP = 666, + TEMPLATE = 667, + TEMPORARY = 668, + TEXT_P = 669, + THEN = 670, + TIME = 671, + TIMESTAMP = 672, + TO = 673, + TRAILING = 674, + TRANSACTION = 675, + TRANSFORM = 676, + TREAT = 677, + TRIGGER = 678, + TRIM = 679, + TRUE_P = 680, + TRUNCATE = 681, + TRUSTED = 682, + TRY_CAST = 683, + TYPE_P = 684, + TYPES_P = 685, + UNBOUNDED = 686, + UNCOMMITTED = 687, + UNENCRYPTED = 688, + UNION = 689, + UNIQUE = 690, + UNKNOWN = 691, + UNLISTEN = 692, + UNLOGGED = 693, + UNTIL = 694, + UPDATE = 695, + USE_P = 696, + USER = 697, + USING = 698, + VACUUM = 699, + VALID = 700, + VALIDATE = 701, + VALIDATOR = 702, + VALUE_P = 703, + VALUES = 704, + VARCHAR = 705, + VARIADIC = 706, + VARYING = 707, + VERBOSE = 708, + VERSION_P = 709, + VIEW = 710, + VIEWS = 711, + VIRTUAL = 712, + VOLATILE = 713, + WHEN = 714, + WHERE = 715, + WHITESPACE_P = 716, + WINDOW = 717, + WITH = 718, + WITHIN = 719, + WITHOUT = 720, + WORK = 721, + WRAPPER = 722, + WRITE_P = 723, + XML_P = 724, + XMLATTRIBUTES = 725, + XMLCONCAT = 726, + XMLELEMENT = 727, + XMLEXISTS = 728, + XMLFOREST = 729, + XMLNAMESPACES = 730, + XMLPARSE = 731, + XMLPI = 732, + XMLROOT = 733, + XMLSERIALIZE = 734, + XMLTABLE = 735, + YEAR_P = 736, + YEARS_P = 737, + YES_P = 738, + ZONE = 739, + NOT_LA = 740, + NULLS_LA = 741, + WITH_LA = 742, + POSTFIXOP = 743, + UMINUS = 744 }; #endif /* Tokens. */ @@ -292990,180 +306751,182 @@ PGValue *makeString(const char *str) { #define PLANS 566 #define POLICY 567 #define POSITION 568 -#define PRAGMA_P 569 -#define PRECEDING 570 -#define PRECISION 571 -#define PREPARE 572 -#define PREPARED 573 -#define PRESERVE 574 -#define PRIMARY 575 -#define PRIOR 576 -#define PRIVILEGES 577 -#define PROCEDURAL 578 -#define PROCEDURE 579 -#define PROGRAM 580 -#define PUBLICATION 581 -#define QUALIFY 582 -#define QUOTE 583 -#define RANGE 584 -#define READ_P 585 -#define REAL 586 -#define REASSIGN 587 -#define RECHECK 588 -#define RECURSIVE 589 -#define REF 590 -#define REFERENCES 591 -#define REFERENCING 592 -#define REFRESH 593 -#define REINDEX 594 -#define RELATIVE_P 595 -#define RELEASE 596 -#define RENAME 597 -#define REPEATABLE 598 -#define REPLACE 599 -#define REPLICA 600 -#define RESET 601 -#define RESPECT_P 602 -#define RESTART 603 -#define RESTRICT 604 -#define RETURNING 605 -#define RETURNS 606 -#define REVOKE 607 -#define RIGHT 608 -#define ROLE 609 -#define ROLLBACK 610 -#define ROLLUP 611 -#define ROW 612 -#define ROWS 613 -#define RULE 614 -#define SAMPLE 615 -#define SAVEPOINT 616 -#define SCHEMA 617 -#define SCHEMAS 618 -#define SCROLL 619 -#define SEARCH 620 -#define SECOND_P 621 -#define SECONDS_P 622 -#define SECURITY 623 -#define SELECT 624 -#define SEQUENCE 625 -#define SEQUENCES 626 -#define SERIALIZABLE 627 -#define SERVER 628 -#define SESSION 629 -#define SESSION_USER 630 -#define SET 631 -#define SETOF 632 -#define SETS 633 -#define SHARE 634 -#define SHOW 635 -#define SIMILAR 636 -#define SIMPLE 637 -#define SKIP 638 -#define SMALLINT 639 -#define SNAPSHOT 640 -#define SOME 641 -#define SQL_P 642 -#define STABLE 643 -#define STANDALONE_P 644 -#define START 645 -#define STATEMENT 646 -#define STATISTICS 647 -#define STDIN 648 -#define STDOUT 649 -#define STORAGE 650 -#define STORED 651 -#define STRICT_P 652 -#define STRIP_P 653 -#define STRUCT 654 -#define SUBSCRIPTION 655 -#define SUBSTRING 656 -#define SUMMARIZE 657 -#define SYMMETRIC 658 -#define SYSID 659 -#define SYSTEM_P 660 -#define TABLE 661 -#define TABLES 662 -#define TABLESAMPLE 663 -#define TABLESPACE 664 -#define TEMP 665 -#define TEMPLATE 666 -#define TEMPORARY 667 -#define TEXT_P 668 -#define THEN 669 -#define TIME 670 -#define TIMESTAMP 671 -#define TO 672 -#define TRAILING 673 -#define TRANSACTION 674 -#define TRANSFORM 675 -#define TREAT 676 -#define TRIGGER 677 -#define TRIM 678 -#define TRUE_P 679 -#define TRUNCATE 680 -#define TRUSTED 681 -#define TRY_CAST 682 -#define TYPE_P 683 -#define TYPES_P 684 -#define UNBOUNDED 685 -#define UNCOMMITTED 686 -#define UNENCRYPTED 687 -#define UNION 688 -#define UNIQUE 689 -#define UNKNOWN 690 -#define UNLISTEN 691 -#define UNLOGGED 692 -#define UNTIL 693 -#define UPDATE 694 -#define USER 695 -#define USING 696 -#define VACUUM 697 -#define VALID 698 -#define VALIDATE 699 -#define VALIDATOR 700 -#define VALUE_P 701 -#define VALUES 702 -#define VARCHAR 703 -#define VARIADIC 704 -#define VARYING 705 -#define VERBOSE 706 -#define VERSION_P 707 -#define VIEW 708 -#define VIEWS 709 -#define VIRTUAL 710 -#define VOLATILE 711 -#define WHEN 712 -#define WHERE 713 -#define WHITESPACE_P 714 -#define WINDOW 715 -#define WITH 716 -#define WITHIN 717 -#define WITHOUT 718 -#define WORK 719 -#define WRAPPER 720 -#define WRITE_P 721 -#define XML_P 722 -#define XMLATTRIBUTES 723 -#define XMLCONCAT 724 -#define XMLELEMENT 725 -#define XMLEXISTS 726 -#define XMLFOREST 727 -#define XMLNAMESPACES 728 -#define XMLPARSE 729 -#define XMLPI 730 -#define XMLROOT 731 -#define XMLSERIALIZE 732 -#define XMLTABLE 733 -#define YEAR_P 734 -#define YEARS_P 735 -#define YES_P 736 -#define ZONE 737 -#define NOT_LA 738 -#define NULLS_LA 739 -#define WITH_LA 740 -#define POSTFIXOP 741 -#define UMINUS 742 +#define POSITIONAL 569 +#define PRAGMA_P 570 +#define PRECEDING 571 +#define PRECISION 572 +#define PREPARE 573 +#define PREPARED 574 +#define PRESERVE 575 +#define PRIMARY 576 +#define PRIOR 577 +#define PRIVILEGES 578 +#define PROCEDURAL 579 +#define PROCEDURE 580 +#define PROGRAM 581 +#define PUBLICATION 582 +#define QUALIFY 583 +#define QUOTE 584 +#define RANGE 585 +#define READ_P 586 +#define REAL 587 +#define REASSIGN 588 +#define RECHECK 589 +#define RECURSIVE 590 +#define REF 591 +#define REFERENCES 592 +#define REFERENCING 593 +#define REFRESH 594 +#define REINDEX 595 +#define RELATIVE_P 596 +#define RELEASE 597 +#define RENAME 598 +#define REPEATABLE 599 +#define REPLACE 600 +#define REPLICA 601 +#define RESET 602 +#define RESPECT_P 603 +#define RESTART 604 +#define RESTRICT 605 +#define RETURNING 606 +#define RETURNS 607 +#define REVOKE 608 +#define RIGHT 609 +#define ROLE 610 +#define ROLLBACK 611 +#define ROLLUP 612 +#define ROW 613 +#define ROWS 614 +#define RULE 615 +#define SAMPLE 616 +#define SAVEPOINT 617 +#define SCHEMA 618 +#define SCHEMAS 619 +#define SCROLL 620 +#define SEARCH 621 +#define SECOND_P 622 +#define SECONDS_P 623 +#define SECURITY 624 +#define SELECT 625 +#define SEQUENCE 626 +#define SEQUENCES 627 +#define SERIALIZABLE 628 +#define SERVER 629 +#define SESSION 630 +#define SESSION_USER 631 +#define SET 632 +#define SETOF 633 +#define SETS 634 +#define SHARE 635 +#define SHOW 636 +#define SIMILAR 637 +#define SIMPLE 638 +#define SKIP 639 +#define SMALLINT 640 +#define SNAPSHOT 641 +#define SOME 642 +#define SQL_P 643 +#define STABLE 644 +#define STANDALONE_P 645 +#define START 646 +#define STATEMENT 647 +#define STATISTICS 648 +#define STDIN 649 +#define STDOUT 650 +#define STORAGE 651 +#define STORED 652 +#define STRICT_P 653 +#define STRIP_P 654 +#define STRUCT 655 +#define SUBSCRIPTION 656 +#define SUBSTRING 657 +#define SUMMARIZE 658 +#define SYMMETRIC 659 +#define SYSID 660 +#define SYSTEM_P 661 +#define TABLE 662 +#define TABLES 663 +#define TABLESAMPLE 664 +#define TABLESPACE 665 +#define TEMP 666 +#define TEMPLATE 667 +#define TEMPORARY 668 +#define TEXT_P 669 +#define THEN 670 +#define TIME 671 +#define TIMESTAMP 672 +#define TO 673 +#define TRAILING 674 +#define TRANSACTION 675 +#define TRANSFORM 676 +#define TREAT 677 +#define TRIGGER 678 +#define TRIM 679 +#define TRUE_P 680 +#define TRUNCATE 681 +#define TRUSTED 682 +#define TRY_CAST 683 +#define TYPE_P 684 +#define TYPES_P 685 +#define UNBOUNDED 686 +#define UNCOMMITTED 687 +#define UNENCRYPTED 688 +#define UNION 689 +#define UNIQUE 690 +#define UNKNOWN 691 +#define UNLISTEN 692 +#define UNLOGGED 693 +#define UNTIL 694 +#define UPDATE 695 +#define USE_P 696 +#define USER 697 +#define USING 698 +#define VACUUM 699 +#define VALID 700 +#define VALIDATE 701 +#define VALIDATOR 702 +#define VALUE_P 703 +#define VALUES 704 +#define VARCHAR 705 +#define VARIADIC 706 +#define VARYING 707 +#define VERBOSE 708 +#define VERSION_P 709 +#define VIEW 710 +#define VIEWS 711 +#define VIRTUAL 712 +#define VOLATILE 713 +#define WHEN 714 +#define WHERE 715 +#define WHITESPACE_P 716 +#define WINDOW 717 +#define WITH 718 +#define WITHIN 719 +#define WITHOUT 720 +#define WORK 721 +#define WRAPPER 722 +#define WRITE_P 723 +#define XML_P 724 +#define XMLATTRIBUTES 725 +#define XMLCONCAT 726 +#define XMLELEMENT 727 +#define XMLEXISTS 728 +#define XMLFOREST 729 +#define XMLNAMESPACES 730 +#define XMLPARSE 731 +#define XMLPI 732 +#define XMLROOT 733 +#define XMLSERIALIZE 734 +#define XMLTABLE 735 +#define YEAR_P 736 +#define YEARS_P 737 +#define YES_P 738 +#define ZONE 739 +#define NOT_LA 740 +#define NULLS_LA 741 +#define WITH_LA 742 +#define POSTFIXOP 743 +#define UMINUS 744 @@ -293746,180 +307509,182 @@ namespace duckdb_libpgquery { PLANS = 566, POLICY = 567, POSITION = 568, - PRAGMA_P = 569, - PRECEDING = 570, - PRECISION = 571, - PREPARE = 572, - PREPARED = 573, - PRESERVE = 574, - PRIMARY = 575, - PRIOR = 576, - PRIVILEGES = 577, - PROCEDURAL = 578, - PROCEDURE = 579, - PROGRAM = 580, - PUBLICATION = 581, - QUALIFY = 582, - QUOTE = 583, - RANGE = 584, - READ_P = 585, - REAL = 586, - REASSIGN = 587, - RECHECK = 588, - RECURSIVE = 589, - REF = 590, - REFERENCES = 591, - REFERENCING = 592, - REFRESH = 593, - REINDEX = 594, - RELATIVE_P = 595, - RELEASE = 596, - RENAME = 597, - REPEATABLE = 598, - REPLACE = 599, - REPLICA = 600, - RESET = 601, - RESPECT_P = 602, - RESTART = 603, - RESTRICT = 604, - RETURNING = 605, - RETURNS = 606, - REVOKE = 607, - RIGHT = 608, - ROLE = 609, - ROLLBACK = 610, - ROLLUP = 611, - ROW = 612, - ROWS = 613, - RULE = 614, - SAMPLE = 615, - SAVEPOINT = 616, - SCHEMA = 617, - SCHEMAS = 618, - SCROLL = 619, - SEARCH = 620, - SECOND_P = 621, - SECONDS_P = 622, - SECURITY = 623, - SELECT = 624, - SEQUENCE = 625, - SEQUENCES = 626, - SERIALIZABLE = 627, - SERVER = 628, - SESSION = 629, - SESSION_USER = 630, - SET = 631, - SETOF = 632, - SETS = 633, - SHARE = 634, - SHOW = 635, - SIMILAR = 636, - SIMPLE = 637, - SKIP = 638, - SMALLINT = 639, - SNAPSHOT = 640, - SOME = 641, - SQL_P = 642, - STABLE = 643, - STANDALONE_P = 644, - START = 645, - STATEMENT = 646, - STATISTICS = 647, - STDIN = 648, - STDOUT = 649, - STORAGE = 650, - STORED = 651, - STRICT_P = 652, - STRIP_P = 653, - STRUCT = 654, - SUBSCRIPTION = 655, - SUBSTRING = 656, - SUMMARIZE = 657, - SYMMETRIC = 658, - SYSID = 659, - SYSTEM_P = 660, - TABLE = 661, - TABLES = 662, - TABLESAMPLE = 663, - TABLESPACE = 664, - TEMP = 665, - TEMPLATE = 666, - TEMPORARY = 667, - TEXT_P = 668, - THEN = 669, - TIME = 670, - TIMESTAMP = 671, - TO = 672, - TRAILING = 673, - TRANSACTION = 674, - TRANSFORM = 675, - TREAT = 676, - TRIGGER = 677, - TRIM = 678, - TRUE_P = 679, - TRUNCATE = 680, - TRUSTED = 681, - TRY_CAST = 682, - TYPE_P = 683, - TYPES_P = 684, - UNBOUNDED = 685, - UNCOMMITTED = 686, - UNENCRYPTED = 687, - UNION = 688, - UNIQUE = 689, - UNKNOWN = 690, - UNLISTEN = 691, - UNLOGGED = 692, - UNTIL = 693, - UPDATE = 694, - USER = 695, - USING = 696, - VACUUM = 697, - VALID = 698, - VALIDATE = 699, - VALIDATOR = 700, - VALUE_P = 701, - VALUES = 702, - VARCHAR = 703, - VARIADIC = 704, - VARYING = 705, - VERBOSE = 706, - VERSION_P = 707, - VIEW = 708, - VIEWS = 709, - VIRTUAL = 710, - VOLATILE = 711, - WHEN = 712, - WHERE = 713, - WHITESPACE_P = 714, - WINDOW = 715, - WITH = 716, - WITHIN = 717, - WITHOUT = 718, - WORK = 719, - WRAPPER = 720, - WRITE_P = 721, - XML_P = 722, - XMLATTRIBUTES = 723, - XMLCONCAT = 724, - XMLELEMENT = 725, - XMLEXISTS = 726, - XMLFOREST = 727, - XMLNAMESPACES = 728, - XMLPARSE = 729, - XMLPI = 730, - XMLROOT = 731, - XMLSERIALIZE = 732, - XMLTABLE = 733, - YEAR_P = 734, - YEARS_P = 735, - YES_P = 736, - ZONE = 737, - NOT_LA = 738, - NULLS_LA = 739, - WITH_LA = 740, - POSTFIXOP = 741, - UMINUS = 742 + POSITIONAL = 569, + PRAGMA_P = 570, + PRECEDING = 571, + PRECISION = 572, + PREPARE = 573, + PREPARED = 574, + PRESERVE = 575, + PRIMARY = 576, + PRIOR = 577, + PRIVILEGES = 578, + PROCEDURAL = 579, + PROCEDURE = 580, + PROGRAM = 581, + PUBLICATION = 582, + QUALIFY = 583, + QUOTE = 584, + RANGE = 585, + READ_P = 586, + REAL = 587, + REASSIGN = 588, + RECHECK = 589, + RECURSIVE = 590, + REF = 591, + REFERENCES = 592, + REFERENCING = 593, + REFRESH = 594, + REINDEX = 595, + RELATIVE_P = 596, + RELEASE = 597, + RENAME = 598, + REPEATABLE = 599, + REPLACE = 600, + REPLICA = 601, + RESET = 602, + RESPECT_P = 603, + RESTART = 604, + RESTRICT = 605, + RETURNING = 606, + RETURNS = 607, + REVOKE = 608, + RIGHT = 609, + ROLE = 610, + ROLLBACK = 611, + ROLLUP = 612, + ROW = 613, + ROWS = 614, + RULE = 615, + SAMPLE = 616, + SAVEPOINT = 617, + SCHEMA = 618, + SCHEMAS = 619, + SCROLL = 620, + SEARCH = 621, + SECOND_P = 622, + SECONDS_P = 623, + SECURITY = 624, + SELECT = 625, + SEQUENCE = 626, + SEQUENCES = 627, + SERIALIZABLE = 628, + SERVER = 629, + SESSION = 630, + SESSION_USER = 631, + SET = 632, + SETOF = 633, + SETS = 634, + SHARE = 635, + SHOW = 636, + SIMILAR = 637, + SIMPLE = 638, + SKIP = 639, + SMALLINT = 640, + SNAPSHOT = 641, + SOME = 642, + SQL_P = 643, + STABLE = 644, + STANDALONE_P = 645, + START = 646, + STATEMENT = 647, + STATISTICS = 648, + STDIN = 649, + STDOUT = 650, + STORAGE = 651, + STORED = 652, + STRICT_P = 653, + STRIP_P = 654, + STRUCT = 655, + SUBSCRIPTION = 656, + SUBSTRING = 657, + SUMMARIZE = 658, + SYMMETRIC = 659, + SYSID = 660, + SYSTEM_P = 661, + TABLE = 662, + TABLES = 663, + TABLESAMPLE = 664, + TABLESPACE = 665, + TEMP = 666, + TEMPLATE = 667, + TEMPORARY = 668, + TEXT_P = 669, + THEN = 670, + TIME = 671, + TIMESTAMP = 672, + TO = 673, + TRAILING = 674, + TRANSACTION = 675, + TRANSFORM = 676, + TREAT = 677, + TRIGGER = 678, + TRIM = 679, + TRUE_P = 680, + TRUNCATE = 681, + TRUSTED = 682, + TRY_CAST = 683, + TYPE_P = 684, + TYPES_P = 685, + UNBOUNDED = 686, + UNCOMMITTED = 687, + UNENCRYPTED = 688, + UNION = 689, + UNIQUE = 690, + UNKNOWN = 691, + UNLISTEN = 692, + UNLOGGED = 693, + UNTIL = 694, + UPDATE = 695, + USE_P = 696, + USER = 697, + USING = 698, + VACUUM = 699, + VALID = 700, + VALIDATE = 701, + VALIDATOR = 702, + VALUE_P = 703, + VALUES = 704, + VARCHAR = 705, + VARIADIC = 706, + VARYING = 707, + VERBOSE = 708, + VERSION_P = 709, + VIEW = 710, + VIEWS = 711, + VIRTUAL = 712, + VOLATILE = 713, + WHEN = 714, + WHERE = 715, + WHITESPACE_P = 716, + WINDOW = 717, + WITH = 718, + WITHIN = 719, + WITHOUT = 720, + WORK = 721, + WRAPPER = 722, + WRITE_P = 723, + XML_P = 724, + XMLATTRIBUTES = 725, + XMLCONCAT = 726, + XMLELEMENT = 727, + XMLEXISTS = 728, + XMLFOREST = 729, + XMLNAMESPACES = 730, + XMLPARSE = 731, + XMLPI = 732, + XMLROOT = 733, + XMLSERIALIZE = 734, + XMLTABLE = 735, + YEAR_P = 736, + YEARS_P = 737, + YES_P = 738, + ZONE = 739, + NOT_LA = 740, + NULLS_LA = 741, + WITH_LA = 742, + POSTFIXOP = 743, + UMINUS = 744 }; #endif /* Tokens. */ @@ -294234,180 +307999,182 @@ namespace duckdb_libpgquery { #define PLANS 566 #define POLICY 567 #define POSITION 568 -#define PRAGMA_P 569 -#define PRECEDING 570 -#define PRECISION 571 -#define PREPARE 572 -#define PREPARED 573 -#define PRESERVE 574 -#define PRIMARY 575 -#define PRIOR 576 -#define PRIVILEGES 577 -#define PROCEDURAL 578 -#define PROCEDURE 579 -#define PROGRAM 580 -#define PUBLICATION 581 -#define QUALIFY 582 -#define QUOTE 583 -#define RANGE 584 -#define READ_P 585 -#define REAL 586 -#define REASSIGN 587 -#define RECHECK 588 -#define RECURSIVE 589 -#define REF 590 -#define REFERENCES 591 -#define REFERENCING 592 -#define REFRESH 593 -#define REINDEX 594 -#define RELATIVE_P 595 -#define RELEASE 596 -#define RENAME 597 -#define REPEATABLE 598 -#define REPLACE 599 -#define REPLICA 600 -#define RESET 601 -#define RESPECT_P 602 -#define RESTART 603 -#define RESTRICT 604 -#define RETURNING 605 -#define RETURNS 606 -#define REVOKE 607 -#define RIGHT 608 -#define ROLE 609 -#define ROLLBACK 610 -#define ROLLUP 611 -#define ROW 612 -#define ROWS 613 -#define RULE 614 -#define SAMPLE 615 -#define SAVEPOINT 616 -#define SCHEMA 617 -#define SCHEMAS 618 -#define SCROLL 619 -#define SEARCH 620 -#define SECOND_P 621 -#define SECONDS_P 622 -#define SECURITY 623 -#define SELECT 624 -#define SEQUENCE 625 -#define SEQUENCES 626 -#define SERIALIZABLE 627 -#define SERVER 628 -#define SESSION 629 -#define SESSION_USER 630 -#define SET 631 -#define SETOF 632 -#define SETS 633 -#define SHARE 634 -#define SHOW 635 -#define SIMILAR 636 -#define SIMPLE 637 -#define SKIP 638 -#define SMALLINT 639 -#define SNAPSHOT 640 -#define SOME 641 -#define SQL_P 642 -#define STABLE 643 -#define STANDALONE_P 644 -#define START 645 -#define STATEMENT 646 -#define STATISTICS 647 -#define STDIN 648 -#define STDOUT 649 -#define STORAGE 650 -#define STORED 651 -#define STRICT_P 652 -#define STRIP_P 653 -#define STRUCT 654 -#define SUBSCRIPTION 655 -#define SUBSTRING 656 -#define SUMMARIZE 657 -#define SYMMETRIC 658 -#define SYSID 659 -#define SYSTEM_P 660 -#define TABLE 661 -#define TABLES 662 -#define TABLESAMPLE 663 -#define TABLESPACE 664 -#define TEMP 665 -#define TEMPLATE 666 -#define TEMPORARY 667 -#define TEXT_P 668 -#define THEN 669 -#define TIME 670 -#define TIMESTAMP 671 -#define TO 672 -#define TRAILING 673 -#define TRANSACTION 674 -#define TRANSFORM 675 -#define TREAT 676 -#define TRIGGER 677 -#define TRIM 678 -#define TRUE_P 679 -#define TRUNCATE 680 -#define TRUSTED 681 -#define TRY_CAST 682 -#define TYPE_P 683 -#define TYPES_P 684 -#define UNBOUNDED 685 -#define UNCOMMITTED 686 -#define UNENCRYPTED 687 -#define UNION 688 -#define UNIQUE 689 -#define UNKNOWN 690 -#define UNLISTEN 691 -#define UNLOGGED 692 -#define UNTIL 693 -#define UPDATE 694 -#define USER 695 -#define USING 696 -#define VACUUM 697 -#define VALID 698 -#define VALIDATE 699 -#define VALIDATOR 700 -#define VALUE_P 701 -#define VALUES 702 -#define VARCHAR 703 -#define VARIADIC 704 -#define VARYING 705 -#define VERBOSE 706 -#define VERSION_P 707 -#define VIEW 708 -#define VIEWS 709 -#define VIRTUAL 710 -#define VOLATILE 711 -#define WHEN 712 -#define WHERE 713 -#define WHITESPACE_P 714 -#define WINDOW 715 -#define WITH 716 -#define WITHIN 717 -#define WITHOUT 718 -#define WORK 719 -#define WRAPPER 720 -#define WRITE_P 721 -#define XML_P 722 -#define XMLATTRIBUTES 723 -#define XMLCONCAT 724 -#define XMLELEMENT 725 -#define XMLEXISTS 726 -#define XMLFOREST 727 -#define XMLNAMESPACES 728 -#define XMLPARSE 729 -#define XMLPI 730 -#define XMLROOT 731 -#define XMLSERIALIZE 732 -#define XMLTABLE 733 -#define YEAR_P 734 -#define YEARS_P 735 -#define YES_P 736 -#define ZONE 737 -#define NOT_LA 738 -#define NULLS_LA 739 -#define WITH_LA 740 -#define POSTFIXOP 741 -#define UMINUS 742 +#define POSITIONAL 569 +#define PRAGMA_P 570 +#define PRECEDING 571 +#define PRECISION 572 +#define PREPARE 573 +#define PREPARED 574 +#define PRESERVE 575 +#define PRIMARY 576 +#define PRIOR 577 +#define PRIVILEGES 578 +#define PROCEDURAL 579 +#define PROCEDURE 580 +#define PROGRAM 581 +#define PUBLICATION 582 +#define QUALIFY 583 +#define QUOTE 584 +#define RANGE 585 +#define READ_P 586 +#define REAL 587 +#define REASSIGN 588 +#define RECHECK 589 +#define RECURSIVE 590 +#define REF 591 +#define REFERENCES 592 +#define REFERENCING 593 +#define REFRESH 594 +#define REINDEX 595 +#define RELATIVE_P 596 +#define RELEASE 597 +#define RENAME 598 +#define REPEATABLE 599 +#define REPLACE 600 +#define REPLICA 601 +#define RESET 602 +#define RESPECT_P 603 +#define RESTART 604 +#define RESTRICT 605 +#define RETURNING 606 +#define RETURNS 607 +#define REVOKE 608 +#define RIGHT 609 +#define ROLE 610 +#define ROLLBACK 611 +#define ROLLUP 612 +#define ROW 613 +#define ROWS 614 +#define RULE 615 +#define SAMPLE 616 +#define SAVEPOINT 617 +#define SCHEMA 618 +#define SCHEMAS 619 +#define SCROLL 620 +#define SEARCH 621 +#define SECOND_P 622 +#define SECONDS_P 623 +#define SECURITY 624 +#define SELECT 625 +#define SEQUENCE 626 +#define SEQUENCES 627 +#define SERIALIZABLE 628 +#define SERVER 629 +#define SESSION 630 +#define SESSION_USER 631 +#define SET 632 +#define SETOF 633 +#define SETS 634 +#define SHARE 635 +#define SHOW 636 +#define SIMILAR 637 +#define SIMPLE 638 +#define SKIP 639 +#define SMALLINT 640 +#define SNAPSHOT 641 +#define SOME 642 +#define SQL_P 643 +#define STABLE 644 +#define STANDALONE_P 645 +#define START 646 +#define STATEMENT 647 +#define STATISTICS 648 +#define STDIN 649 +#define STDOUT 650 +#define STORAGE 651 +#define STORED 652 +#define STRICT_P 653 +#define STRIP_P 654 +#define STRUCT 655 +#define SUBSCRIPTION 656 +#define SUBSTRING 657 +#define SUMMARIZE 658 +#define SYMMETRIC 659 +#define SYSID 660 +#define SYSTEM_P 661 +#define TABLE 662 +#define TABLES 663 +#define TABLESAMPLE 664 +#define TABLESPACE 665 +#define TEMP 666 +#define TEMPLATE 667 +#define TEMPORARY 668 +#define TEXT_P 669 +#define THEN 670 +#define TIME 671 +#define TIMESTAMP 672 +#define TO 673 +#define TRAILING 674 +#define TRANSACTION 675 +#define TRANSFORM 676 +#define TREAT 677 +#define TRIGGER 678 +#define TRIM 679 +#define TRUE_P 680 +#define TRUNCATE 681 +#define TRUSTED 682 +#define TRY_CAST 683 +#define TYPE_P 684 +#define TYPES_P 685 +#define UNBOUNDED 686 +#define UNCOMMITTED 687 +#define UNENCRYPTED 688 +#define UNION 689 +#define UNIQUE 690 +#define UNKNOWN 691 +#define UNLISTEN 692 +#define UNLOGGED 693 +#define UNTIL 694 +#define UPDATE 695 +#define USE_P 696 +#define USER 697 +#define USING 698 +#define VACUUM 699 +#define VALID 700 +#define VALIDATE 701 +#define VALIDATOR 702 +#define VALUE_P 703 +#define VALUES 704 +#define VARCHAR 705 +#define VARIADIC 706 +#define VARYING 707 +#define VERBOSE 708 +#define VERSION_P 709 +#define VIEW 710 +#define VIEWS 711 +#define VIRTUAL 712 +#define VOLATILE 713 +#define WHEN 714 +#define WHERE 715 +#define WHITESPACE_P 716 +#define WINDOW 717 +#define WITH 718 +#define WITHIN 719 +#define WITHOUT 720 +#define WORK 721 +#define WRAPPER 722 +#define WRITE_P 723 +#define XML_P 724 +#define XMLATTRIBUTES 725 +#define XMLCONCAT 726 +#define XMLELEMENT 727 +#define XMLEXISTS 728 +#define XMLFOREST 729 +#define XMLNAMESPACES 730 +#define XMLPARSE 731 +#define XMLPI 732 +#define XMLROOT 733 +#define XMLSERIALIZE 734 +#define XMLTABLE 735 +#define YEAR_P 736 +#define YEARS_P 737 +#define YES_P 738 +#define ZONE 739 +#define NOT_LA 740 +#define NULLS_LA 741 +#define WITH_LA 742 +#define POSTFIXOP 743 +#define UMINUS 744 @@ -294446,6 +308213,7 @@ typedef union YYSTYPE PGWithClause *with; PGInferClause *infer; PGOnConflictClause *onconflict; + PGOnConflictActionAlias onconflictshorthand; PGAIndices *aind; PGResTarget *target; PGInsertStmt *istmt; @@ -294460,7 +308228,7 @@ typedef union YYSTYPE PGViewCheckOption viewcheckoption; } /* Line 1529 of yacc.c. */ -#line 1068 "third_party/libpg_query/grammar/grammar_out.hpp" +#line 1073 "third_party/libpg_query/grammar/grammar_out.hpp" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 @@ -294877,6 +308645,7 @@ static PGNode *makeNullAConst(int location); static PGNode *makeAConst(PGValue *v, int location); static PGNode *makeBoolAConst(bool state, int location); static PGNode *makeParamRef(int number, int location); +static PGNode *makeNamedParamRef(char* name, int location); static void check_qualified_name(PGList *names, core_yyscan_t yyscanner); static PGList *check_func_name(PGList *names, core_yyscan_t yyscanner); static PGList *check_indirection(PGList *indirection, core_yyscan_t yyscanner); @@ -294956,6 +308725,7 @@ typedef union YYSTYPE PGWithClause *with; PGInferClause *infer; PGOnConflictClause *onconflict; + PGOnConflictActionAlias onconflictshorthand; PGAIndices *aind; PGResTarget *target; PGInsertStmt *istmt; @@ -294970,7 +308740,7 @@ typedef union YYSTYPE PGViewCheckOption viewcheckoption; } /* Line 193 of yacc.c. */ -#line 1289 "third_party/libpg_query/grammar/grammar_out.cpp" +#line 1295 "third_party/libpg_query/grammar/grammar_out.cpp" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 @@ -294995,7 +308765,7 @@ typedef struct YYLTYPE /* Line 216 of yacc.c. */ -#line 1314 "third_party/libpg_query/grammar/grammar_out.cpp" +#line 1320 "third_party/libpg_query/grammar/grammar_out.cpp" #ifdef short # undef short @@ -295210,22 +308980,22 @@ union yyalloc #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 671 +#define YYFINAL 694 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 59356 +#define YYLAST 61781 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 509 +#define YYNTOKENS 512 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 401 +#define YYNNTS 414 /* YYNRULES -- Number of rules. */ -#define YYNRULES 1944 +#define YYNRULES 1987 /* YYNRULES -- Number of states. */ -#define YYNSTATES 3186 +#define YYNSTATES 3267 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 742 +#define YYMAXUTOK 744 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -295236,16 +309006,16 @@ static const yytype_uint16 yytranslate[] = 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 504, 2, 494, 2, 2, - 499, 500, 492, 490, 503, 491, 501, 493, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 508, 502, - 486, 488, 487, 505, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 506, 507, 496, 2, 2, + 501, 502, 494, 492, 505, 493, 503, 495, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 511, 504, + 488, 490, 489, 508, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 497, 2, 498, 495, 2, 2, 2, 2, 2, + 2, 499, 2, 500, 497, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 506, 2, 507, 2, 2, 2, 2, + 2, 2, 2, 509, 2, 510, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -295307,7 +309077,7 @@ static const yytype_uint16 yytranslate[] = 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, - 485, 489, 496 + 485, 486, 487, 491, 498 }; #if YYDEBUG @@ -295319,740 +309089,759 @@ static const yytype_uint16 yyprhs[] = 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, - 80, 85, 92, 97, 104, 109, 116, 121, 128, 130, - 133, 137, 140, 142, 146, 149, 153, 155, 159, 162, - 168, 172, 179, 184, 191, 198, 205, 211, 217, 224, - 234, 239, 245, 253, 260, 265, 274, 279, 282, 287, - 291, 298, 303, 306, 309, 312, 315, 317, 320, 321, - 323, 326, 329, 332, 334, 338, 343, 346, 348, 349, - 352, 356, 359, 363, 370, 377, 386, 393, 402, 409, - 418, 425, 434, 443, 454, 463, 474, 476, 477, 485, - 487, 492, 497, 505, 508, 510, 514, 519, 523, 524, - 526, 527, 530, 534, 540, 549, 555, 556, 562, 568, - 576, 579, 580, 582, 584, 586, 590, 593, 594, 596, - 597, 599, 603, 605, 609, 611, 614, 616, 620, 623, - 630, 639, 645, 647, 648, 650, 654, 657, 662, 668, - 674, 683, 685, 686, 690, 700, 713, 717, 718, 723, - 730, 732, 735, 737, 739, 740, 742, 745, 748, 750, - 753, 756, 758, 761, 765, 768, 771, 774, 777, 781, - 785, 789, 791, 795, 797, 798, 800, 803, 806, 809, - 812, 815, 818, 821, 824, 826, 828, 829, 839, 852, - 864, 865, 868, 870, 872, 874, 876, 878, 880, 884, - 885, 887, 890, 892, 894, 897, 900, 904, 906, 908, - 911, 914, 916, 919, 923, 929, 933, 936, 942, 944, - 946, 948, 949, 955, 963, 969, 972, 976, 978, 980, - 983, 986, 987, 991, 996, 1001, 1002, 1006, 1009, 1010, - 1014, 1016, 1018, 1020, 1022, 1024, 1026, 1028, 1030, 1032, - 1034, 1038, 1042, 1044, 1047, 1050, 1053, 1056, 1059, 1062, - 1063, 1067, 1071, 1075, 1076, 1078, 1081, 1083, 1086, 1089, - 1092, 1095, 1099, 1104, 1106, 1110, 1112, 1114, 1116, 1118, - 1122, 1124, 1127, 1128, 1130, 1133, 1134, 1136, 1140, 1141, - 1144, 1145, 1149, 1153, 1155, 1161, 1165, 1167, 1171, 1173, - 1176, 1178, 1183, 1189, 1195, 1202, 1206, 1214, 1219, 1231, - 1233, 1237, 1240, 1243, 1246, 1247, 1251, 1253, 1255, 1258, - 1261, 1264, 1267, 1269, 1270, 1272, 1275, 1282, 1287, 1294, - 1299, 1306, 1315, 1320, 1327, 1329, 1331, 1333, 1335, 1338, - 1340, 1343, 1345, 1348, 1350, 1352, 1354, 1358, 1362, 1366, - 1370, 1373, 1376, 1378, 1382, 1384, 1386, 1388, 1390, 1394, - 1396, 1398, 1399, 1401, 1403, 1405, 1407, 1411, 1420, 1432, - 1443, 1451, 1462, 1472, 1474, 1476, 1479, 1483, 1492, 1504, - 1514, 1516, 1518, 1522, 1523, 1525, 1529, 1531, 1532, 1534, - 1535, 1537, 1538, 1540, 1544, 1546, 1548, 1550, 1554, 1555, - 1558, 1561, 1562, 1565, 1566, 1568, 1569, 1571, 1573, 1575, - 1579, 1583, 1585, 1587, 1591, 1595, 1599, 1603, 1608, 1612, - 1615, 1617, 1619, 1621, 1623, 1625, 1629, 1631, 1633, 1637, - 1641, 1643, 1646, 1651, 1656, 1659, 1663, 1669, 1675, 1677, - 1679, 1683, 1684, 1696, 1708, 1719, 1732, 1734, 1737, 1743, - 1748, 1753, 1758, 1761, 1764, 1768, 1770, 1774, 1781, 1784, - 1785, 1789, 1793, 1798, 1803, 1808, 1813, 1817, 1820, 1822, - 1824, 1825, 1827, 1829, 1830, 1833, 1835, 1841, 1843, 1844, - 1847, 1850, 1851, 1853, 1854, 1858, 1864, 1870, 1872, 1876, - 1881, 1885, 1887, 1889, 1890, 1893, 1896, 1897, 1900, 1903, - 1905, 1907, 1909, 1910, 1913, 1918, 1924, 1929, 1932, 1936, - 1939, 1942, 1945, 1948, 1950, 1953, 1957, 1958, 1960, 1961, - 1967, 1969, 1974, 1981, 1984, 1986, 1987, 1992, 1993, 1995, - 1997, 2000, 2003, 2006, 2008, 2010, 2013, 2016, 2018, 2020, - 2022, 2024, 2026, 2028, 2032, 2036, 2040, 2041, 2043, 2047, - 2049, 2052, 2054, 2056, 2058, 2060, 2062, 2065, 2070, 2075, - 2081, 2083, 2085, 2088, 2089, 2092, 2093, 2095, 2099, 2101, - 2102, 2104, 2107, 2111, 2114, 2119, 2122, 2126, 2129, 2130, - 2132, 2135, 2136, 2141, 2147, 2149, 2152, 2155, 2156, 2158, - 2162, 2164, 2167, 2171, 2175, 2179, 2183, 2187, 2191, 2193, - 2198, 2202, 2207, 2213, 2218, 2224, 2229, 2235, 2238, 2243, - 2245, 2247, 2248, 2250, 2255, 2261, 2266, 2267, 2270, 2273, - 2276, 2278, 2280, 2281, 2286, 2289, 2291, 2294, 2297, 2302, - 2305, 2312, 2315, 2317, 2321, 2326, 2327, 2330, 2331, 2334, - 2335, 2337, 2341, 2345, 2348, 2349, 2352, 2357, 2359, 2361, - 2363, 2364, 2367, 2371, 2377, 2384, 2387, 2391, 2397, 2403, - 2409, 2413, 2418, 2419, 2421, 2423, 2425, 2427, 2429, 2432, - 2437, 2439, 2441, 2443, 2445, 2448, 2452, 2453, 2455, 2457, - 2459, 2461, 2463, 2466, 2469, 2472, 2475, 2478, 2480, 2484, - 2485, 2487, 2489, 2491, 2493, 2499, 2502, 2504, 2506, 2508, - 2510, 2515, 2517, 2520, 2523, 2525, 2529, 2533, 2536, 2538, - 2539, 2545, 2548, 2554, 2557, 2559, 2563, 2567, 2568, 2570, - 2572, 2574, 2576, 2578, 2580, 2582, 2584, 2586, 2588, 2590, - 2592, 2594, 2596, 2598, 2600, 2602, 2604, 2606, 2608, 2610, - 2612, 2614, 2616, 2620, 2624, 2628, 2632, 2636, 2640, 2644, - 2645, 2647, 2651, 2655, 2661, 2664, 2667, 2671, 2675, 2679, - 2683, 2687, 2691, 2695, 2699, 2703, 2707, 2711, 2715, 2719, - 2723, 2726, 2729, 2733, 2737, 2740, 2743, 2747, 2751, 2757, - 2762, 2769, 2773, 2779, 2784, 2791, 2796, 2803, 2809, 2817, - 2821, 2824, 2829, 2833, 2836, 2840, 2844, 2848, 2852, 2857, - 2861, 2866, 2870, 2875, 2881, 2888, 2895, 2903, 2910, 2918, - 2925, 2933, 2937, 2942, 2947, 2954, 2956, 2963, 2968, 2970, - 2974, 2977, 2980, 2984, 2988, 2992, 2996, 3000, 3004, 3008, - 3012, 3016, 3020, 3024, 3028, 3032, 3036, 3039, 3042, 3048, - 3055, 3062, 3070, 3072, 3074, 3077, 3080, 3083, 3088, 3090, - 3094, 3098, 3100, 3103, 3108, 3110, 3113, 3115, 3118, 3121, - 3126, 3130, 3137, 3145, 3155, 3163, 3171, 3176, 3182, 3184, - 3186, 3188, 3194, 3196, 3198, 3203, 3205, 3210, 3212, 3217, - 3219, 3224, 3226, 3228, 3230, 3232, 3234, 3236, 3243, 3250, - 3255, 3260, 3265, 3270, 3277, 3283, 3289, 3295, 3300, 3307, - 3312, 3320, 3330, 3336, 3337, 3343, 3348, 3349, 3351, 3352, - 3355, 3356, 3358, 3362, 3366, 3369, 3372, 3373, 3380, 3382, - 3383, 3387, 3388, 3391, 3394, 3395, 3397, 3402, 3405, 3408, - 3411, 3414, 3417, 3422, 3426, 3428, 3434, 3438, 3440, 3444, - 3446, 3449, 3451, 3453, 3455, 3457, 3459, 3461, 3463, 3465, - 3467, 3469, 3471, 3473, 3475, 3477, 3479, 3481, 3483, 3485, - 3487, 3492, 3494, 3499, 3501, 3506, 3508, 3511, 3513, 3516, - 3518, 3521, 3523, 3527, 3529, 3533, 3535, 3538, 3540, 3541, - 3543, 3547, 3549, 3553, 3557, 3559, 3563, 3567, 3568, 3570, - 3572, 3574, 3576, 3578, 3580, 3582, 3584, 3586, 3588, 3593, - 3597, 3600, 3604, 3605, 3609, 3613, 3616, 3619, 3621, 3622, - 3625, 3628, 3632, 3635, 3637, 3639, 3643, 3649, 3651, 3654, - 3659, 3662, 3663, 3665, 3666, 3668, 3671, 3674, 3678, 3684, - 3686, 3687, 3689, 3692, 3693, 3696, 3698, 3699, 3701, 3702, - 3704, 3708, 3710, 3713, 3717, 3720, 3722, 3726, 3732, 3737, - 3740, 3742, 3743, 3747, 3749, 3753, 3755, 3758, 3763, 3766, - 3767, 3769, 3773, 3775, 3778, 3780, 3784, 3786, 3789, 3791, - 3793, 3795, 3798, 3800, 3802, 3805, 3807, 3809, 3812, 3820, - 3823, 3829, 3833, 3837, 3839, 3841, 3843, 3845, 3847, 3849, - 3851, 3853, 3855, 3857, 3859, 3861, 3863, 3865, 3867, 3869, - 3871, 3873, 3875, 3877, 3880, 3883, 3887, 3891, 3892, 3894, - 3896, 3898, 3900, 3902, 3904, 3906, 3912, 3916, 3917, 3919, - 3921, 3923, 3925, 3930, 3938, 3941, 3942, 3944, 3946, 3948, - 3950, 3964, 3981, 3983, 3986, 3987, 3989, 3990, 3992, 3993, - 3996, 3997, 3999, 4000, 4007, 4016, 4023, 4032, 4039, 4048, - 4051, 4053, 4058, 4062, 4065, 4070, 4074, 4080, 4082, 4083, - 4085, 4087, 4088, 4090, 4092, 4094, 4096, 4098, 4100, 4102, - 4104, 4106, 4108, 4110, 4112, 4114, 4116, 4118, 4120, 4122, - 4124, 4126, 4128, 4130, 4132, 4134, 4136, 4138, 4140, 4142, - 4144, 4146, 4148, 4150, 4152, 4154, 4156, 4158, 4160, 4164, - 4166, 4168, 4170, 4172, 4174, 4176, 4179, 4181, 4183, 4186, - 4190, 4194, 4198, 4200, 4204, 4208, 4211, 4215, 4219, 4223, - 4227, 4229, 4231, 4233, 4235, 4239, 4245, 4247, 4249, 4251, - 4253, 4257, 4260, 4263, 4267, 4269, 4271, 4276, 4282, 4288, - 4293, 4300, 4302, 4304, 4306, 4308, 4310, 4312, 4313, 4315, - 4319, 4321, 4322, 4330, 4334, 4336, 4339, 4343, 4346, 4347, - 4350, 4351, 4354, 4359, 4362, 4364, 4366, 4368, 4371, 4375, - 4378, 4381, 4384, 4387, 4391, 4396, 4399, 4401, 4403, 4405, - 4407, 4411, 4413, 4417, 4420, 4430, 4442, 4455, 4470, 4474, - 4479, 4484, 4485, 4493, 4504, 4514, 4517, 4521, 4522, 4527, - 4529, 4531, 4533, 4535, 4537, 4539, 4541, 4543, 4545, 4547, - 4549, 4551, 4553, 4555, 4557, 4559, 4561, 4563, 4565, 4567, - 4569, 4571, 4573, 4575, 4577, 4579, 4581, 4583, 4585, 4587, - 4589, 4591, 4593, 4595, 4597, 4599, 4601, 4603, 4605, 4607, - 4609, 4611, 4613, 4615, 4617, 4619, 4621, 4623, 4625, 4627, - 4629, 4631, 4633, 4635, 4637, 4639, 4641, 4643, 4645, 4647, - 4649, 4651, 4653, 4655, 4657, 4659, 4661, 4663, 4665, 4667, - 4669, 4671, 4673, 4675, 4677, 4679, 4681, 4683, 4685, 4687, - 4689, 4691, 4693, 4695, 4697, 4699, 4701, 4703, 4705, 4707, - 4709, 4711, 4713, 4715, 4717, 4719, 4721, 4723, 4725, 4727, - 4729, 4731, 4733, 4735, 4737, 4739, 4741, 4743, 4745, 4747, - 4749, 4751, 4753, 4755, 4757, 4759, 4761, 4763, 4765, 4767, - 4769, 4771, 4773, 4775, 4777, 4779, 4781, 4783, 4785, 4787, - 4789, 4791, 4793, 4795, 4797, 4799, 4801, 4803, 4805, 4807, - 4809, 4811, 4813, 4815, 4817, 4819, 4821, 4823, 4825, 4827, - 4829, 4831, 4833, 4835, 4837, 4839, 4841, 4843, 4845, 4847, - 4849, 4851, 4853, 4855, 4857, 4859, 4861, 4863, 4865, 4867, - 4869, 4871, 4873, 4875, 4877, 4879, 4881, 4883, 4885, 4887, - 4889, 4891, 4893, 4895, 4897, 4899, 4901, 4903, 4905, 4907, - 4909, 4911, 4913, 4915, 4917, 4919, 4921, 4923, 4925, 4927, - 4929, 4931, 4933, 4935, 4937, 4939, 4941, 4943, 4945, 4947, - 4949, 4951, 4953, 4955, 4957, 4959, 4961, 4963, 4965, 4967, - 4969, 4971, 4973, 4975, 4977, 4979, 4981, 4983, 4985, 4987, - 4989, 4991, 4993, 4995, 4997, 4999, 5001, 5003, 5005, 5007, - 5009, 5011, 5013, 5015, 5017, 5019, 5021, 5023, 5025, 5027, - 5029, 5031, 5033, 5035, 5037, 5039, 5041, 5043, 5045, 5047, - 5049, 5051, 5053, 5055, 5057, 5059, 5061, 5063, 5065, 5067, - 5069, 5071, 5073, 5075, 5077, 5079, 5081, 5083, 5085, 5087, - 5089, 5091, 5093, 5095, 5097, 5099, 5101, 5103, 5105, 5107, - 5109, 5111, 5113, 5115, 5117, 5119, 5121, 5123, 5125, 5127, - 5129, 5131, 5133, 5135, 5137, 5139, 5141, 5143, 5145, 5147, - 5149, 5151, 5153, 5155, 5157, 5159, 5161, 5163, 5165, 5167, - 5169, 5171, 5173, 5175, 5177, 5179, 5181, 5183, 5185, 5187, - 5189, 5191, 5193, 5195, 5197, 5199, 5201, 5203, 5205, 5207, - 5209, 5211, 5213, 5215, 5217, 5219, 5221, 5223, 5225, 5227, - 5229, 5231, 5233, 5235, 5237, 5239, 5241, 5243, 5245, 5247, - 5249, 5251, 5253, 5255, 5257, 5259, 5261, 5263, 5265, 5267, - 5269, 5271, 5273, 5275, 5277, 5279, 5281, 5283, 5285, 5287, - 5289, 5291, 5293, 5295, 5297, 5299, 5301, 5303, 5305, 5307, - 5309, 5311, 5313, 5315, 5317, 5319, 5321, 5323, 5325, 5327, - 5329, 5331, 5333, 5335, 5337, 5339, 5341, 5343, 5345, 5347, - 5349, 5351, 5353, 5355, 5357, 5359, 5361, 5363, 5365, 5367, - 5369, 5371, 5373, 5375, 5377, 5379, 5381, 5383, 5385, 5387, - 5389, 5391, 5393, 5395, 5397, 5399, 5401, 5403, 5405, 5407, - 5409, 5411, 5413, 5415, 5417, 5419, 5421, 5423, 5425, 5427, - 5429, 5431, 5433, 5435, 5437, 5439, 5441, 5443, 5445, 5447, - 5449, 5451, 5453, 5455, 5457, 5459, 5461, 5463, 5465, 5467, - 5469, 5471, 5473, 5475, 5477, 5479, 5481, 5483, 5485, 5487, - 5489, 5491, 5493, 5495, 5497, 5499, 5501, 5503, 5505, 5507, - 5509, 5511, 5513, 5515, 5517, 5519, 5521, 5523, 5525, 5527, - 5529, 5531, 5533, 5535, 5537, 5539, 5541, 5543, 5545, 5547, - 5549, 5551, 5553, 5555, 5557, 5559, 5561, 5563, 5565, 5567, - 5569, 5571, 5573, 5575, 5577, 5579, 5581, 5583, 5585, 5587, - 5589, 5591, 5593, 5595, 5597, 5599, 5601, 5603, 5605, 5607, - 5609, 5611, 5613, 5615, 5617, 5619, 5621, 5623, 5625, 5627, - 5629, 5631, 5633, 5635, 5637, 5639, 5641, 5643, 5645, 5647, - 5649, 5651, 5653, 5655, 5657, 5659, 5661, 5663, 5665, 5667, - 5669, 5671, 5673, 5675, 5677, 5679, 5681, 5683, 5685, 5687, - 5689, 5691, 5693, 5695, 5697, 5699, 5701, 5703, 5705, 5707, - 5709, 5711, 5713, 5715, 5717, 5719, 5721, 5723, 5725, 5727, - 5729, 5731, 5733, 5735, 5737, 5739, 5741, 5743, 5745, 5747, - 5749, 5751, 5753, 5755, 5757 + 81, 83, 85, 87, 88, 93, 100, 105, 112, 117, + 124, 129, 136, 138, 141, 145, 148, 150, 154, 157, + 161, 163, 167, 170, 176, 180, 187, 192, 199, 206, + 213, 219, 225, 232, 242, 247, 253, 261, 268, 273, + 282, 287, 290, 295, 299, 306, 311, 314, 317, 320, + 323, 325, 328, 329, 331, 334, 337, 340, 342, 346, + 351, 354, 356, 357, 360, 364, 367, 371, 378, 385, + 394, 401, 410, 417, 426, 433, 442, 451, 462, 471, + 482, 484, 485, 494, 496, 501, 506, 514, 517, 519, + 523, 528, 532, 533, 535, 536, 539, 543, 549, 552, + 555, 556, 565, 571, 572, 578, 584, 592, 595, 596, + 598, 600, 602, 606, 609, 610, 612, 613, 615, 619, + 621, 625, 627, 630, 632, 636, 639, 646, 655, 661, + 663, 664, 666, 670, 673, 678, 684, 688, 693, 700, + 706, 712, 721, 729, 731, 737, 746, 748, 749, 753, + 763, 776, 780, 781, 786, 793, 795, 798, 800, 802, + 803, 805, 808, 811, 813, 816, 819, 821, 824, 828, + 831, 834, 837, 840, 844, 848, 852, 854, 858, 860, + 861, 863, 866, 869, 872, 875, 878, 881, 884, 887, + 889, 891, 892, 895, 905, 918, 930, 931, 934, 936, + 938, 940, 942, 944, 946, 950, 951, 953, 956, 958, + 960, 963, 966, 970, 972, 974, 977, 980, 982, 985, + 989, 995, 999, 1002, 1008, 1010, 1012, 1014, 1015, 1021, + 1029, 1035, 1038, 1042, 1044, 1046, 1049, 1052, 1053, 1057, + 1062, 1067, 1068, 1072, 1075, 1076, 1080, 1082, 1084, 1086, + 1088, 1090, 1092, 1094, 1096, 1098, 1100, 1104, 1108, 1110, + 1113, 1116, 1119, 1122, 1125, 1128, 1129, 1133, 1137, 1141, + 1142, 1144, 1147, 1149, 1152, 1155, 1158, 1161, 1165, 1170, + 1172, 1176, 1178, 1180, 1182, 1184, 1188, 1190, 1193, 1194, + 1196, 1199, 1200, 1202, 1206, 1207, 1210, 1211, 1215, 1219, + 1221, 1227, 1231, 1233, 1237, 1239, 1242, 1244, 1249, 1255, + 1261, 1268, 1272, 1280, 1285, 1297, 1299, 1303, 1306, 1309, + 1312, 1313, 1317, 1319, 1321, 1324, 1327, 1330, 1333, 1335, + 1336, 1338, 1341, 1348, 1353, 1360, 1365, 1372, 1381, 1386, + 1393, 1395, 1397, 1399, 1401, 1403, 1406, 1408, 1411, 1413, + 1416, 1418, 1420, 1422, 1424, 1428, 1432, 1436, 1440, 1443, + 1446, 1448, 1452, 1454, 1456, 1458, 1462, 1464, 1466, 1467, + 1469, 1471, 1473, 1475, 1479, 1488, 1500, 1511, 1519, 1530, + 1540, 1542, 1544, 1547, 1551, 1560, 1572, 1582, 1584, 1586, + 1590, 1591, 1593, 1597, 1599, 1600, 1602, 1603, 1605, 1606, + 1608, 1612, 1614, 1616, 1618, 1622, 1623, 1626, 1629, 1630, + 1633, 1634, 1636, 1637, 1639, 1641, 1643, 1647, 1651, 1653, + 1655, 1659, 1663, 1667, 1671, 1675, 1679, 1684, 1688, 1691, + 1693, 1695, 1697, 1699, 1701, 1705, 1707, 1709, 1713, 1717, + 1719, 1722, 1727, 1732, 1735, 1739, 1745, 1751, 1753, 1755, + 1759, 1760, 1772, 1784, 1795, 1808, 1810, 1813, 1819, 1824, + 1829, 1834, 1837, 1840, 1844, 1846, 1850, 1857, 1860, 1861, + 1865, 1869, 1874, 1879, 1884, 1889, 1893, 1896, 1898, 1900, + 1901, 1903, 1905, 1906, 1909, 1911, 1917, 1919, 1920, 1923, + 1926, 1927, 1929, 1930, 1934, 1940, 1946, 1948, 1952, 1957, + 1961, 1963, 1965, 1966, 1969, 1972, 1973, 1976, 1979, 1981, + 1983, 1985, 1986, 1989, 1994, 2000, 2005, 2008, 2012, 2015, + 2018, 2021, 2024, 2026, 2029, 2033, 2034, 2036, 2037, 2043, + 2045, 2050, 2057, 2060, 2062, 2063, 2068, 2069, 2071, 2073, + 2076, 2079, 2082, 2084, 2086, 2089, 2092, 2094, 2096, 2098, + 2100, 2102, 2104, 2108, 2112, 2116, 2117, 2119, 2123, 2125, + 2128, 2130, 2132, 2134, 2136, 2138, 2141, 2146, 2151, 2157, + 2159, 2161, 2164, 2165, 2168, 2169, 2171, 2175, 2177, 2178, + 2180, 2183, 2187, 2190, 2195, 2198, 2202, 2205, 2206, 2208, + 2211, 2212, 2217, 2223, 2225, 2228, 2231, 2232, 2234, 2238, + 2240, 2243, 2247, 2251, 2255, 2259, 2263, 2267, 2269, 2274, + 2278, 2283, 2289, 2294, 2300, 2305, 2310, 2316, 2319, 2324, + 2326, 2328, 2329, 2331, 2336, 2342, 2347, 2348, 2351, 2354, + 2357, 2359, 2361, 2362, 2367, 2370, 2372, 2375, 2378, 2383, + 2386, 2393, 2396, 2398, 2402, 2407, 2408, 2411, 2412, 2415, + 2416, 2418, 2422, 2426, 2429, 2430, 2433, 2438, 2440, 2442, + 2444, 2445, 2448, 2452, 2458, 2465, 2468, 2472, 2478, 2484, + 2490, 2494, 2499, 2500, 2502, 2504, 2506, 2508, 2510, 2513, + 2518, 2520, 2522, 2524, 2526, 2529, 2533, 2534, 2536, 2538, + 2540, 2542, 2544, 2547, 2550, 2553, 2556, 2559, 2561, 2565, + 2566, 2568, 2570, 2572, 2574, 2580, 2583, 2585, 2587, 2589, + 2591, 2596, 2598, 2601, 2604, 2606, 2610, 2614, 2617, 2619, + 2620, 2626, 2629, 2635, 2638, 2640, 2644, 2648, 2649, 2651, + 2653, 2655, 2657, 2659, 2661, 2663, 2665, 2667, 2669, 2671, + 2673, 2675, 2677, 2679, 2681, 2683, 2685, 2687, 2689, 2691, + 2693, 2695, 2697, 2701, 2705, 2709, 2713, 2717, 2721, 2725, + 2726, 2728, 2732, 2736, 2742, 2745, 2748, 2752, 2756, 2760, + 2764, 2768, 2772, 2776, 2780, 2784, 2788, 2792, 2796, 2800, + 2804, 2807, 2810, 2814, 2818, 2821, 2824, 2828, 2832, 2838, + 2843, 2850, 2854, 2860, 2865, 2872, 2877, 2884, 2890, 2898, + 2902, 2905, 2910, 2914, 2917, 2921, 2925, 2929, 2933, 2938, + 2942, 2947, 2951, 2956, 2962, 2969, 2976, 2984, 2991, 2999, + 3006, 3014, 3018, 3023, 3028, 3035, 3037, 3044, 3049, 3051, + 3055, 3058, 3061, 3065, 3069, 3073, 3077, 3081, 3085, 3089, + 3093, 3097, 3101, 3105, 3109, 3113, 3117, 3120, 3123, 3129, + 3136, 3143, 3151, 3153, 3155, 3158, 3161, 3164, 3166, 3170, + 3172, 3175, 3180, 3182, 3184, 3187, 3190, 3195, 3197, 3199, + 3203, 3207, 3209, 3213, 3220, 3228, 3238, 3246, 3254, 3259, + 3265, 3267, 3269, 3271, 3277, 3279, 3281, 3286, 3288, 3293, + 3295, 3300, 3302, 3307, 3309, 3311, 3313, 3315, 3317, 3319, + 3326, 3333, 3338, 3343, 3348, 3353, 3360, 3366, 3372, 3378, + 3383, 3390, 3395, 3403, 3413, 3419, 3420, 3426, 3431, 3432, + 3434, 3435, 3438, 3439, 3441, 3445, 3449, 3452, 3455, 3456, + 3463, 3465, 3466, 3470, 3471, 3474, 3477, 3478, 3480, 3485, + 3488, 3491, 3494, 3497, 3500, 3505, 3509, 3511, 3517, 3521, + 3523, 3527, 3529, 3532, 3534, 3536, 3538, 3540, 3542, 3544, + 3546, 3548, 3550, 3552, 3554, 3556, 3558, 3560, 3562, 3564, + 3566, 3568, 3570, 3575, 3577, 3582, 3584, 3589, 3591, 3594, + 3596, 3599, 3601, 3604, 3606, 3610, 3612, 3616, 3618, 3621, + 3623, 3624, 3626, 3630, 3632, 3636, 3640, 3642, 3646, 3650, + 3651, 3653, 3655, 3657, 3659, 3661, 3663, 3665, 3667, 3669, + 3671, 3676, 3680, 3683, 3687, 3688, 3692, 3696, 3699, 3702, + 3704, 3705, 3708, 3711, 3715, 3718, 3720, 3722, 3726, 3732, + 3734, 3737, 3742, 3745, 3746, 3748, 3749, 3751, 3754, 3757, + 3761, 3767, 3769, 3770, 3772, 3775, 3776, 3779, 3781, 3782, + 3784, 3785, 3787, 3791, 3793, 3796, 3800, 3803, 3805, 3809, + 3815, 3820, 3823, 3825, 3826, 3830, 3832, 3836, 3838, 3841, + 3846, 3849, 3850, 3852, 3856, 3858, 3861, 3863, 3867, 3869, + 3872, 3874, 3876, 3878, 3881, 3883, 3885, 3888, 3890, 3892, + 3895, 3903, 3906, 3912, 3916, 3920, 3922, 3924, 3926, 3928, + 3930, 3932, 3934, 3936, 3938, 3940, 3942, 3944, 3946, 3948, + 3950, 3952, 3954, 3956, 3958, 3960, 3963, 3966, 3970, 3974, + 3975, 3977, 3979, 3981, 3983, 3985, 3987, 3989, 3991, 3997, + 4001, 4002, 4004, 4006, 4008, 4010, 4015, 4023, 4026, 4027, + 4029, 4031, 4033, 4035, 4049, 4066, 4068, 4071, 4072, 4074, + 4075, 4077, 4078, 4081, 4082, 4084, 4085, 4092, 4101, 4108, + 4117, 4124, 4133, 4137, 4140, 4142, 4143, 4148, 4155, 4159, + 4162, 4167, 4171, 4177, 4179, 4180, 4182, 4184, 4185, 4187, + 4189, 4191, 4193, 4195, 4197, 4199, 4201, 4203, 4205, 4207, + 4209, 4211, 4213, 4215, 4217, 4219, 4221, 4223, 4225, 4227, + 4229, 4231, 4233, 4235, 4237, 4239, 4241, 4243, 4245, 4247, + 4249, 4251, 4253, 4255, 4257, 4261, 4263, 4265, 4267, 4269, + 4271, 4273, 4276, 4278, 4280, 4283, 4287, 4291, 4295, 4297, + 4301, 4305, 4308, 4312, 4316, 4320, 4324, 4326, 4328, 4330, + 4332, 4336, 4342, 4344, 4346, 4348, 4350, 4354, 4357, 4360, + 4364, 4366, 4368, 4373, 4379, 4385, 4390, 4397, 4399, 4401, + 4403, 4405, 4407, 4409, 4410, 4412, 4416, 4418, 4419, 4427, + 4431, 4433, 4436, 4440, 4443, 4444, 4447, 4448, 4451, 4456, + 4462, 4466, 4469, 4475, 4477, 4478, 4481, 4482, 4484, 4486, + 4490, 4493, 4495, 4497, 4499, 4502, 4506, 4509, 4512, 4515, + 4518, 4522, 4527, 4530, 4532, 4534, 4536, 4538, 4542, 4544, + 4548, 4551, 4561, 4574, 4586, 4599, 4614, 4618, 4623, 4628, + 4629, 4637, 4648, 4658, 4661, 4665, 4666, 4671, 4673, 4675, + 4677, 4679, 4681, 4683, 4685, 4687, 4689, 4691, 4693, 4695, + 4697, 4699, 4701, 4703, 4705, 4707, 4709, 4711, 4713, 4715, + 4717, 4719, 4721, 4723, 4725, 4727, 4729, 4731, 4733, 4735, + 4737, 4739, 4741, 4743, 4745, 4747, 4749, 4751, 4753, 4755, + 4757, 4759, 4761, 4763, 4765, 4767, 4769, 4771, 4773, 4775, + 4777, 4779, 4781, 4783, 4785, 4787, 4789, 4791, 4793, 4795, + 4797, 4799, 4801, 4803, 4805, 4807, 4809, 4811, 4813, 4815, + 4817, 4819, 4821, 4823, 4825, 4827, 4829, 4831, 4833, 4835, + 4837, 4839, 4841, 4843, 4845, 4847, 4849, 4851, 4853, 4855, + 4857, 4859, 4861, 4863, 4865, 4867, 4869, 4871, 4873, 4875, + 4877, 4879, 4881, 4883, 4885, 4887, 4889, 4891, 4893, 4895, + 4897, 4899, 4901, 4903, 4905, 4907, 4909, 4911, 4913, 4915, + 4917, 4919, 4921, 4923, 4925, 4927, 4929, 4931, 4933, 4935, + 4937, 4939, 4941, 4943, 4945, 4947, 4949, 4951, 4953, 4955, + 4957, 4959, 4961, 4963, 4965, 4967, 4969, 4971, 4973, 4975, + 4977, 4979, 4981, 4983, 4985, 4987, 4989, 4991, 4993, 4995, + 4997, 4999, 5001, 5003, 5005, 5007, 5009, 5011, 5013, 5015, + 5017, 5019, 5021, 5023, 5025, 5027, 5029, 5031, 5033, 5035, + 5037, 5039, 5041, 5043, 5045, 5047, 5049, 5051, 5053, 5055, + 5057, 5059, 5061, 5063, 5065, 5067, 5069, 5071, 5073, 5075, + 5077, 5079, 5081, 5083, 5085, 5087, 5089, 5091, 5093, 5095, + 5097, 5099, 5101, 5103, 5105, 5107, 5109, 5111, 5113, 5115, + 5117, 5119, 5121, 5123, 5125, 5127, 5129, 5131, 5133, 5135, + 5137, 5139, 5141, 5143, 5145, 5147, 5149, 5151, 5153, 5155, + 5157, 5159, 5161, 5163, 5165, 5167, 5169, 5171, 5173, 5175, + 5177, 5179, 5181, 5183, 5185, 5187, 5189, 5191, 5193, 5195, + 5197, 5199, 5201, 5203, 5205, 5207, 5209, 5211, 5213, 5215, + 5217, 5219, 5221, 5223, 5225, 5227, 5229, 5231, 5233, 5235, + 5237, 5239, 5241, 5243, 5245, 5247, 5249, 5251, 5253, 5255, + 5257, 5259, 5261, 5263, 5265, 5267, 5269, 5271, 5273, 5275, + 5277, 5279, 5281, 5283, 5285, 5287, 5289, 5291, 5293, 5295, + 5297, 5299, 5301, 5303, 5305, 5307, 5309, 5311, 5313, 5315, + 5317, 5319, 5321, 5323, 5325, 5327, 5329, 5331, 5333, 5335, + 5337, 5339, 5341, 5343, 5345, 5347, 5349, 5351, 5353, 5355, + 5357, 5359, 5361, 5363, 5365, 5367, 5369, 5371, 5373, 5375, + 5377, 5379, 5381, 5383, 5385, 5387, 5389, 5391, 5393, 5395, + 5397, 5399, 5401, 5403, 5405, 5407, 5409, 5411, 5413, 5415, + 5417, 5419, 5421, 5423, 5425, 5427, 5429, 5431, 5433, 5435, + 5437, 5439, 5441, 5443, 5445, 5447, 5449, 5451, 5453, 5455, + 5457, 5459, 5461, 5463, 5465, 5467, 5469, 5471, 5473, 5475, + 5477, 5479, 5481, 5483, 5485, 5487, 5489, 5491, 5493, 5495, + 5497, 5499, 5501, 5503, 5505, 5507, 5509, 5511, 5513, 5515, + 5517, 5519, 5521, 5523, 5525, 5527, 5529, 5531, 5533, 5535, + 5537, 5539, 5541, 5543, 5545, 5547, 5549, 5551, 5553, 5555, + 5557, 5559, 5561, 5563, 5565, 5567, 5569, 5571, 5573, 5575, + 5577, 5579, 5581, 5583, 5585, 5587, 5589, 5591, 5593, 5595, + 5597, 5599, 5601, 5603, 5605, 5607, 5609, 5611, 5613, 5615, + 5617, 5619, 5621, 5623, 5625, 5627, 5629, 5631, 5633, 5635, + 5637, 5639, 5641, 5643, 5645, 5647, 5649, 5651, 5653, 5655, + 5657, 5659, 5661, 5663, 5665, 5667, 5669, 5671, 5673, 5675, + 5677, 5679, 5681, 5683, 5685, 5687, 5689, 5691, 5693, 5695, + 5697, 5699, 5701, 5703, 5705, 5707, 5709, 5711, 5713, 5715, + 5717, 5719, 5721, 5723, 5725, 5727, 5729, 5731, 5733, 5735, + 5737, 5739, 5741, 5743, 5745, 5747, 5749, 5751, 5753, 5755, + 5757, 5759, 5761, 5763, 5765, 5767, 5769, 5771, 5773, 5775, + 5777, 5779, 5781, 5783, 5785, 5787, 5789, 5791, 5793, 5795, + 5797, 5799, 5801, 5803, 5805, 5807, 5809, 5811, 5813, 5815, + 5817, 5819, 5821, 5823, 5825, 5827, 5829, 5831, 5833, 5835, + 5837, 5839, 5841, 5843, 5845, 5847, 5849, 5851, 5853, 5855, + 5857, 5859, 5861, 5863, 5865, 5867, 5869, 5871, 5873, 5875, + 5877, 5879, 5881, 5883, 5885, 5887, 5889, 5891, 5893, 5895, + 5897, 5899, 5901, 5903, 5905, 5907, 5909, 5911 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int16 yyrhs[] = { - 510, 0, -1, 511, -1, 511, 502, 512, -1, 512, - -1, 857, -1, 554, -1, 513, -1, 889, -1, 897, - -1, 858, -1, 622, -1, 900, -1, 618, -1, 847, - -1, 550, -1, 563, -1, 546, -1, 524, -1, 885, - -1, 611, -1, 552, -1, 861, -1, 859, -1, 860, - -1, 850, -1, 527, -1, 878, -1, 549, -1, 844, - -1, 525, -1, 639, -1, 561, -1, 621, -1, 880, - -1, 890, -1, 872, -1, 893, -1, 898, -1, -1, - 31, 406, 710, 521, -1, 31, 406, 190, 152, 710, - 521, -1, 31, 200, 824, 521, -1, 31, 200, 190, - 152, 824, 521, -1, 31, 370, 824, 521, -1, 31, - 370, 190, 152, 824, 521, -1, 31, 453, 824, 521, - -1, 31, 453, 190, 152, 824, 521, -1, 516, -1, - 514, 516, -1, 376, 117, 753, -1, 137, 117, -1, - 348, -1, 348, 556, 557, -1, 376, 558, -1, 376, - 175, 610, -1, 520, -1, 517, 503, 520, -1, 25, - 590, -1, 25, 190, 272, 152, 590, -1, 25, 77, - 590, -1, 25, 77, 190, 272, 152, 590, -1, 31, - 526, 833, 515, -1, 31, 526, 833, 137, 272, 277, - -1, 31, 526, 833, 376, 272, 277, -1, 31, 526, - 833, 376, 392, 560, -1, 31, 526, 833, 376, 578, - -1, 31, 526, 833, 346, 578, -1, 31, 526, 833, - 376, 395, 833, -1, 31, 526, 833, 25, 175, 610, - 38, 189, 566, -1, 31, 526, 833, 514, -1, 31, - 526, 833, 137, 189, -1, 31, 526, 833, 137, 189, - 190, 152, -1, 137, 526, 190, 152, 833, 615, -1, - 137, 526, 833, 615, -1, 31, 526, 833, 523, 428, - 723, 719, 519, -1, 31, 526, 833, 522, -1, 25, - 580, -1, 31, 88, 827, 564, -1, 444, 88, 827, - -1, 137, 88, 190, 152, 827, 615, -1, 137, 88, - 827, 615, -1, 376, 244, -1, 376, 437, -1, 376, - 578, -1, 346, 578, -1, 522, -1, 441, 753, -1, - -1, 574, -1, 376, 574, -1, 25, 574, -1, 137, - 588, -1, 518, -1, 521, 503, 518, -1, 291, 499, - 517, 500, -1, 376, 109, -1, 376, -1, -1, 113, - 827, -1, 113, 317, 827, -1, 113, 29, -1, 113, - 317, 29, -1, 31, 362, 827, 342, 417, 827, -1, - 31, 406, 710, 342, 417, 827, -1, 31, 406, 190, - 152, 710, 342, 417, 827, -1, 31, 370, 824, 342, - 417, 827, -1, 31, 370, 190, 152, 824, 342, 417, - 827, -1, 31, 453, 824, 342, 417, 827, -1, 31, - 453, 190, 152, 824, 342, 417, 827, -1, 31, 200, - 824, 342, 417, 827, -1, 31, 200, 190, 152, 824, - 342, 417, 827, -1, 31, 406, 710, 342, 526, 827, - 417, 827, -1, 31, 406, 190, 152, 710, 342, 526, - 827, 417, 827, -1, 31, 406, 710, 342, 88, 827, - 417, 827, -1, 31, 406, 190, 152, 710, 342, 88, - 827, 417, 827, -1, 77, -1, -1, 531, 210, 217, - 529, 528, 534, 536, -1, 639, -1, 300, 537, 446, - 639, -1, 499, 541, 500, 639, -1, 499, 541, 500, - 300, 537, 446, 639, -1, 117, 447, -1, 824, -1, - 824, 38, 833, -1, 499, 544, 500, 716, -1, 287, - 88, 827, -1, -1, 645, -1, -1, 833, 811, -1, - 545, 488, 753, -1, 499, 538, 500, 488, 753, -1, - 287, 86, 530, 133, 439, 376, 543, 716, -1, 287, - 86, 530, 133, 273, -1, -1, 833, 539, 540, 660, - 661, -1, 758, 539, 540, 660, 661, -1, 499, 753, - 500, 539, 540, 660, 661, -1, 350, 814, -1, -1, - 440, -1, 405, -1, 545, -1, 538, 503, 545, -1, - 75, 838, -1, -1, 838, -1, -1, 532, -1, 541, - 503, 532, -1, 533, -1, 542, 503, 533, -1, 542, - -1, 542, 503, -1, 535, -1, 544, 503, 535, -1, - 833, 811, -1, 95, 428, 838, 38, 144, 640, -1, - 95, 428, 838, 38, 144, 499, 547, 500, -1, 95, - 428, 838, 38, 723, -1, 548, -1, -1, 832, -1, - 548, 503, 832, -1, 314, 833, -1, 314, 833, 488, - 877, -1, 314, 833, 499, 789, 500, -1, 95, 609, - 370, 824, 551, -1, 95, 609, 370, 190, 272, 152, - 824, 551, -1, 555, -1, -1, 151, 827, 553, -1, - 95, 609, 406, 902, 38, 151, 827, 553, 901, -1, - 95, 609, 406, 190, 272, 152, 902, 38, 151, 827, - 553, 901, -1, 499, 787, 500, -1, -1, 31, 370, - 824, 555, -1, 31, 370, 190, 152, 824, 555, -1, - 558, -1, 555, 558, -1, 461, -1, 485, -1, -1, - 4, -1, 490, 4, -1, 491, 4, -1, 560, -1, - 38, 725, -1, 57, 557, -1, 108, -1, 270, 108, - -1, 199, 559, 557, -1, 250, 557, -1, 258, 557, - -1, 270, 250, -1, 270, 258, -1, 301, 56, 838, - -1, 370, 263, 838, -1, 390, 556, 557, -1, 348, - -1, 348, 556, 557, -1, 56, -1, -1, 831, -1, - 490, 831, -1, 491, 831, -1, 21, 562, -1, 49, - 562, -1, 390, 562, -1, 81, 562, -1, 143, 562, - -1, 355, 562, -1, 464, -1, 419, -1, -1, 95, - 609, 406, 824, 499, 596, 500, 585, 577, -1, 95, - 609, 406, 190, 272, 152, 824, 499, 596, 500, 585, - 577, -1, 95, 292, 344, 609, 406, 824, 499, 596, - 500, 585, 577, -1, -1, 564, 589, -1, 604, -1, - 909, -1, 783, -1, 557, -1, 832, -1, 271, -1, - 499, 555, 500, -1, -1, 832, -1, 270, 24, -1, - 349, -1, 60, -1, 376, 277, -1, 376, 117, -1, - 88, 827, 570, -1, 570, -1, 584, -1, 75, 838, - -1, 272, 277, -1, 277, -1, 434, 595, -1, 320, - 224, 595, -1, 69, 499, 753, 500, 579, -1, 441, - 83, 827, -1, 117, 754, -1, 336, 824, 598, 607, - 576, -1, 455, -1, 396, -1, 571, -1, -1, 175, - 610, 38, 189, 566, -1, 175, 610, 38, 499, 753, - 500, 572, -1, 38, 499, 753, 500, 572, -1, 588, - 567, -1, 287, 439, 568, -1, 575, -1, 600, -1, - 575, 600, -1, 600, 575, -1, -1, 287, 81, 137, - -1, 287, 81, 122, 358, -1, 287, 81, 319, 358, - -1, -1, 499, 582, 500, -1, 270, 202, -1, -1, - 88, 827, 605, -1, 605, -1, 80, -1, 89, -1, - 118, -1, 189, -1, 201, -1, 392, -1, 395, -1, - 29, -1, 601, -1, 582, 503, 601, -1, 441, 200, - 592, -1, 119, -1, 272, 119, -1, 204, 120, -1, - 204, 193, -1, 461, 578, -1, 461, 285, -1, 463, - 285, -1, -1, 499, 591, 500, -1, 587, 198, 581, - -1, 587, 149, 581, -1, -1, 842, -1, 272, 119, - -1, 119, -1, 204, 193, -1, 204, 120, -1, 272, - 443, -1, 270, 202, -1, 833, 723, 599, -1, 833, - 722, 573, 599, -1, 594, -1, 591, 503, 594, -1, - 833, -1, 590, -1, 608, -1, 580, -1, 842, 488, - 565, -1, 842, -1, 461, 586, -1, -1, 606, -1, - 606, 503, -1, -1, 833, -1, 499, 602, 500, -1, - -1, 599, 569, -1, -1, 287, 122, 568, -1, 842, - 488, 565, -1, 842, -1, 842, 501, 842, 488, 565, - -1, 842, 501, 842, -1, 597, -1, 602, 503, 597, - -1, 602, -1, 602, 503, -1, 723, -1, 835, 839, - 494, 428, -1, 377, 835, 839, 494, 428, -1, 69, - 499, 753, 500, 564, -1, 434, 499, 603, 500, 595, - 564, -1, 434, 583, 564, -1, 320, 224, 499, 603, - 500, 595, 564, -1, 320, 224, 583, 564, -1, 168, - 224, 499, 603, 500, 336, 824, 598, 607, 576, 564, - -1, 593, -1, 606, 503, 593, -1, 248, 172, -1, - 248, 305, -1, 248, 382, -1, -1, 234, 824, 587, - -1, 412, -1, 410, -1, 238, 412, -1, 238, 410, - -1, 177, 412, -1, 177, 410, -1, 437, -1, -1, - 32, -1, 56, 117, -1, 137, 612, 190, 152, 614, - 615, -1, 137, 612, 614, 615, -1, 137, 613, 190, - 152, 825, 615, -1, 137, 613, 825, 615, -1, 137, - 616, 827, 287, 838, 615, -1, 137, 616, 190, 152, - 827, 287, 838, 615, -1, 137, 428, 617, 615, -1, - 137, 428, 190, 152, 617, 615, -1, 406, -1, 370, - -1, 173, -1, 245, -1, 245, 406, -1, 453, -1, - 249, 453, -1, 200, -1, 168, 406, -1, 76, -1, - 92, -1, 392, -1, 413, 365, 304, -1, 413, 365, - 129, -1, 413, 365, 411, -1, 413, 365, 85, -1, - 23, 251, -1, 146, 422, -1, 156, -1, 168, 109, - 465, -1, 326, -1, 362, -1, 373, -1, 838, -1, - 614, 503, 838, -1, 60, -1, 349, -1, -1, 312, - -1, 359, -1, 422, -1, 723, -1, 617, 503, 723, - -1, 95, 609, 619, 824, 620, 38, 406, 639, -1, - 95, 609, 619, 190, 272, 152, 824, 620, 38, 406, - 639, -1, 95, 292, 344, 609, 619, 824, 620, 38, - 406, 639, -1, 95, 609, 619, 824, 620, 38, 753, - -1, 95, 609, 619, 190, 272, 152, 824, 620, 38, - 753, -1, 95, 292, 344, 609, 619, 824, 620, 38, - 753, -1, 173, -1, 245, -1, 499, 500, -1, 499, - 789, 500, -1, 531, 439, 886, 376, 543, 699, 887, - 536, -1, 93, 634, 824, 598, 632, 623, 628, 637, - 624, 556, 629, -1, 93, 499, 639, 500, 417, 628, - 637, 556, 629, -1, 171, -1, 417, -1, 626, 124, - 832, -1, -1, 636, -1, 625, 503, 636, -1, 441, - -1, -1, 38, -1, -1, 325, -1, -1, 633, -1, - 499, 638, 500, -1, 869, -1, 557, -1, 492, -1, - 499, 625, 500, -1, -1, 842, 630, -1, 461, 285, - -1, -1, 633, 635, -1, -1, 52, -1, -1, 52, - -1, 285, -1, 170, -1, 123, 627, 832, -1, 277, - 627, 832, -1, 97, -1, 185, -1, 328, 627, 832, - -1, 145, 627, 832, -1, 167, 328, 602, -1, 167, - 328, 492, -1, 167, 272, 277, 602, -1, 167, 277, - 602, -1, 141, 832, -1, 869, -1, 832, -1, 393, - -1, 394, -1, 631, -1, 638, 503, 631, -1, 641, - -1, 640, -1, 499, 641, 500, -1, 499, 640, 500, - -1, 644, -1, 642, 657, -1, 642, 656, 690, 663, - -1, 642, 656, 662, 691, -1, 645, 642, -1, 645, - 642, 657, -1, 645, 642, 656, 690, 663, -1, 645, - 642, 656, 662, 691, -1, 644, -1, 640, -1, 369, - 654, 813, -1, -1, 369, 654, 813, 648, 699, 716, - 679, 688, 764, 689, 667, -1, 369, 653, 815, 648, - 699, 716, 679, 688, 764, 689, 667, -1, 171, 700, - 643, 648, 716, 679, 688, 764, 689, 667, -1, 171, - 700, 369, 653, 815, 648, 716, 679, 688, 764, 689, - 667, -1, 698, -1, 406, 710, -1, 642, 433, 651, - 652, 642, -1, 642, 433, 651, 642, -1, 642, 215, - 651, 642, -1, 642, 147, 651, 642, -1, 461, 646, - -1, 485, 646, -1, 461, 334, 646, -1, 647, -1, - 646, 503, 647, -1, 827, 840, 38, 499, 846, 500, - -1, 217, 649, -1, -1, 412, 650, 824, -1, 410, - 650, 824, -1, 238, 412, 650, 824, -1, 238, 410, - 650, 824, -1, 177, 412, 650, 824, -1, 177, 410, - 650, 824, -1, 437, 650, 824, -1, 406, 824, -1, - 824, -1, 406, -1, -1, 29, -1, 132, -1, -1, - 56, 263, -1, 132, -1, 132, 287, 499, 787, 500, - -1, 29, -1, -1, 191, 279, -1, 347, 279, -1, - -1, 657, -1, -1, 293, 56, 658, -1, 293, 56, - 29, 660, 661, -1, 293, 56, 492, 660, 661, -1, - 659, -1, 658, 503, 659, -1, 753, 441, 783, 661, - -1, 753, 660, 661, -1, 39, -1, 126, -1, -1, - 484, 163, -1, 484, 228, -1, -1, 664, 665, -1, - 665, 664, -1, 664, -1, 665, -1, 662, -1, -1, - 235, 673, -1, 235, 673, 503, 674, -1, 161, 678, - 675, 677, 288, -1, 161, 678, 677, 288, -1, 284, - 674, -1, 284, 675, 677, -1, 4, 494, -1, 9, - 494, -1, 4, 309, -1, 9, 309, -1, 9, -1, - 9, 358, -1, 441, 360, 669, -1, -1, 833, -1, - -1, 668, 499, 666, 500, 672, -1, 666, -1, 666, - 499, 833, 500, -1, 666, 499, 833, 503, 9, 500, - -1, 408, 669, -1, 670, -1, -1, 343, 499, 9, - 500, -1, -1, 753, -1, 29, -1, 753, 494, -1, - 4, 309, -1, 9, 309, -1, 753, -1, 755, -1, - 490, 676, -1, 491, 676, -1, 831, -1, 4, -1, - 357, -1, 358, -1, 163, -1, 269, -1, 180, 56, - 681, -1, 180, 56, 29, -1, 180, 56, 492, -1, - -1, 682, -1, 680, 503, 682, -1, 680, -1, 680, - 503, -1, 753, -1, 683, -1, 685, -1, 684, -1, - 686, -1, 499, 500, -1, 356, 499, 787, 500, -1, - 98, 499, 787, 500, -1, 181, 378, 499, 681, 500, - -1, 181, -1, 182, -1, 184, 753, -1, -1, 327, - 753, -1, -1, 692, -1, 166, 330, 288, -1, 690, - -1, -1, 693, -1, 692, 693, -1, 694, 695, 696, - -1, 166, 439, -1, 166, 270, 224, 439, -1, 166, - 379, -1, 166, 224, 379, -1, 282, 823, -1, -1, - 276, -1, 383, 243, -1, -1, 447, 499, 787, 500, - -1, 697, 503, 499, 787, 500, -1, 697, -1, 697, - 503, -1, 171, 701, -1, -1, 702, -1, 700, 503, - 702, -1, 700, -1, 700, 503, -1, 710, 705, 671, - -1, 711, 706, 671, -1, 698, 704, 671, -1, 229, - 711, 706, -1, 640, 705, 671, -1, 229, 640, 705, - -1, 703, -1, 499, 703, 500, 704, -1, 499, 703, - 500, -1, 702, 96, 222, 702, -1, 702, 707, 222, - 702, 709, -1, 702, 222, 702, 709, -1, 702, 266, - 707, 222, 702, -1, 702, 266, 222, 702, -1, 38, - 834, 499, 826, 500, -1, 38, 834, -1, 833, 499, - 826, 500, -1, 833, -1, 704, -1, -1, 704, -1, - 38, 499, 717, 500, -1, 38, 834, 499, 717, 500, - -1, 833, 499, 717, 500, -1, -1, 172, 708, -1, - 232, 708, -1, 353, 708, -1, 206, -1, 296, -1, - -1, 441, 499, 826, 500, -1, 287, 753, -1, 824, - -1, 824, 492, -1, 288, 824, -1, 288, 499, 824, - 500, -1, 758, 715, -1, 358, 171, 499, 713, 500, - 715, -1, 758, 714, -1, 712, -1, 713, 503, 712, - -1, 38, 499, 717, 500, -1, -1, 485, 294, -1, - -1, 458, 753, -1, -1, 718, -1, 717, 503, 718, - -1, 834, 723, 719, -1, 75, 838, -1, -1, 833, - 723, -1, 720, 503, 833, 723, -1, 357, -1, 399, - -1, 723, -1, -1, 725, 724, -1, 377, 725, 724, - -1, 725, 37, 497, 831, 498, -1, 377, 725, 37, - 497, 831, 498, -1, 725, 37, -1, 377, 725, 37, - -1, 721, 499, 720, 500, 724, -1, 246, 499, 791, - 500, 724, -1, 433, 499, 720, 500, 724, -1, 724, - 497, 498, -1, 724, 497, 831, 498, -1, -1, 727, - -1, 729, -1, 731, -1, 735, -1, 741, -1, 742, - 752, -1, 742, 499, 831, 500, -1, 729, -1, 732, - -1, 736, -1, 741, -1, 837, 728, -1, 499, 788, - 500, -1, -1, 213, -1, 214, -1, 384, -1, 51, - -1, 331, -1, 164, 730, -1, 136, 316, -1, 115, - 728, -1, 114, 728, -1, 280, 728, -1, 54, -1, - 499, 831, 500, -1, -1, 733, -1, 734, -1, 733, - -1, 734, -1, 53, 740, 499, 787, 500, -1, 53, - 740, -1, 737, -1, 738, -1, 737, -1, 738, -1, - 739, 499, 831, 500, -1, 739, -1, 67, 740, -1, - 66, 740, -1, 448, -1, 265, 67, 740, -1, 265, - 66, 740, -1, 267, 740, -1, 450, -1, -1, 416, - 499, 831, 500, 743, -1, 416, 743, -1, 415, 499, - 831, 500, 743, -1, 415, 743, -1, 216, -1, 485, - 415, 482, -1, 463, 415, 482, -1, -1, 479, -1, - 480, -1, 260, -1, 261, -1, 111, -1, 112, -1, - 187, -1, 188, -1, 256, -1, 257, -1, 366, -1, - 367, -1, 254, -1, 255, -1, 252, -1, 253, -1, - 744, -1, 745, -1, 746, -1, 747, -1, 748, -1, - 749, -1, 750, -1, 751, -1, 744, 417, 745, -1, - 746, 417, 747, -1, 746, 417, 748, -1, 746, 417, - 749, -1, 747, 417, 748, -1, 747, 417, 749, -1, - 748, 417, 749, -1, -1, 755, -1, 753, 11, 723, - -1, 753, 75, 838, -1, 753, 43, 415, 482, 753, - -1, 490, 753, -1, 491, 753, -1, 753, 490, 753, - -1, 753, 491, 753, -1, 753, 492, 753, -1, 753, - 493, 753, -1, 753, 494, 753, -1, 753, 495, 753, - -1, 753, 15, 753, -1, 753, 486, 753, -1, 753, - 487, 753, -1, 753, 488, 753, -1, 753, 18, 753, - -1, 753, 19, 753, -1, 753, 20, 753, -1, 753, - 782, 753, -1, 782, 753, -1, 753, 782, -1, 753, - 35, 753, -1, 753, 292, 753, -1, 272, 753, -1, - 483, 753, -1, 753, 176, 753, -1, 753, 234, 753, - -1, 753, 234, 753, 145, 753, -1, 753, 483, 234, - 753, -1, 753, 483, 234, 753, 145, 753, -1, 753, - 192, 753, -1, 753, 192, 753, 145, 753, -1, 753, - 483, 192, 753, -1, 753, 483, 192, 753, 145, 753, - -1, 753, 381, 417, 753, -1, 753, 381, 417, 753, - 145, 753, -1, 753, 483, 381, 417, 753, -1, 753, - 483, 381, 417, 753, 145, 753, -1, 753, 219, 277, - -1, 753, 220, -1, 753, 219, 272, 277, -1, 753, - 272, 277, -1, 753, 275, -1, 753, 16, 753, -1, - 753, 17, 753, -1, 775, 298, 775, -1, 753, 219, - 424, -1, 753, 219, 272, 424, -1, 753, 219, 159, - -1, 753, 219, 272, 159, -1, 753, 219, 435, -1, - 753, 219, 272, 435, -1, 753, 219, 132, 171, 753, - -1, 753, 219, 272, 132, 171, 753, -1, 753, 219, - 282, 499, 791, 500, -1, 753, 219, 272, 282, 499, - 791, 500, -1, 753, 50, 812, 754, 35, 753, -1, - 753, 483, 50, 812, 754, 35, 753, -1, 753, 50, - 403, 754, 35, 753, -1, 753, 483, 50, 403, 754, - 35, 753, -1, 753, 197, 801, -1, 753, 483, 197, - 801, -1, 753, 784, 779, 640, -1, 753, 784, 779, - 499, 753, 500, -1, 117, -1, 78, 499, 492, 818, - 822, 500, -1, 78, 499, 832, 500, -1, 755, -1, - 754, 11, 723, -1, 490, 754, -1, 491, 754, -1, - 754, 490, 754, -1, 754, 491, 754, -1, 754, 492, - 754, -1, 754, 493, 754, -1, 754, 494, 754, -1, - 754, 495, 754, -1, 754, 15, 754, -1, 754, 486, - 754, -1, 754, 487, 754, -1, 754, 488, 754, -1, - 754, 18, 754, -1, 754, 19, 754, -1, 754, 20, - 754, -1, 754, 782, 754, -1, 782, 754, -1, 754, - 782, -1, 754, 219, 132, 171, 754, -1, 754, 219, - 272, 132, 171, 754, -1, 754, 219, 282, 499, 791, - 500, -1, 754, 219, 272, 282, 499, 791, 500, -1, - 807, -1, 830, -1, 504, 9, -1, 505, 811, -1, - 10, 811, -1, 499, 753, 500, 811, -1, 775, -1, - 506, 778, 507, -1, 497, 788, 498, -1, 760, -1, - 37, 640, -1, 37, 497, 788, 498, -1, 802, -1, - 757, 811, -1, 640, -1, 640, 810, -1, 152, 640, - -1, 687, 499, 787, 500, -1, 829, 499, 500, -1, - 829, 499, 789, 656, 655, 500, -1, 829, 499, 449, - 790, 656, 655, 500, -1, 829, 499, 789, 503, 449, - 790, 656, 655, 500, -1, 829, 499, 29, 789, 656, - 655, 500, -1, 829, 499, 132, 789, 656, 655, 500, - -1, 829, 499, 492, 500, -1, 756, 761, 762, 763, - 767, -1, 759, -1, 756, -1, 759, -1, 76, 166, - 499, 753, 500, -1, 101, -1, 104, -1, 104, 499, - 831, 500, -1, 105, -1, 105, 499, 831, 500, -1, - 239, -1, 239, 499, 831, 500, -1, 240, -1, 240, - 499, 831, 500, -1, 102, -1, 106, -1, 375, -1, - 440, -1, 100, -1, 103, -1, 63, 499, 753, 38, - 723, 500, -1, 427, 499, 753, 38, 723, 500, -1, - 158, 499, 792, 500, -1, 299, 499, 794, 500, -1, - 313, 499, 796, 500, -1, 401, 499, 797, 500, -1, - 421, 499, 753, 38, 723, 500, -1, 423, 499, 55, - 800, 500, -1, 423, 499, 230, 800, 500, -1, 423, - 499, 418, 800, 500, -1, 423, 499, 800, 500, -1, - 278, 499, 753, 503, 753, 500, -1, 74, 499, 787, - 500, -1, 497, 753, 166, 833, 197, 753, 498, -1, - 497, 753, 166, 833, 197, 755, 190, 753, 498, -1, - 462, 180, 499, 657, 500, -1, -1, 162, 499, 458, - 753, 500, -1, 162, 499, 753, 500, -1, -1, 155, - -1, -1, 460, 765, -1, -1, 766, -1, 765, 503, - 766, -1, 833, 38, 768, -1, 297, 768, -1, 297, - 833, -1, -1, 499, 769, 770, 656, 771, 500, -1, - 833, -1, -1, 306, 56, 786, -1, -1, 329, 772, - -1, 358, 772, -1, -1, 773, -1, 50, 773, 35, - 773, -1, 430, 315, -1, 430, 165, -1, 99, 357, - -1, 753, 315, -1, 753, 165, -1, 357, 499, 787, - 500, -1, 357, 499, 500, -1, 774, -1, 499, 786, - 503, 753, 500, -1, 834, 508, 753, -1, 776, -1, - 777, 503, 776, -1, 777, -1, 777, 503, -1, 36, - -1, 386, -1, 29, -1, 8, -1, 781, -1, 490, - -1, 491, -1, 492, -1, 493, -1, 494, -1, 495, - -1, 15, -1, 486, -1, 487, -1, 488, -1, 18, - -1, 19, -1, 20, -1, 8, -1, 289, 499, 785, - 500, -1, 780, -1, 289, 499, 785, 500, -1, 780, - -1, 289, 499, 785, 500, -1, 234, -1, 483, 234, - -1, 176, -1, 483, 176, -1, 192, -1, 483, 192, - -1, 780, -1, 833, 501, 785, -1, 753, -1, 786, - 503, 753, -1, 786, -1, 786, 503, -1, 787, -1, - -1, 790, -1, 789, 503, 790, -1, 753, -1, 841, - 13, 753, -1, 841, 14, 753, -1, 723, -1, 791, - 503, 723, -1, 793, 171, 753, -1, -1, 3, -1, - 744, -1, 745, -1, 746, -1, 747, -1, 748, -1, - 749, -1, 750, -1, 751, -1, 832, -1, 753, 795, - 798, 799, -1, 753, 795, 798, -1, 310, 753, -1, - 754, 197, 754, -1, -1, 753, 798, 799, -1, 753, - 799, 798, -1, 753, 798, -1, 753, 799, -1, 786, - -1, -1, 171, 753, -1, 166, 753, -1, 753, 171, - 787, -1, 171, 787, -1, 787, -1, 640, -1, 499, - 787, 500, -1, 62, 806, 803, 805, 143, -1, 804, - -1, 803, 804, -1, 457, 753, 414, 753, -1, 139, - 753, -1, -1, 753, -1, -1, 833, -1, 833, 810, - -1, 501, 828, -1, 497, 753, 498, -1, 497, 809, - 508, 809, 498, -1, 753, -1, -1, 808, -1, 810, - 808, -1, -1, 811, 808, -1, 42, -1, -1, 815, - -1, -1, 816, -1, 814, 503, 816, -1, 814, -1, - 814, 503, -1, 753, 38, 843, -1, 753, 3, -1, - 753, -1, 492, 818, 822, -1, 833, 501, 492, 818, - 822, -1, 148, 499, 826, 500, -1, 148, 833, -1, - 817, -1, -1, 753, 38, 833, -1, 819, -1, 820, - 503, 819, -1, 820, -1, 820, 503, -1, 344, 499, - 821, 500, -1, 344, 819, -1, -1, 824, -1, 823, - 503, 824, -1, 834, -1, 833, 810, -1, 827, -1, - 825, 503, 827, -1, 825, -1, 825, 503, -1, 834, - -1, 842, -1, 836, -1, 833, 810, -1, 831, -1, - 4, -1, 832, 811, -1, 6, -1, 7, -1, 829, - 832, -1, 829, 499, 789, 656, 655, 500, 832, -1, - 726, 832, -1, 742, 499, 753, 500, 752, -1, 742, - 831, 752, -1, 742, 832, 752, -1, 424, -1, 159, - -1, 277, -1, 9, -1, 5, -1, 3, -1, 903, - -1, 904, -1, 833, -1, 5, -1, 3, -1, 903, - -1, 908, -1, 3, -1, 903, -1, 905, -1, 3, - -1, 903, -1, 906, -1, 833, -1, 833, 839, -1, - 501, 828, -1, 839, 501, 828, -1, 499, 826, 500, - -1, -1, 835, -1, 3, -1, 907, -1, 903, -1, - 909, -1, 842, -1, 5, -1, 317, 827, 845, 38, - 846, -1, 499, 791, 500, -1, -1, 639, -1, 527, - -1, 621, -1, 885, -1, 95, 362, 833, 848, -1, - 95, 362, 190, 272, 152, 833, 848, -1, 848, 849, - -1, -1, 563, -1, 850, -1, 550, -1, 898, -1, - 95, 856, 200, 853, 854, 287, 824, 852, 499, 544, - 500, 855, 716, -1, 95, 856, 200, 853, 190, 272, - 152, 592, 287, 824, 852, 499, 544, 500, 855, 716, - -1, 833, -1, 441, 851, -1, -1, 84, -1, -1, - 592, -1, -1, 461, 578, -1, -1, 434, -1, -1, - 31, 406, 710, 376, 362, 827, -1, 31, 406, 190, - 152, 710, 376, 362, 827, -1, 31, 370, 824, 376, - 362, 827, -1, 31, 370, 190, 152, 824, 376, 362, - 827, -1, 31, 453, 824, 376, 362, 827, -1, 31, - 453, 190, 152, 824, 376, 362, 827, -1, 167, 70, - -1, 70, -1, 154, 110, 832, 629, -1, 196, 110, - 832, -1, 153, 864, -1, 153, 868, 862, 864, -1, - 153, 451, 864, -1, 153, 499, 867, 500, 864, -1, - 451, -1, -1, 869, -1, 557, -1, -1, 857, -1, - 554, -1, 513, -1, 897, -1, 858, -1, 622, -1, - 900, -1, 618, -1, 847, -1, 550, -1, 563, -1, - 546, -1, 524, -1, 885, -1, 611, -1, 552, -1, - 850, -1, 527, -1, 878, -1, 549, -1, 844, -1, - 525, -1, 639, -1, 561, -1, 621, -1, 880, -1, - 890, -1, 872, -1, 893, -1, 898, -1, 3, -1, - 903, -1, 907, -1, 865, -1, 832, -1, 870, -1, - 867, 503, 870, -1, 34, -1, 33, -1, 424, -1, - 159, -1, 287, -1, 866, -1, 871, 863, -1, 865, - -1, 868, -1, 376, 873, -1, 376, 238, 873, -1, - 376, 374, 873, -1, 376, 177, 873, -1, 874, -1, - 895, 171, 99, -1, 415, 482, 876, -1, 362, 832, - -1, 895, 417, 877, -1, 895, 488, 877, -1, 895, - 417, 117, -1, 895, 488, 117, -1, 869, -1, 557, - -1, 832, -1, 3, -1, 742, 832, 752, -1, 742, - 499, 831, 500, 832, -1, 557, -1, 117, -1, 238, - -1, 875, -1, 877, 503, 875, -1, 237, 879, -1, - 211, 879, -1, 167, 211, 879, -1, 832, -1, 833, - -1, 442, 882, 884, 862, -1, 442, 882, 884, 862, - 824, -1, 442, 882, 884, 862, 889, -1, 442, 499, - 883, 500, -1, 442, 499, 883, 500, 824, 840, -1, - 868, -1, 451, -1, 170, -1, 172, -1, 3, -1, - 172, -1, -1, 881, -1, 883, 503, 881, -1, 170, - -1, -1, 531, 122, 171, 886, 888, 887, 536, -1, - 425, 650, 886, -1, 710, -1, 710, 833, -1, 710, - 38, 833, -1, 458, 753, -1, -1, 441, 701, -1, - -1, 868, 862, -1, 868, 862, 824, 840, -1, 346, - 892, -1, 895, -1, 29, -1, 891, -1, 415, 482, - -1, 419, 221, 233, -1, 894, 639, -1, 402, 639, - -1, 402, 896, -1, 894, 896, -1, 894, 415, 482, - -1, 894, 419, 221, 233, -1, 894, 29, -1, 894, - -1, 380, -1, 127, -1, 833, -1, 895, 501, 833, - -1, 833, -1, 896, 501, 833, -1, 58, 756, -1, - 95, 609, 453, 824, 598, 855, 38, 639, 899, -1, - 95, 292, 344, 609, 453, 824, 598, 855, 38, 639, - 899, -1, 95, 609, 334, 453, 824, 499, 602, 500, - 855, 38, 639, 899, -1, 95, 292, 344, 609, 334, - 453, 824, 499, 602, 500, 855, 38, 639, 899, -1, - 461, 69, 290, -1, 461, 61, 69, 290, -1, 461, - 238, 69, 290, -1, -1, 95, 609, 406, 902, 38, - 639, 901, -1, 95, 609, 406, 190, 272, 152, 902, - 38, 639, 901, -1, 95, 292, 344, 609, 406, 902, - 38, 639, 901, -1, 461, 109, -1, 461, 270, 109, - -1, -1, 824, 598, 585, 577, -1, 21, -1, 22, - -1, 23, -1, 24, -1, 25, -1, 26, -1, 27, - -1, 28, -1, 30, -1, 31, -1, 32, -1, 40, - -1, 41, -1, 43, -1, 44, -1, 45, -1, 47, - -1, 48, -1, 49, -1, 56, -1, 57, -1, 58, - -1, 59, -1, 60, -1, 61, -1, 64, -1, 65, - -1, 68, -1, 70, -1, 71, -1, 72, -1, 73, - -1, 79, -1, 80, -1, 81, -1, 82, -1, 83, - -1, 85, -1, 86, -1, 87, -1, 89, -1, 90, - -1, 91, -1, 92, -1, 93, -1, 94, -1, 97, - -1, 98, -1, 99, -1, 107, -1, 108, -1, 109, - -1, 110, -1, 111, -1, 112, -1, 113, -1, 116, - -1, 118, -1, 120, -1, 121, -1, 122, -1, 123, - -1, 124, -1, 125, -1, 127, -1, 128, -1, 129, - -1, 130, -1, 131, -1, 134, -1, 135, -1, 136, - -1, 137, -1, 138, -1, 140, -1, 141, -1, 142, - -1, 144, -1, 145, -1, 146, -1, 148, -1, 149, - -1, 150, -1, 151, -1, 153, -1, 154, -1, 155, - -1, 156, -1, 157, -1, 160, -1, 162, -1, 163, - -1, 165, -1, 167, -1, 169, -1, 173, -1, 174, - -1, 177, -1, 179, -1, 183, -1, 185, -1, 186, - -1, 187, -1, 188, -1, 189, -1, 190, -1, 191, - -1, 193, -1, 194, -1, 195, -1, 196, -1, 198, - -1, 199, -1, 200, -1, 201, -1, 202, -1, 203, - -1, 205, -1, 208, -1, 209, -1, 210, -1, 211, - -1, 212, -1, 218, -1, 221, -1, 223, -1, 224, - -1, 225, -1, 226, -1, 227, -1, 228, -1, 231, - -1, 233, -1, 236, -1, 237, -1, 238, -1, 241, - -1, 242, -1, 243, -1, 244, -1, 245, -1, 247, - -1, 248, -1, 249, -1, 250, -1, 251, -1, 252, - -1, 253, -1, 254, -1, 255, -1, 256, -1, 257, - -1, 258, -1, 259, -1, 260, -1, 261, -1, 262, - -1, 263, -1, 264, -1, 268, -1, 269, -1, 270, - -1, 273, -1, 274, -1, 276, -1, 279, -1, 281, - -1, 282, -1, 283, -1, 285, -1, 286, -1, 289, - -1, 290, -1, 291, -1, 294, -1, 297, -1, 300, - -1, 301, -1, 302, -1, 303, -1, 304, -1, 305, - -1, 306, -1, 307, -1, 308, -1, 309, -1, 311, - -1, 312, -1, 314, -1, 315, -1, 317, -1, 318, - -1, 319, -1, 321, -1, 322, -1, 323, -1, 324, - -1, 325, -1, 326, -1, 328, -1, 329, -1, 330, - -1, 332, -1, 333, -1, 334, -1, 335, -1, 337, - -1, 338, -1, 339, -1, 340, -1, 341, -1, 342, - -1, 343, -1, 344, -1, 345, -1, 346, -1, 347, - -1, 348, -1, 349, -1, 351, -1, 352, -1, 354, - -1, 355, -1, 356, -1, 358, -1, 359, -1, 360, - -1, 361, -1, 362, -1, 363, -1, 364, -1, 365, - -1, 366, -1, 367, -1, 368, -1, 370, -1, 371, - -1, 372, -1, 373, -1, 374, -1, 376, -1, 378, - -1, 379, -1, 380, -1, 382, -1, 383, -1, 385, - -1, 387, -1, 388, -1, 389, -1, 390, -1, 391, - -1, 392, -1, 393, -1, 394, -1, 395, -1, 396, - -1, 397, -1, 398, -1, 400, -1, 402, -1, 404, - -1, 405, -1, 407, -1, 409, -1, 410, -1, 411, - -1, 412, -1, 413, -1, 419, -1, 420, -1, 422, - -1, 425, -1, 426, -1, 428, -1, 429, -1, 430, - -1, 431, -1, 432, -1, 435, -1, 436, -1, 437, - -1, 438, -1, 439, -1, 442, -1, 443, -1, 444, - -1, 445, -1, 446, -1, 450, -1, 452, -1, 453, - -1, 454, -1, 455, -1, 456, -1, 459, -1, 462, - -1, 463, -1, 464, -1, 465, -1, 466, -1, 467, - -1, 479, -1, 480, -1, 481, -1, 482, -1, 50, - -1, 51, -1, 53, -1, 54, -1, 66, -1, 67, - -1, 74, -1, 78, -1, 114, -1, 115, -1, 152, - -1, 158, -1, 164, -1, 175, -1, 181, -1, 182, - -1, 207, -1, 213, -1, 214, -1, 216, -1, 246, - -1, 265, -1, 267, -1, 271, -1, 278, -1, 280, - -1, 295, -1, 299, -1, 313, -1, 316, -1, 331, - -1, 357, -1, 377, -1, 384, -1, 399, -1, 401, - -1, 415, -1, 416, -1, 421, -1, 423, -1, 427, - -1, 447, -1, 448, -1, 468, -1, 469, -1, 470, - -1, 471, -1, 472, -1, 473, -1, 474, -1, 475, - -1, 476, -1, 477, -1, 478, -1, 46, -1, 52, - -1, 76, -1, 84, -1, 96, -1, 100, -1, 101, - -1, 102, -1, 103, -1, 106, -1, 170, -1, 172, - -1, 175, -1, 176, -1, 192, -1, 206, -1, 219, - -1, 220, -1, 222, -1, 232, -1, 234, -1, 246, - -1, 266, -1, 275, -1, 296, -1, 298, -1, 353, - -1, 375, -1, 381, -1, 399, -1, 408, -1, 440, - -1, 451, -1, 46, -1, 52, -1, 76, -1, 78, - -1, 84, -1, 96, -1, 100, -1, 101, -1, 102, - -1, 103, -1, 106, -1, 170, -1, 172, -1, 176, + 513, 0, -1, 514, -1, 514, 504, 515, -1, 515, + -1, 866, -1, 560, -1, 516, -1, 899, -1, 900, + -1, 913, -1, 867, -1, 629, -1, 916, -1, 554, + -1, 625, -1, 856, -1, 556, -1, 570, -1, 550, + -1, 527, -1, 895, -1, 901, -1, 618, -1, 558, + -1, 871, -1, 869, -1, 870, -1, 859, -1, 530, + -1, 888, -1, 553, -1, 853, -1, 528, -1, 646, + -1, 567, -1, 628, -1, 569, -1, 890, -1, 906, + -1, 882, -1, 909, -1, 914, -1, -1, 31, 407, + 717, 524, -1, 31, 407, 190, 152, 717, 524, -1, + 31, 200, 832, 524, -1, 31, 200, 190, 152, 832, + 524, -1, 31, 371, 832, 524, -1, 31, 371, 190, + 152, 832, 524, -1, 31, 455, 832, 524, -1, 31, + 455, 190, 152, 832, 524, -1, 519, -1, 517, 519, + -1, 377, 117, 760, -1, 137, 117, -1, 349, -1, + 349, 562, 563, -1, 377, 564, -1, 377, 175, 617, + -1, 523, -1, 520, 505, 523, -1, 25, 597, -1, + 25, 190, 272, 152, 597, -1, 25, 77, 597, -1, + 25, 77, 190, 272, 152, 597, -1, 31, 529, 841, + 518, -1, 31, 529, 841, 137, 272, 277, -1, 31, + 529, 841, 377, 272, 277, -1, 31, 529, 841, 377, + 393, 566, -1, 31, 529, 841, 377, 585, -1, 31, + 529, 841, 347, 585, -1, 31, 529, 841, 377, 396, + 841, -1, 31, 529, 841, 25, 175, 617, 38, 189, + 573, -1, 31, 529, 841, 517, -1, 31, 529, 841, + 137, 189, -1, 31, 529, 841, 137, 189, 190, 152, + -1, 137, 529, 190, 152, 841, 622, -1, 137, 529, + 841, 622, -1, 31, 529, 841, 526, 429, 730, 726, + 522, -1, 31, 529, 841, 525, -1, 25, 587, -1, + 31, 88, 835, 571, -1, 446, 88, 835, -1, 137, + 88, 190, 152, 835, 622, -1, 137, 88, 835, 622, + -1, 377, 244, -1, 377, 438, -1, 377, 585, -1, + 347, 585, -1, 525, -1, 443, 760, -1, -1, 581, + -1, 377, 581, -1, 25, 581, -1, 137, 595, -1, + 521, -1, 524, 505, 521, -1, 291, 501, 520, 502, + -1, 377, 109, -1, 377, -1, -1, 113, 835, -1, + 113, 318, 835, -1, 113, 29, -1, 113, 318, 29, + -1, 31, 363, 835, 343, 418, 835, -1, 31, 407, + 717, 343, 418, 835, -1, 31, 407, 190, 152, 717, + 343, 418, 835, -1, 31, 371, 832, 343, 418, 835, + -1, 31, 371, 190, 152, 832, 343, 418, 835, -1, + 31, 455, 832, 343, 418, 835, -1, 31, 455, 190, + 152, 832, 343, 418, 835, -1, 31, 200, 832, 343, + 418, 835, -1, 31, 200, 190, 152, 832, 343, 418, + 835, -1, 31, 407, 717, 343, 529, 835, 418, 835, + -1, 31, 407, 190, 152, 717, 343, 529, 835, 418, + 835, -1, 31, 407, 717, 343, 88, 835, 418, 835, + -1, 31, 407, 190, 152, 717, 343, 88, 835, 418, + 835, -1, 77, -1, -1, 534, 210, 537, 217, 532, + 531, 538, 540, -1, 646, -1, 300, 541, 448, 646, + -1, 501, 545, 502, 646, -1, 501, 545, 502, 300, + 541, 448, 646, -1, 117, 449, -1, 832, -1, 832, + 38, 841, -1, 501, 548, 502, 723, -1, 287, 88, + 835, -1, -1, 652, -1, -1, 841, 819, -1, 549, + 490, 760, -1, 501, 542, 502, 490, 760, -1, 292, + 345, -1, 292, 191, -1, -1, 287, 86, 533, 133, + 440, 377, 547, 723, -1, 287, 86, 533, 133, 273, + -1, -1, 841, 543, 544, 667, 668, -1, 766, 543, + 544, 667, 668, -1, 501, 760, 502, 543, 544, 667, + 668, -1, 351, 822, -1, -1, 442, -1, 406, -1, + 549, -1, 542, 505, 549, -1, 75, 846, -1, -1, + 846, -1, -1, 535, -1, 545, 505, 535, -1, 536, + -1, 546, 505, 536, -1, 546, -1, 546, 505, -1, + 539, -1, 548, 505, 539, -1, 841, 819, -1, 95, + 429, 832, 38, 144, 647, -1, 95, 429, 832, 38, + 144, 501, 551, 502, -1, 95, 429, 832, 38, 730, + -1, 552, -1, -1, 840, -1, 552, 505, 840, -1, + 315, 841, -1, 315, 841, 490, 887, -1, 315, 841, + 501, 797, 502, -1, 95, 110, 832, -1, 95, 555, + 110, 832, -1, 95, 110, 190, 272, 152, 832, -1, + 95, 292, 345, 110, 832, -1, 95, 110, 832, 171, + 840, -1, 95, 110, 190, 272, 152, 832, 171, 840, + -1, 95, 292, 345, 110, 832, 171, 840, -1, 840, + -1, 95, 616, 371, 832, 557, -1, 95, 616, 371, + 190, 272, 152, 832, 557, -1, 561, -1, -1, 151, + 835, 559, -1, 95, 616, 407, 918, 38, 151, 835, + 559, 917, -1, 95, 616, 407, 190, 272, 152, 918, + 38, 151, 835, 559, 917, -1, 501, 795, 502, -1, + -1, 31, 371, 832, 561, -1, 31, 371, 190, 152, + 832, 561, -1, 564, -1, 561, 564, -1, 463, -1, + 487, -1, -1, 4, -1, 492, 4, -1, 493, 4, + -1, 566, -1, 38, 732, -1, 57, 563, -1, 108, + -1, 270, 108, -1, 199, 565, 563, -1, 250, 563, + -1, 258, 563, -1, 270, 250, -1, 270, 258, -1, + 301, 56, 846, -1, 371, 263, 846, -1, 391, 562, + 563, -1, 349, -1, 349, 562, 563, -1, 56, -1, + -1, 839, -1, 492, 839, -1, 493, 839, -1, 21, + 568, -1, 49, 568, -1, 391, 568, -1, 81, 568, + -1, 143, 568, -1, 356, 568, -1, 466, -1, 420, + -1, -1, 441, 832, -1, 95, 616, 407, 832, 501, + 603, 502, 592, 584, -1, 95, 616, 407, 190, 272, + 152, 832, 501, 603, 502, 592, 584, -1, 95, 292, + 345, 616, 407, 832, 501, 603, 502, 592, 584, -1, + -1, 571, 596, -1, 611, -1, 925, -1, 791, -1, + 563, -1, 840, -1, 271, -1, 501, 561, 502, -1, + -1, 840, -1, 270, 24, -1, 350, -1, 60, -1, + 377, 277, -1, 377, 117, -1, 88, 835, 577, -1, + 577, -1, 591, -1, 75, 846, -1, 272, 277, -1, + 277, -1, 435, 602, -1, 321, 224, 602, -1, 69, + 501, 760, 502, 586, -1, 443, 83, 835, -1, 117, + 761, -1, 337, 832, 605, 614, 583, -1, 457, -1, + 397, -1, 578, -1, -1, 175, 617, 38, 189, 573, + -1, 175, 617, 38, 501, 760, 502, 579, -1, 38, + 501, 760, 502, 579, -1, 595, 574, -1, 287, 440, + 575, -1, 582, -1, 607, -1, 582, 607, -1, 607, + 582, -1, -1, 287, 81, 137, -1, 287, 81, 122, + 359, -1, 287, 81, 320, 359, -1, -1, 501, 589, + 502, -1, 270, 202, -1, -1, 88, 835, 612, -1, + 612, -1, 80, -1, 89, -1, 118, -1, 189, -1, + 201, -1, 393, -1, 396, -1, 29, -1, 608, -1, + 589, 505, 608, -1, 443, 200, 599, -1, 119, -1, + 272, 119, -1, 204, 120, -1, 204, 193, -1, 463, + 585, -1, 463, 285, -1, 465, 285, -1, -1, 501, + 598, 502, -1, 594, 198, 588, -1, 594, 149, 588, + -1, -1, 850, -1, 272, 119, -1, 119, -1, 204, + 193, -1, 204, 120, -1, 272, 445, -1, 270, 202, + -1, 841, 730, 606, -1, 841, 729, 580, 606, -1, + 601, -1, 598, 505, 601, -1, 841, -1, 597, -1, + 615, -1, 587, -1, 850, 490, 572, -1, 850, -1, + 463, 593, -1, -1, 613, -1, 613, 505, -1, -1, + 841, -1, 501, 609, 502, -1, -1, 606, 576, -1, + -1, 287, 122, 575, -1, 850, 490, 572, -1, 850, + -1, 850, 503, 850, 490, 572, -1, 850, 503, 850, + -1, 604, -1, 609, 505, 604, -1, 609, -1, 609, + 505, -1, 730, -1, 843, 847, 496, 429, -1, 378, + 843, 847, 496, 429, -1, 69, 501, 760, 502, 571, + -1, 435, 501, 610, 502, 602, 571, -1, 435, 590, + 571, -1, 321, 224, 501, 610, 502, 602, 571, -1, + 321, 224, 590, 571, -1, 168, 224, 501, 610, 502, + 337, 832, 605, 614, 583, 571, -1, 600, -1, 613, + 505, 600, -1, 248, 172, -1, 248, 305, -1, 248, + 383, -1, -1, 234, 832, 594, -1, 413, -1, 411, + -1, 238, 413, -1, 238, 411, -1, 177, 413, -1, + 177, 411, -1, 438, -1, -1, 32, -1, 56, 117, + -1, 137, 619, 190, 152, 621, 622, -1, 137, 619, + 621, 622, -1, 137, 620, 190, 152, 833, 622, -1, + 137, 620, 833, 622, -1, 137, 623, 835, 287, 846, + 622, -1, 137, 623, 190, 152, 835, 287, 846, 622, + -1, 137, 429, 624, 622, -1, 137, 429, 190, 152, + 624, 622, -1, 407, -1, 110, -1, 371, -1, 173, + -1, 245, -1, 245, 407, -1, 455, -1, 249, 455, + -1, 200, -1, 168, 407, -1, 76, -1, 92, -1, + 363, -1, 393, -1, 414, 366, 304, -1, 414, 366, + 129, -1, 414, 366, 412, -1, 414, 366, 85, -1, + 23, 251, -1, 146, 423, -1, 156, -1, 168, 109, + 467, -1, 327, -1, 374, -1, 846, -1, 621, 505, + 846, -1, 60, -1, 350, -1, -1, 312, -1, 360, + -1, 423, -1, 730, -1, 624, 505, 730, -1, 95, + 616, 626, 832, 627, 38, 407, 646, -1, 95, 616, + 626, 190, 272, 152, 832, 627, 38, 407, 646, -1, + 95, 292, 345, 616, 626, 832, 627, 38, 407, 646, + -1, 95, 616, 626, 832, 627, 38, 760, -1, 95, + 616, 626, 190, 272, 152, 832, 627, 38, 760, -1, + 95, 292, 345, 616, 626, 832, 627, 38, 760, -1, + 173, -1, 245, -1, 501, 502, -1, 501, 797, 502, + -1, 534, 440, 896, 377, 547, 706, 897, 540, -1, + 93, 641, 832, 605, 639, 630, 635, 644, 631, 562, + 636, -1, 93, 501, 646, 502, 418, 635, 644, 562, + 636, -1, 171, -1, 418, -1, 633, 124, 840, -1, + -1, 643, -1, 632, 505, 643, -1, 443, -1, -1, + 38, -1, -1, 326, -1, -1, 640, -1, 501, 645, + 502, -1, 879, -1, 563, -1, 494, -1, 501, 632, + 502, -1, -1, 850, 637, -1, 463, 285, -1, -1, + 640, 642, -1, -1, 52, -1, -1, 52, -1, 285, + -1, 170, -1, 123, 634, 840, -1, 277, 634, 840, + -1, 97, -1, 185, -1, 329, 634, 840, -1, 145, + 634, 840, -1, 167, 329, 609, -1, 167, 329, 494, + -1, 306, 56, 609, -1, 306, 56, 494, -1, 167, + 272, 277, 609, -1, 167, 277, 609, -1, 141, 840, + -1, 879, -1, 840, -1, 394, -1, 395, -1, 638, + -1, 645, 505, 638, -1, 648, -1, 647, -1, 501, + 648, 502, -1, 501, 647, 502, -1, 651, -1, 649, + 664, -1, 649, 663, 697, 670, -1, 649, 663, 669, + 698, -1, 652, 649, -1, 652, 649, 664, -1, 652, + 649, 663, 697, 670, -1, 652, 649, 663, 669, 698, + -1, 651, -1, 647, -1, 370, 661, 821, -1, -1, + 370, 661, 821, 655, 706, 723, 686, 695, 772, 696, + 674, -1, 370, 660, 823, 655, 706, 723, 686, 695, + 772, 696, 674, -1, 171, 707, 650, 655, 723, 686, + 695, 772, 696, 674, -1, 171, 707, 370, 660, 823, + 655, 723, 686, 695, 772, 696, 674, -1, 705, -1, + 407, 717, -1, 649, 434, 658, 659, 649, -1, 649, + 434, 658, 649, -1, 649, 215, 658, 649, -1, 649, + 147, 658, 649, -1, 463, 653, -1, 487, 653, -1, + 463, 335, 653, -1, 654, -1, 653, 505, 654, -1, + 835, 848, 38, 501, 855, 502, -1, 217, 656, -1, + -1, 413, 657, 832, -1, 411, 657, 832, -1, 238, + 413, 657, 832, -1, 238, 411, 657, 832, -1, 177, + 413, 657, 832, -1, 177, 411, 657, 832, -1, 438, + 657, 832, -1, 407, 832, -1, 832, -1, 407, -1, + -1, 29, -1, 132, -1, -1, 56, 263, -1, 132, + -1, 132, 287, 501, 795, 502, -1, 29, -1, -1, + 191, 279, -1, 348, 279, -1, -1, 664, -1, -1, + 293, 56, 665, -1, 293, 56, 29, 667, 668, -1, + 293, 56, 494, 667, 668, -1, 666, -1, 665, 505, + 666, -1, 760, 443, 791, 668, -1, 760, 667, 668, + -1, 39, -1, 126, -1, -1, 486, 163, -1, 486, + 228, -1, -1, 671, 672, -1, 672, 671, -1, 671, + -1, 672, -1, 669, -1, -1, 235, 680, -1, 235, + 680, 505, 681, -1, 161, 685, 682, 684, 288, -1, + 161, 685, 684, 288, -1, 284, 681, -1, 284, 682, + 684, -1, 4, 496, -1, 9, 496, -1, 4, 309, + -1, 9, 309, -1, 9, -1, 9, 359, -1, 443, + 361, 676, -1, -1, 841, -1, -1, 675, 501, 673, + 502, 679, -1, 673, -1, 673, 501, 841, 502, -1, + 673, 501, 841, 505, 9, 502, -1, 409, 676, -1, + 677, -1, -1, 344, 501, 9, 502, -1, -1, 760, + -1, 29, -1, 760, 496, -1, 4, 309, -1, 9, + 309, -1, 760, -1, 762, -1, 492, 683, -1, 493, + 683, -1, 839, -1, 4, -1, 358, -1, 359, -1, + 163, -1, 269, -1, 180, 56, 688, -1, 180, 56, + 29, -1, 180, 56, 494, -1, -1, 689, -1, 687, + 505, 689, -1, 687, -1, 687, 505, -1, 760, -1, + 690, -1, 692, -1, 691, -1, 693, -1, 501, 502, + -1, 357, 501, 795, 502, -1, 98, 501, 795, 502, + -1, 181, 379, 501, 688, 502, -1, 181, -1, 182, + -1, 184, 760, -1, -1, 328, 760, -1, -1, 699, + -1, 166, 331, 288, -1, 697, -1, -1, 700, -1, + 699, 700, -1, 701, 702, 703, -1, 166, 440, -1, + 166, 270, 224, 440, -1, 166, 380, -1, 166, 224, + 380, -1, 282, 831, -1, -1, 276, -1, 384, 243, + -1, -1, 449, 501, 795, 502, -1, 704, 505, 501, + 795, 502, -1, 704, -1, 704, 505, -1, 171, 708, + -1, -1, 709, -1, 707, 505, 709, -1, 707, -1, + 707, 505, -1, 717, 712, 678, -1, 718, 713, 678, + -1, 705, 711, 678, -1, 229, 718, 713, -1, 647, + 712, 678, -1, 229, 647, 712, -1, 710, -1, 501, + 710, 502, 711, -1, 501, 710, 502, -1, 709, 96, + 222, 709, -1, 709, 714, 222, 709, 716, -1, 709, + 222, 709, 716, -1, 709, 266, 714, 222, 709, -1, + 709, 266, 222, 709, -1, 709, 314, 222, 709, -1, + 38, 842, 501, 834, 502, -1, 38, 842, -1, 841, + 501, 834, 502, -1, 841, -1, 711, -1, -1, 711, + -1, 38, 501, 724, 502, -1, 38, 842, 501, 724, + 502, -1, 841, 501, 724, 502, -1, -1, 172, 715, + -1, 232, 715, -1, 354, 715, -1, 206, -1, 296, + -1, -1, 443, 501, 834, 502, -1, 287, 760, -1, + 832, -1, 832, 494, -1, 288, 832, -1, 288, 501, + 832, 502, -1, 766, 722, -1, 359, 171, 501, 720, + 502, 722, -1, 766, 721, -1, 719, -1, 720, 505, + 719, -1, 38, 501, 724, 502, -1, -1, 487, 294, + -1, -1, 460, 760, -1, -1, 725, -1, 724, 505, + 725, -1, 842, 730, 726, -1, 75, 846, -1, -1, + 841, 730, -1, 727, 505, 841, 730, -1, 358, -1, + 400, -1, 730, -1, -1, 732, 731, -1, 378, 732, + 731, -1, 732, 37, 499, 839, 500, -1, 378, 732, + 37, 499, 839, 500, -1, 732, 37, -1, 378, 732, + 37, -1, 728, 501, 727, 502, 731, -1, 246, 501, + 799, 502, 731, -1, 434, 501, 727, 502, 731, -1, + 731, 499, 500, -1, 731, 499, 839, 500, -1, -1, + 734, -1, 736, -1, 738, -1, 742, -1, 748, -1, + 749, 759, -1, 749, 501, 839, 502, -1, 736, -1, + 739, -1, 743, -1, 748, -1, 845, 735, -1, 501, + 796, 502, -1, -1, 213, -1, 214, -1, 385, -1, + 51, -1, 332, -1, 164, 737, -1, 136, 317, -1, + 115, 735, -1, 114, 735, -1, 280, 735, -1, 54, + -1, 501, 839, 502, -1, -1, 740, -1, 741, -1, + 740, -1, 741, -1, 53, 747, 501, 795, 502, -1, + 53, 747, -1, 744, -1, 745, -1, 744, -1, 745, + -1, 746, 501, 839, 502, -1, 746, -1, 67, 747, + -1, 66, 747, -1, 450, -1, 265, 67, 747, -1, + 265, 66, 747, -1, 267, 747, -1, 452, -1, -1, + 417, 501, 839, 502, 750, -1, 417, 750, -1, 416, + 501, 839, 502, 750, -1, 416, 750, -1, 216, -1, + 487, 416, 484, -1, 465, 416, 484, -1, -1, 481, + -1, 482, -1, 260, -1, 261, -1, 111, -1, 112, + -1, 187, -1, 188, -1, 256, -1, 257, -1, 367, + -1, 368, -1, 254, -1, 255, -1, 252, -1, 253, + -1, 751, -1, 752, -1, 753, -1, 754, -1, 755, + -1, 756, -1, 757, -1, 758, -1, 751, 418, 752, + -1, 753, 418, 754, -1, 753, 418, 755, -1, 753, + 418, 756, -1, 754, 418, 755, -1, 754, 418, 756, + -1, 755, 418, 756, -1, -1, 762, -1, 760, 11, + 730, -1, 760, 75, 846, -1, 760, 43, 416, 484, + 760, -1, 492, 760, -1, 493, 760, -1, 760, 492, + 760, -1, 760, 493, 760, -1, 760, 494, 760, -1, + 760, 495, 760, -1, 760, 496, 760, -1, 760, 497, + 760, -1, 760, 15, 760, -1, 760, 488, 760, -1, + 760, 489, 760, -1, 760, 490, 760, -1, 760, 18, + 760, -1, 760, 19, 760, -1, 760, 20, 760, -1, + 760, 790, 760, -1, 790, 760, -1, 760, 790, -1, + 760, 35, 760, -1, 760, 292, 760, -1, 272, 760, + -1, 485, 760, -1, 760, 176, 760, -1, 760, 234, + 760, -1, 760, 234, 760, 145, 760, -1, 760, 485, + 234, 760, -1, 760, 485, 234, 760, 145, 760, -1, + 760, 192, 760, -1, 760, 192, 760, 145, 760, -1, + 760, 485, 192, 760, -1, 760, 485, 192, 760, 145, + 760, -1, 760, 382, 418, 760, -1, 760, 382, 418, + 760, 145, 760, -1, 760, 485, 382, 418, 760, -1, + 760, 485, 382, 418, 760, 145, 760, -1, 760, 219, + 277, -1, 760, 220, -1, 760, 219, 272, 277, -1, + 760, 272, 277, -1, 760, 275, -1, 760, 16, 760, + -1, 760, 17, 760, -1, 783, 298, 783, -1, 760, + 219, 425, -1, 760, 219, 272, 425, -1, 760, 219, + 159, -1, 760, 219, 272, 159, -1, 760, 219, 436, + -1, 760, 219, 272, 436, -1, 760, 219, 132, 171, + 760, -1, 760, 219, 272, 132, 171, 760, -1, 760, + 219, 282, 501, 799, 502, -1, 760, 219, 272, 282, + 501, 799, 502, -1, 760, 50, 820, 761, 35, 760, + -1, 760, 485, 50, 820, 761, 35, 760, -1, 760, + 50, 404, 761, 35, 760, -1, 760, 485, 50, 404, + 761, 35, 760, -1, 760, 197, 809, -1, 760, 485, + 197, 809, -1, 760, 792, 787, 647, -1, 760, 792, + 787, 501, 760, 502, -1, 117, -1, 78, 501, 494, + 826, 830, 502, -1, 78, 501, 840, 502, -1, 762, + -1, 761, 11, 730, -1, 492, 761, -1, 493, 761, + -1, 761, 492, 761, -1, 761, 493, 761, -1, 761, + 494, 761, -1, 761, 495, 761, -1, 761, 496, 761, + -1, 761, 497, 761, -1, 761, 15, 761, -1, 761, + 488, 761, -1, 761, 489, 761, -1, 761, 490, 761, + -1, 761, 18, 761, -1, 761, 19, 761, -1, 761, + 20, 761, -1, 761, 790, 761, -1, 790, 761, -1, + 761, 790, -1, 761, 219, 132, 171, 761, -1, 761, + 219, 272, 132, 171, 761, -1, 761, 219, 282, 501, + 799, 502, -1, 761, 219, 272, 282, 501, 799, 502, + -1, 815, -1, 838, -1, 506, 9, -1, 763, 819, + -1, 507, 852, -1, 783, -1, 499, 796, 500, -1, + 768, -1, 37, 647, -1, 37, 499, 796, 500, -1, + 810, -1, 647, -1, 647, 818, -1, 152, 647, -1, + 694, 501, 795, 502, -1, 508, -1, 10, -1, 501, + 760, 502, -1, 509, 786, 510, -1, 765, -1, 837, + 501, 502, -1, 837, 501, 797, 663, 662, 502, -1, + 837, 501, 451, 798, 663, 662, 502, -1, 837, 501, + 797, 505, 451, 798, 663, 662, 502, -1, 837, 501, + 29, 797, 663, 662, 502, -1, 837, 501, 132, 797, + 663, 662, 502, -1, 837, 501, 494, 502, -1, 764, + 769, 770, 771, 775, -1, 767, -1, 764, -1, 767, + -1, 76, 166, 501, 760, 502, -1, 101, -1, 104, + -1, 104, 501, 839, 502, -1, 105, -1, 105, 501, + 839, 502, -1, 239, -1, 239, 501, 839, 502, -1, + 240, -1, 240, 501, 839, 502, -1, 102, -1, 106, + -1, 376, -1, 442, -1, 100, -1, 103, -1, 63, + 501, 760, 38, 730, 502, -1, 428, 501, 760, 38, + 730, 502, -1, 158, 501, 800, 502, -1, 299, 501, + 802, 502, -1, 313, 501, 804, 502, -1, 402, 501, + 805, 502, -1, 422, 501, 760, 38, 730, 502, -1, + 424, 501, 55, 808, 502, -1, 424, 501, 230, 808, + 502, -1, 424, 501, 419, 808, 502, -1, 424, 501, + 808, 502, -1, 278, 501, 760, 505, 760, 502, -1, + 74, 501, 795, 502, -1, 499, 760, 166, 841, 197, + 760, 500, -1, 499, 760, 166, 841, 197, 762, 190, + 760, 500, -1, 464, 180, 501, 664, 502, -1, -1, + 162, 501, 460, 760, 502, -1, 162, 501, 760, 502, + -1, -1, 155, -1, -1, 462, 773, -1, -1, 774, + -1, 773, 505, 774, -1, 841, 38, 776, -1, 297, + 776, -1, 297, 841, -1, -1, 501, 777, 778, 663, + 779, 502, -1, 841, -1, -1, 306, 56, 794, -1, + -1, 330, 780, -1, 359, 780, -1, -1, 781, -1, + 50, 781, 35, 781, -1, 431, 316, -1, 431, 165, + -1, 99, 358, -1, 760, 316, -1, 760, 165, -1, + 358, 501, 795, 502, -1, 358, 501, 502, -1, 782, + -1, 501, 794, 505, 760, 502, -1, 842, 511, 760, + -1, 784, -1, 785, 505, 784, -1, 785, -1, 785, + 505, -1, 36, -1, 387, -1, 29, -1, 8, -1, + 789, -1, 492, -1, 493, -1, 494, -1, 495, -1, + 496, -1, 497, -1, 15, -1, 488, -1, 489, -1, + 490, -1, 18, -1, 19, -1, 20, -1, 8, -1, + 289, 501, 793, 502, -1, 788, -1, 289, 501, 793, + 502, -1, 788, -1, 289, 501, 793, 502, -1, 234, + -1, 485, 234, -1, 176, -1, 485, 176, -1, 192, + -1, 485, 192, -1, 788, -1, 841, 503, 793, -1, + 760, -1, 794, 505, 760, -1, 794, -1, 794, 505, + -1, 795, -1, -1, 798, -1, 797, 505, 798, -1, + 760, -1, 849, 13, 760, -1, 849, 14, 760, -1, + 730, -1, 799, 505, 730, -1, 801, 171, 760, -1, + -1, 3, -1, 751, -1, 752, -1, 753, -1, 754, + -1, 755, -1, 756, -1, 757, -1, 758, -1, 840, + -1, 760, 803, 806, 807, -1, 760, 803, 806, -1, + 310, 760, -1, 761, 197, 761, -1, -1, 760, 806, + 807, -1, 760, 807, 806, -1, 760, 806, -1, 760, + 807, -1, 794, -1, -1, 171, 760, -1, 166, 760, + -1, 760, 171, 795, -1, 171, 795, -1, 795, -1, + 647, -1, 501, 795, 502, -1, 62, 814, 811, 813, + 143, -1, 812, -1, 811, 812, -1, 459, 760, 415, + 760, -1, 139, 760, -1, -1, 760, -1, -1, 841, + -1, 841, 818, -1, 503, 836, -1, 499, 760, 500, + -1, 499, 817, 511, 817, 500, -1, 760, -1, -1, + 816, -1, 818, 816, -1, -1, 819, 816, -1, 42, + -1, -1, 823, -1, -1, 824, -1, 822, 505, 824, + -1, 822, -1, 822, 505, -1, 760, 38, 851, -1, + 760, 3, -1, 760, -1, 494, 826, 830, -1, 841, + 503, 494, 826, 830, -1, 148, 501, 834, 502, -1, + 148, 841, -1, 825, -1, -1, 760, 38, 841, -1, + 827, -1, 828, 505, 827, -1, 828, -1, 828, 505, + -1, 345, 501, 829, 502, -1, 345, 827, -1, -1, + 832, -1, 831, 505, 832, -1, 842, -1, 841, 818, + -1, 835, -1, 833, 505, 835, -1, 833, -1, 833, + 505, -1, 842, -1, 850, -1, 844, -1, 841, 818, + -1, 839, -1, 4, -1, 840, 819, -1, 6, -1, + 7, -1, 837, 840, -1, 837, 501, 797, 663, 662, + 502, 840, -1, 733, 840, -1, 749, 501, 760, 502, + 759, -1, 749, 839, 759, -1, 749, 840, 759, -1, + 425, -1, 159, -1, 277, -1, 9, -1, 5, -1, + 3, -1, 919, -1, 920, -1, 841, -1, 5, -1, + 3, -1, 919, -1, 924, -1, 3, -1, 919, -1, + 921, -1, 3, -1, 919, -1, 922, -1, 841, -1, + 841, 847, -1, 503, 836, -1, 847, 503, 836, -1, + 501, 834, 502, -1, -1, 843, -1, 3, -1, 923, + -1, 919, -1, 925, -1, 850, -1, 5, -1, 3, + -1, 318, 835, 854, 38, 855, -1, 501, 799, 502, + -1, -1, 646, -1, 530, -1, 628, -1, 895, -1, + 95, 363, 832, 857, -1, 95, 363, 190, 272, 152, + 832, 857, -1, 857, 858, -1, -1, 570, -1, 859, + -1, 556, -1, 914, -1, 95, 865, 200, 862, 863, + 287, 832, 861, 501, 548, 502, 864, 723, -1, 95, + 865, 200, 862, 190, 272, 152, 599, 287, 832, 861, + 501, 548, 502, 864, 723, -1, 841, -1, 443, 860, + -1, -1, 84, -1, -1, 599, -1, -1, 463, 585, + -1, -1, 435, -1, -1, 31, 407, 717, 377, 363, + 835, -1, 31, 407, 190, 152, 717, 377, 363, 835, + -1, 31, 371, 832, 377, 363, 835, -1, 31, 371, + 190, 152, 832, 377, 363, 835, -1, 31, 455, 832, + 377, 363, 835, -1, 31, 455, 190, 152, 832, 377, + 363, 835, -1, 167, 70, 868, -1, 70, 868, -1, + 841, -1, -1, 154, 110, 840, 636, -1, 154, 110, + 841, 418, 840, 636, -1, 196, 110, 840, -1, 153, + 874, -1, 153, 878, 872, 874, -1, 153, 453, 874, + -1, 153, 501, 877, 502, 874, -1, 453, -1, -1, + 879, -1, 563, -1, -1, 866, -1, 560, -1, 516, + -1, 913, -1, 867, -1, 629, -1, 916, -1, 625, + -1, 856, -1, 556, -1, 570, -1, 550, -1, 527, + -1, 895, -1, 618, -1, 558, -1, 859, -1, 530, + -1, 888, -1, 553, -1, 853, -1, 528, -1, 646, + -1, 567, -1, 628, -1, 890, -1, 906, -1, 882, + -1, 909, -1, 914, -1, 3, -1, 919, -1, 923, + -1, 875, -1, 840, -1, 880, -1, 877, 505, 880, + -1, 34, -1, 33, -1, 425, -1, 159, -1, 287, + -1, 876, -1, 881, 873, -1, 875, -1, 878, -1, + 377, 883, -1, 377, 238, 883, -1, 377, 375, 883, + -1, 377, 177, 883, -1, 884, -1, 911, 171, 99, + -1, 416, 484, 886, -1, 363, 840, -1, 911, 418, + 887, -1, 911, 490, 887, -1, 911, 418, 117, -1, + 911, 490, 117, -1, 879, -1, 563, -1, 840, -1, + 3, -1, 749, 840, 759, -1, 749, 501, 839, 502, + 840, -1, 563, -1, 117, -1, 238, -1, 885, -1, + 887, 505, 885, -1, 237, 889, -1, 211, 889, -1, + 167, 211, 889, -1, 840, -1, 841, -1, 444, 892, + 894, 872, -1, 444, 892, 894, 872, 832, -1, 444, + 892, 894, 872, 899, -1, 444, 501, 893, 502, -1, + 444, 501, 893, 502, 832, 848, -1, 878, -1, 453, + -1, 170, -1, 172, -1, 3, -1, 172, -1, -1, + 891, -1, 893, 505, 891, -1, 170, -1, -1, 534, + 122, 171, 896, 898, 897, 540, -1, 426, 657, 896, + -1, 717, -1, 717, 841, -1, 717, 38, 841, -1, + 460, 760, -1, -1, 443, 708, -1, -1, 878, 872, + -1, 878, 872, 832, 848, -1, 44, 902, 840, 903, + 636, -1, 128, 110, 621, -1, 128, 905, -1, 128, + 110, 190, 152, 621, -1, 110, -1, -1, 38, 841, + -1, -1, 3, -1, 904, -1, 905, 505, 904, -1, + 347, 908, -1, 911, -1, 29, -1, 907, -1, 416, + 484, -1, 420, 221, 233, -1, 910, 646, -1, 403, + 646, -1, 403, 912, -1, 910, 912, -1, 910, 416, + 484, -1, 910, 420, 221, 233, -1, 910, 29, -1, + 910, -1, 381, -1, 127, -1, 841, -1, 911, 503, + 841, -1, 841, -1, 912, 503, 841, -1, 58, 764, + -1, 95, 616, 455, 832, 605, 864, 38, 646, 915, + -1, 95, 616, 455, 190, 272, 152, 832, 605, 864, + 38, 646, 915, -1, 95, 292, 345, 616, 455, 832, + 605, 864, 38, 646, 915, -1, 95, 616, 335, 455, + 832, 501, 609, 502, 864, 38, 646, 915, -1, 95, + 292, 345, 616, 335, 455, 832, 501, 609, 502, 864, + 38, 646, 915, -1, 463, 69, 290, -1, 463, 61, + 69, 290, -1, 463, 238, 69, 290, -1, -1, 95, + 616, 407, 918, 38, 646, 917, -1, 95, 616, 407, + 190, 272, 152, 918, 38, 646, 917, -1, 95, 292, + 345, 616, 407, 918, 38, 646, 917, -1, 463, 109, + -1, 463, 270, 109, -1, -1, 832, 605, 592, 584, + -1, 21, -1, 22, -1, 23, -1, 24, -1, 25, + -1, 26, -1, 27, -1, 28, -1, 30, -1, 31, + -1, 32, -1, 40, -1, 41, -1, 43, -1, 44, + -1, 45, -1, 47, -1, 48, -1, 49, -1, 56, + -1, 57, -1, 58, -1, 59, -1, 60, -1, 61, + -1, 64, -1, 65, -1, 68, -1, 70, -1, 71, + -1, 72, -1, 73, -1, 79, -1, 80, -1, 81, + -1, 82, -1, 83, -1, 85, -1, 86, -1, 87, + -1, 89, -1, 90, -1, 91, -1, 92, -1, 93, + -1, 94, -1, 97, -1, 98, -1, 99, -1, 107, + -1, 108, -1, 109, -1, 110, -1, 111, -1, 112, + -1, 113, -1, 116, -1, 118, -1, 120, -1, 121, + -1, 122, -1, 123, -1, 124, -1, 125, -1, 127, + -1, 128, -1, 129, -1, 130, -1, 131, -1, 134, + -1, 135, -1, 136, -1, 137, -1, 138, -1, 140, + -1, 141, -1, 142, -1, 144, -1, 145, -1, 146, + -1, 148, -1, 149, -1, 150, -1, 151, -1, 153, + -1, 154, -1, 155, -1, 156, -1, 157, -1, 160, + -1, 162, -1, 163, -1, 165, -1, 167, -1, 169, + -1, 173, -1, 174, -1, 177, -1, 179, -1, 183, + -1, 185, -1, 186, -1, 187, -1, 188, -1, 189, + -1, 190, -1, 191, -1, 193, -1, 194, -1, 195, + -1, 196, -1, 198, -1, 199, -1, 200, -1, 201, + -1, 202, -1, 203, -1, 205, -1, 208, -1, 209, + -1, 210, -1, 211, -1, 212, -1, 218, -1, 221, + -1, 223, -1, 224, -1, 225, -1, 226, -1, 227, + -1, 228, -1, 231, -1, 233, -1, 236, -1, 237, + -1, 238, -1, 241, -1, 242, -1, 243, -1, 244, + -1, 245, -1, 247, -1, 248, -1, 249, -1, 250, + -1, 251, -1, 252, -1, 253, -1, 254, -1, 255, + -1, 256, -1, 257, -1, 258, -1, 259, -1, 260, + -1, 261, -1, 262, -1, 263, -1, 264, -1, 268, + -1, 269, -1, 270, -1, 273, -1, 274, -1, 276, + -1, 279, -1, 281, -1, 282, -1, 283, -1, 285, + -1, 286, -1, 289, -1, 290, -1, 291, -1, 294, + -1, 297, -1, 300, -1, 301, -1, 302, -1, 303, + -1, 304, -1, 305, -1, 306, -1, 307, -1, 308, + -1, 309, -1, 311, -1, 312, -1, 315, -1, 316, + -1, 318, -1, 319, -1, 320, -1, 322, -1, 323, + -1, 324, -1, 325, -1, 326, -1, 327, -1, 329, + -1, 330, -1, 331, -1, 333, -1, 334, -1, 335, + -1, 336, -1, 338, -1, 339, -1, 340, -1, 341, + -1, 342, -1, 343, -1, 344, -1, 345, -1, 346, + -1, 347, -1, 348, -1, 349, -1, 350, -1, 352, + -1, 353, -1, 355, -1, 356, -1, 357, -1, 359, + -1, 360, -1, 361, -1, 362, -1, 363, -1, 364, + -1, 365, -1, 366, -1, 367, -1, 368, -1, 369, + -1, 371, -1, 372, -1, 373, -1, 374, -1, 375, + -1, 377, -1, 379, -1, 380, -1, 381, -1, 383, + -1, 384, -1, 386, -1, 388, -1, 389, -1, 390, + -1, 391, -1, 392, -1, 393, -1, 394, -1, 395, + -1, 396, -1, 397, -1, 398, -1, 399, -1, 401, + -1, 403, -1, 405, -1, 406, -1, 408, -1, 410, + -1, 411, -1, 412, -1, 413, -1, 414, -1, 420, + -1, 421, -1, 423, -1, 426, -1, 427, -1, 429, + -1, 430, -1, 431, -1, 432, -1, 433, -1, 436, + -1, 437, -1, 438, -1, 439, -1, 440, -1, 441, + -1, 444, -1, 445, -1, 446, -1, 447, -1, 448, + -1, 452, -1, 454, -1, 455, -1, 456, -1, 457, + -1, 458, -1, 461, -1, 464, -1, 465, -1, 466, + -1, 467, -1, 468, -1, 469, -1, 481, -1, 482, + -1, 483, -1, 484, -1, 50, -1, 51, -1, 53, + -1, 54, -1, 66, -1, 67, -1, 74, -1, 78, + -1, 114, -1, 115, -1, 152, -1, 158, -1, 164, + -1, 175, -1, 181, -1, 182, -1, 207, -1, 213, + -1, 214, -1, 216, -1, 246, -1, 265, -1, 267, + -1, 271, -1, 278, -1, 280, -1, 295, -1, 299, + -1, 313, -1, 317, -1, 332, -1, 358, -1, 378, + -1, 385, -1, 400, -1, 402, -1, 416, -1, 417, + -1, 422, -1, 424, -1, 428, -1, 449, -1, 450, + -1, 470, -1, 471, -1, 472, -1, 473, -1, 474, + -1, 475, -1, 476, -1, 477, -1, 478, -1, 479, + -1, 480, -1, 46, -1, 52, -1, 76, -1, 84, + -1, 96, -1, 100, -1, 101, -1, 102, -1, 103, + -1, 106, -1, 170, -1, 172, -1, 175, -1, 176, -1, 192, -1, 206, -1, 219, -1, 220, -1, 222, - -1, 232, -1, 234, -1, 266, -1, 275, -1, 296, - -1, 298, -1, 353, -1, 375, -1, 381, -1, 408, - -1, 427, -1, 440, -1, 451, -1, 46, -1, 50, + -1, 232, -1, 234, -1, 246, -1, 266, -1, 275, + -1, 296, -1, 298, -1, 314, -1, 354, -1, 376, + -1, 382, -1, 400, -1, 409, -1, 442, -1, 453, + -1, 46, -1, 52, -1, 76, -1, 78, -1, 84, + -1, 96, -1, 100, -1, 101, -1, 102, -1, 103, + -1, 106, -1, 170, -1, 172, -1, 176, -1, 192, + -1, 206, -1, 219, -1, 220, -1, 222, -1, 232, + -1, 234, -1, 266, -1, 275, -1, 296, -1, 298, + -1, 314, -1, 354, -1, 376, -1, 382, -1, 409, + -1, 428, -1, 442, -1, 453, -1, 46, -1, 50, -1, 51, -1, 52, -1, 53, -1, 54, -1, 67, -1, 66, -1, 74, -1, 76, -1, 78, -1, 84, -1, 96, -1, 100, -1, 101, -1, 102, -1, 103, @@ -296063,172 +309852,177 @@ static const yytype_int16 yyrhs[] = -1, 222, -1, 232, -1, 234, -1, 246, -1, 265, -1, 266, -1, 267, -1, 271, -1, 275, -1, 278, -1, 280, -1, 296, -1, 295, -1, 298, -1, 299, - -1, 313, -1, 316, -1, 331, -1, 353, -1, 357, - -1, 375, -1, 377, -1, 381, -1, 384, -1, 399, - -1, 401, -1, 408, -1, 415, -1, 416, -1, 421, - -1, 423, -1, 427, -1, 440, -1, 447, -1, 448, - -1, 451, -1, 468, -1, 469, -1, 470, -1, 471, - -1, 472, -1, 473, -1, 474, -1, 475, -1, 476, - -1, 477, -1, 478, -1, 46, -1, 52, -1, 76, - -1, 78, -1, 84, -1, 96, -1, 100, -1, 101, - -1, 102, -1, 103, -1, 106, -1, 170, -1, 172, - -1, 175, -1, 176, -1, 192, -1, 206, -1, 219, - -1, 220, -1, 222, -1, 232, -1, 234, -1, 246, - -1, 266, -1, 275, -1, 296, -1, 298, -1, 353, - -1, 375, -1, 381, -1, 399, -1, 408, -1, 427, - -1, 440, -1, 451, -1, 29, -1, 33, -1, 34, - -1, 35, -1, 36, -1, 37, -1, 38, -1, 39, - -1, 42, -1, 55, -1, 62, -1, 63, -1, 69, - -1, 75, -1, 77, -1, 88, -1, 95, -1, 104, - -1, 105, -1, 117, -1, 119, -1, 126, -1, 132, - -1, 133, -1, 139, -1, 143, -1, 147, -1, 159, - -1, 161, -1, 166, -1, 168, -1, 171, -1, 178, - -1, 180, -1, 184, -1, 197, -1, 204, -1, 215, - -1, 217, -1, 229, -1, 230, -1, 235, -1, 239, - -1, 240, -1, 272, -1, 277, -1, 284, -1, 287, - -1, 288, -1, 292, -1, 293, -1, 310, -1, 320, - -1, 327, -1, 336, -1, 350, -1, 369, -1, 386, - -1, 403, -1, 406, -1, 414, -1, 417, -1, 418, - -1, 424, -1, 433, -1, 434, -1, 441, -1, 449, - -1, 457, -1, 458, -1, 460, -1, 461, -1 + -1, 313, -1, 314, -1, 317, -1, 332, -1, 354, + -1, 358, -1, 376, -1, 378, -1, 382, -1, 385, + -1, 400, -1, 402, -1, 409, -1, 416, -1, 417, + -1, 422, -1, 424, -1, 428, -1, 442, -1, 449, + -1, 450, -1, 453, -1, 470, -1, 471, -1, 472, + -1, 473, -1, 474, -1, 475, -1, 476, -1, 477, + -1, 478, -1, 479, -1, 480, -1, 46, -1, 52, + -1, 76, -1, 78, -1, 84, -1, 96, -1, 100, + -1, 101, -1, 102, -1, 103, -1, 106, -1, 170, + -1, 172, -1, 175, -1, 176, -1, 192, -1, 206, + -1, 219, -1, 220, -1, 222, -1, 232, -1, 234, + -1, 246, -1, 266, -1, 275, -1, 296, -1, 298, + -1, 314, -1, 354, -1, 376, -1, 382, -1, 400, + -1, 409, -1, 428, -1, 442, -1, 453, -1, 29, + -1, 33, -1, 34, -1, 35, -1, 36, -1, 37, + -1, 38, -1, 39, -1, 42, -1, 55, -1, 62, + -1, 63, -1, 69, -1, 75, -1, 77, -1, 88, + -1, 95, -1, 104, -1, 105, -1, 117, -1, 119, + -1, 126, -1, 132, -1, 133, -1, 139, -1, 143, + -1, 147, -1, 159, -1, 161, -1, 166, -1, 168, + -1, 171, -1, 178, -1, 180, -1, 184, -1, 197, + -1, 204, -1, 215, -1, 217, -1, 229, -1, 230, + -1, 235, -1, 239, -1, 240, -1, 272, -1, 277, + -1, 284, -1, 287, -1, 288, -1, 292, -1, 293, + -1, 310, -1, 321, -1, 328, -1, 337, -1, 351, + -1, 370, -1, 387, -1, 404, -1, 407, -1, 415, + -1, 418, -1, 419, -1, 425, -1, 434, -1, 435, + -1, 443, -1, 451, -1, 459, -1, 460, -1, 462, + -1, 463, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 470, 470, 486, 498, 507, 508, 509, 510, 511, - 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, - 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, - 532, 533, 534, 535, 536, 537, 538, 539, 540, 542, - 9, 18, 27, 36, 45, 54, 63, 72, 85, 87, - 93, 94, 99, 103, 107, 118, 126, 130, 139, 148, - 157, 166, 175, 184, 192, 200, 209, 218, 227, 236, - 253, 262, 271, 280, 290, 303, 318, 327, 335, 350, - 358, 368, 378, 385, 392, 400, 407, 418, 419, 424, - 428, 433, 438, 446, 447, 452, 456, 457, 458, 7, - 13, 19, 25, 6, 15, 25, 35, 45, 55, 65, - 75, 85, 95, 106, 117, 127, 140, 141, 8, 21, - 27, 34, 40, 47, 57, 61, 70, 79, 88, 95, - 96, 101, 113, 118, 143, 153, 163, 169, 180, 191, - 206, 207, 213, 214, 219, 220, 226, 227, 231, 232, - 237, 239, 245, 246, 250, 251, 254, 255, 260, 7, - 16, 25, 46, 47, 50, 54, 7, 14, 22, 9, - 19, 32, 33, 7, 14, 31, 51, 52, 9, 17, - 29, 30, 34, 35, 36, 41, 42, 43, 48, 52, - 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, - 97, 101, 105, 112, 113, 117, 118, 119, 2, 9, - 15, 21, 28, 35, 45, 46, 47, 7, 21, 36, - 56, 57, 84, 85, 86, 87, 88, 89, 93, 94, - 99, 104, 105, 106, 107, 108, 113, 120, 121, 122, - 139, 146, 153, 163, 173, 185, 193, 202, 220, 221, - 225, 226, 230, 239, 262, 276, 283, 288, 290, 292, - 294, 297, 300, 301, 302, 303, 308, 312, 313, 318, - 325, 330, 331, 332, 333, 334, 335, 336, 337, 343, - 344, 348, 353, 360, 367, 374, 386, 387, 388, 389, - 393, 398, 399, 400, 405, 410, 411, 412, 413, 414, - 415, 420, 440, 469, 470, 474, 478, 479, 480, 484, - 488, 496, 497, 502, 503, 504, 508, 516, 517, 522, - 523, 527, 532, 536, 540, 545, 553, 554, 558, 559, - 563, 564, 570, 581, 594, 608, 622, 636, 650, 673, - 677, 684, 688, 696, 701, 708, 718, 719, 720, 721, - 722, 729, 736, 737, 742, 743, 9, 19, 29, 39, - 49, 59, 69, 79, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 113, 114, 115, 116, 117, 118, 119, 124, 125, 130, - 131, 132, 137, 138, 139, 142, 143, 8, 20, 33, - 46, 58, 70, 86, 87, 91, 95, 7, 1, 30, - 53, 54, 59, 63, 68, 72, 80, 81, 85, 86, - 91, 92, 96, 97, 102, 103, 104, 105, 106, 111, - 119, 123, 128, 129, 134, 138, 143, 147, 151, 155, - 159, 163, 167, 171, 175, 179, 183, 187, 191, 195, - 203, 209, 210, 211, 216, 220, 47, 48, 52, 53, - 68, 69, 76, 84, 92, 100, 108, 116, 127, 128, - 155, 160, 168, 184, 201, 218, 235, 236, 255, 259, - 263, 267, 284, 291, 298, 308, 309, 312, 324, 335, - 343, 348, 353, 358, 363, 371, 379, 384, 389, 396, - 397, 401, 402, 403, 407, 414, 415, 419, 420, 424, - 425, 426, 430, 431, 435, 436, 446, 459, 460, 463, - 472, 483, 484, 485, 488, 489, 490, 494, 495, 496, - 497, 501, 502, 506, 508, 524, 526, 531, 534, 542, - 546, 550, 554, 558, 562, 569, 574, 581, 582, 586, - 591, 595, 599, 607, 614, 615, 620, 621, 625, 626, - 631, 633, 635, 640, 660, 661, 663, 668, 669, 673, - 674, 677, 678, 703, 704, 709, 714, 718, 719, 723, - 724, 728, 729, 730, 731, 732, 736, 749, 756, 763, - 770, 771, 775, 776, 780, 781, 785, 786, 790, 791, - 795, 796, 800, 811, 812, 813, 814, 818, 819, 824, - 825, 826, 835, 841, 850, 851, 864, 865, 869, 870, - 874, 875, 881, 887, 895, 904, 912, 921, 930, 934, - 960, 964, 977, 991, 1006, 1018, 1034, 1040, 1045, 1051, - 1058, 1059, 1067, 1071, 1075, 1081, 1088, 1093, 1094, 1095, - 1096, 1100, 1101, 1113, 1114, 1119, 1126, 1133, 1140, 1172, - 1183, 1196, 1201, 1202, 1205, 1206, 1209, 1210, 1215, 1216, - 1221, 1225, 1231, 1252, 1260, 1273, 1276, 1280, 1280, 1283, - 1284, 1286, 1291, 1298, 1303, 1309, 1314, 1320, 1326, 1332, - 1341, 1343, 1346, 1350, 1351, 1352, 1353, 1354, 1355, 1360, - 1380, 1381, 1382, 1383, 1394, 1408, 1409, 1415, 1420, 1425, - 1430, 1435, 1440, 1445, 1450, 1456, 1462, 1468, 1475, 1497, - 1506, 1510, 1518, 1522, 1530, 1542, 1563, 1567, 1573, 1577, - 1590, 1598, 1608, 1610, 1612, 1614, 1616, 1618, 1623, 1624, - 1631, 1640, 1648, 1657, 1668, 1676, 1677, 1678, 1682, 1682, - 1685, 1685, 1688, 1688, 1691, 1691, 1694, 1694, 1697, 1697, - 1700, 1700, 1703, 1703, 1706, 1708, 1710, 1712, 1714, 1716, - 1718, 1720, 1722, 1727, 1732, 1738, 1745, 1750, 1756, 1762, - 1793, 1795, 1797, 1805, 1820, 1822, 1824, 1826, 1828, 1830, - 1832, 1834, 1836, 1838, 1840, 1842, 1844, 1846, 1848, 1851, - 1853, 1855, 1858, 1860, 1862, 1864, 1866, 1871, 1876, 1883, - 1888, 1895, 1900, 1907, 1912, 1920, 1928, 1936, 1944, 1962, - 1970, 1978, 1986, 1994, 2002, 2010, 2014, 2030, 2038, 2046, - 2054, 2062, 2070, 2078, 2082, 2086, 2090, 2094, 2102, 2110, - 2118, 2126, 2146, 2168, 2179, 2186, 2200, 2209, 2228, 2230, - 2232, 2234, 2236, 2238, 2240, 2242, 2244, 2246, 2248, 2250, - 2252, 2254, 2256, 2258, 2260, 2262, 2264, 2266, 2268, 2272, - 2276, 2280, 2294, 2295, 2296, 2303, 2315, 2330, 2342, 2346, - 2350, 2354, 2357, 2368, 2373, 2375, 2387, 2398, 2422, 2433, - 2442, 2446, 2453, 2461, 2469, 2480, 2488, 2516, 2552, 2563, - 2564, 2571, 2577, 2581, 2585, 2589, 2593, 2597, 2601, 2605, - 2609, 2613, 2617, 2621, 2625, 2629, 2633, 2637, 2639, 2641, - 2645, 2654, 2659, 2666, 2681, 2688, 2692, 2696, 2700, 2704, - 2714, 2723, 2745, 2746, 2750, 2751, 2752, 2756, 2757, 2764, - 2765, 2769, 2770, 2775, 2783, 2785, 2799, 2802, 2829, 2830, - 2833, 2834, 2845, 2851, 2858, 2867, 2884, 2929, 2937, 2945, - 2953, 2961, 2982, 2983, 2986, 2987, 2991, 3001, 3002, 3006, - 3007, 3011, 3012, 3013, 3016, 3017, 3020, 3021, 3022, 3023, - 3024, 3025, 3026, 3027, 3028, 3029, 3030, 3031, 3032, 3035, - 3037, 3042, 3044, 3049, 3051, 3053, 3055, 3057, 3059, 3061, - 3063, 3077, 3079, 3083, 3087, 3094, 3099, 3106, 3111, 3119, - 3123, 3129, 3133, 3142, 3153, 3154, 3158, 3162, 3169, 3170, - 3171, 3172, 3173, 3174, 3175, 3176, 3177, 3178, 3188, 3192, - 3199, 3206, 3207, 3223, 3227, 3232, 3236, 3251, 3256, 3260, - 3263, 3266, 3267, 3268, 3271, 3278, 3288, 3302, 3303, 3307, - 3318, 3319, 3322, 3323, 3326, 3330, 3337, 3341, 3349, 3360, - 3361, 3365, 3366, 3370, 3371, 3374, 3375, 3385, 3386, 3390, - 3391, 3395, 3396, 3399, 3415, 3423, 3431, 3446, 3464, 3465, - 3468, 3469, 3472, 3476, 3477, 3481, 3482, 3485, 3486, 3487, - 3497, 3498, 3509, 3513, 3540, 3542, 3548, 3549, 3552, 3554, - 3564, 3567, 3578, 3582, 3586, 3598, 3602, 3611, 3618, 3656, - 3660, 3664, 3668, 3672, 3676, 3680, 3686, 3687, 3703, 3704, - 3705, 3708, 3709, 3715, 3716, 3717, 3720, 3721, 3722, 3725, - 3726, 3727, 3730, 3731, 3734, 3736, 3741, 3742, 3745, 3753, - 3754, 3755, 3756, 3759, 3760, 7, 18, 19, 23, 24, - 25, 26, 7, 16, 34, 41, 46, 47, 48, 49, - 8, 33, 62, 66, 67, 72, 73, 78, 79, 83, - 84, 89, 90, 7, 16, 25, 34, 43, 52, 5, - 11, 7, 20, 9, 16, 26, 33, 44, 45, 50, - 51, 52, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 90, 91, 92, 97, 98, 103, 107, 115, - 116, 121, 122, 123, 129, 134, 142, 143, 10, 16, - 22, 28, 38, 39, 47, 58, 70, 78, 86, 93, - 103, 105, 111, 115, 119, 134, 141, 142, 143, 147, - 148, 7, 14, 20, 28, 29, 8, 22, 36, 48, - 56, 70, 71, 72, 73, 74, 87, 88, 93, 94, - 98, 99, 7, 18, 31, 35, 42, 53, 54, 60, - 61, 9, 19, 2, 7, 14, 24, 25, 32, 3, - 10, 17, 24, 31, 38, 45, 52, 61, 61, 63, - 64, 68, 69, 6, 8, 21, 34, 52, 74, 75, - 76, 77, 11, 24, 37, 54, 55, 56, 61, 74, + 0, 483, 483, 499, 511, 520, 521, 522, 523, 524, + 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, + 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, + 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, + 555, 556, 557, 559, 9, 18, 27, 36, 45, 54, + 63, 72, 85, 87, 93, 94, 99, 103, 107, 118, + 126, 130, 139, 148, 157, 166, 175, 184, 192, 200, + 209, 218, 227, 236, 253, 262, 271, 280, 290, 303, + 318, 327, 335, 350, 358, 368, 378, 385, 392, 400, + 407, 418, 419, 424, 428, 433, 438, 446, 447, 452, + 456, 457, 458, 7, 13, 19, 25, 6, 15, 25, + 35, 45, 55, 65, 75, 85, 95, 106, 117, 127, + 140, 141, 9, 23, 29, 36, 42, 49, 59, 63, + 72, 81, 90, 97, 98, 103, 115, 120, 145, 150, + 155, 161, 171, 181, 187, 198, 209, 224, 225, 231, + 232, 237, 238, 244, 245, 249, 250, 255, 257, 263, + 264, 268, 269, 272, 273, 278, 7, 16, 25, 46, + 47, 50, 54, 7, 14, 22, 9, 15, 22, 28, + 34, 41, 48, 59, 9, 19, 32, 33, 7, 14, + 31, 51, 52, 9, 17, 29, 30, 34, 35, 36, + 41, 42, 43, 48, 52, 56, 60, 64, 68, 72, + 76, 80, 84, 88, 92, 97, 101, 105, 112, 113, + 117, 118, 119, 2, 9, 15, 21, 28, 35, 45, + 46, 47, 2, 7, 21, 36, 56, 57, 84, 85, + 86, 87, 88, 89, 93, 94, 99, 104, 105, 106, + 107, 108, 113, 120, 121, 122, 139, 146, 153, 163, + 173, 185, 193, 202, 220, 221, 225, 226, 230, 239, + 262, 276, 283, 288, 290, 292, 294, 297, 300, 301, + 302, 303, 308, 312, 313, 318, 325, 330, 331, 332, + 333, 334, 335, 336, 337, 343, 344, 348, 353, 360, + 367, 374, 386, 387, 388, 389, 393, 398, 399, 400, + 405, 410, 411, 412, 413, 414, 415, 420, 440, 469, + 470, 474, 478, 479, 480, 484, 488, 496, 497, 502, + 503, 504, 508, 516, 517, 522, 523, 527, 532, 536, + 540, 545, 553, 554, 558, 559, 563, 564, 570, 581, + 594, 608, 622, 636, 650, 673, 677, 684, 688, 696, + 701, 708, 718, 719, 720, 721, 722, 729, 736, 737, + 742, 743, 9, 19, 29, 39, 49, 59, 69, 79, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 115, 116, + 117, 118, 119, 120, 125, 126, 131, 132, 133, 138, + 139, 140, 143, 144, 8, 20, 33, 46, 58, 70, + 86, 87, 91, 95, 7, 1, 30, 53, 54, 59, + 63, 68, 72, 80, 81, 85, 86, 91, 92, 96, + 97, 102, 103, 104, 105, 106, 111, 119, 123, 128, + 129, 134, 138, 143, 147, 151, 155, 159, 163, 167, + 171, 175, 179, 183, 187, 191, 195, 199, 203, 211, + 217, 218, 219, 224, 228, 47, 48, 52, 53, 68, + 69, 76, 84, 92, 100, 108, 116, 127, 128, 155, + 160, 168, 184, 201, 218, 235, 236, 255, 259, 263, + 267, 284, 291, 298, 308, 309, 312, 324, 335, 343, + 348, 353, 358, 363, 371, 379, 384, 389, 396, 397, + 401, 402, 403, 407, 414, 415, 419, 420, 424, 425, + 426, 430, 431, 435, 436, 446, 459, 460, 463, 472, + 483, 484, 485, 488, 489, 490, 494, 495, 496, 497, + 501, 502, 506, 508, 524, 526, 531, 534, 542, 546, + 550, 554, 558, 562, 569, 574, 581, 582, 586, 591, + 595, 599, 607, 614, 615, 620, 621, 625, 626, 631, + 633, 635, 640, 660, 661, 663, 668, 669, 673, 674, + 677, 678, 703, 704, 709, 714, 718, 719, 723, 724, + 728, 729, 730, 731, 732, 736, 749, 756, 763, 770, + 771, 775, 776, 780, 781, 785, 786, 790, 791, 795, + 796, 800, 811, 812, 813, 814, 818, 819, 824, 825, + 826, 835, 841, 850, 851, 864, 865, 869, 870, 874, + 875, 881, 887, 895, 904, 912, 921, 930, 934, 961, + 965, 978, 992, 1007, 1019, 1032, 1048, 1054, 1059, 1065, + 1072, 1073, 1081, 1085, 1089, 1095, 1102, 1107, 1108, 1109, + 1110, 1114, 1115, 1127, 1128, 1133, 1140, 1147, 1154, 1186, + 1197, 1210, 1215, 1216, 1219, 1220, 1223, 1224, 1229, 1230, + 1235, 1239, 1245, 1266, 1274, 1287, 1290, 1294, 1294, 1297, + 1298, 1300, 1305, 1312, 1317, 1323, 1328, 1334, 1340, 1346, + 1355, 1357, 1360, 1364, 1365, 1366, 1367, 1368, 1369, 1374, + 1394, 1395, 1396, 1397, 1408, 1422, 1423, 1429, 1434, 1439, + 1444, 1449, 1454, 1459, 1464, 1470, 1476, 1482, 1489, 1511, + 1520, 1524, 1532, 1536, 1544, 1556, 1577, 1581, 1587, 1591, + 1604, 1612, 1622, 1624, 1626, 1628, 1630, 1632, 1637, 1638, + 1645, 1654, 1662, 1671, 1682, 1690, 1691, 1692, 1696, 1696, + 1699, 1699, 1702, 1702, 1705, 1705, 1708, 1708, 1711, 1711, + 1714, 1714, 1717, 1717, 1720, 1722, 1724, 1726, 1728, 1730, + 1732, 1734, 1736, 1741, 1746, 1752, 1759, 1764, 1770, 1776, + 1807, 1809, 1811, 1819, 1834, 1836, 1838, 1840, 1842, 1844, + 1846, 1848, 1850, 1852, 1854, 1856, 1858, 1860, 1862, 1865, + 1867, 1869, 1872, 1874, 1876, 1878, 1880, 1885, 1890, 1897, + 1902, 1909, 1914, 1921, 1926, 1934, 1942, 1950, 1958, 1976, + 1984, 1992, 2000, 2008, 2016, 2024, 2028, 2044, 2052, 2060, + 2068, 2076, 2084, 2092, 2096, 2100, 2104, 2108, 2116, 2124, + 2132, 2140, 2160, 2182, 2193, 2200, 2214, 2223, 2242, 2244, + 2246, 2248, 2250, 2252, 2254, 2256, 2258, 2260, 2262, 2264, + 2266, 2268, 2270, 2272, 2274, 2276, 2278, 2280, 2282, 2286, + 2290, 2294, 2308, 2309, 2310, 2317, 2329, 2333, 2337, 2341, + 2344, 2355, 2360, 2362, 2373, 2397, 2408, 2419, 2423, 2430, + 2434, 2439, 2444, 2448, 2455, 2463, 2471, 2482, 2490, 2518, + 2554, 2565, 2566, 2573, 2579, 2583, 2587, 2591, 2595, 2599, + 2603, 2607, 2611, 2615, 2619, 2623, 2627, 2631, 2635, 2639, + 2641, 2643, 2647, 2656, 2661, 2668, 2683, 2690, 2694, 2698, + 2702, 2706, 2716, 2725, 2747, 2748, 2752, 2753, 2754, 2758, + 2759, 2766, 2767, 2771, 2772, 2777, 2785, 2787, 2801, 2804, + 2831, 2832, 2835, 2836, 2847, 2853, 2860, 2869, 2886, 2931, + 2939, 2947, 2955, 2963, 2984, 2985, 2988, 2989, 2993, 3003, + 3004, 3008, 3009, 3013, 3014, 3015, 3018, 3019, 3022, 3023, + 3024, 3025, 3026, 3027, 3028, 3029, 3030, 3031, 3032, 3033, + 3034, 3037, 3039, 3044, 3046, 3051, 3053, 3055, 3057, 3059, + 3061, 3063, 3065, 3079, 3081, 3085, 3089, 3096, 3101, 3108, + 3113, 3121, 3125, 3131, 3135, 3144, 3155, 3156, 3160, 3164, + 3171, 3172, 3173, 3174, 3175, 3176, 3177, 3178, 3179, 3180, + 3190, 3194, 3201, 3208, 3209, 3225, 3229, 3234, 3238, 3253, + 3258, 3262, 3265, 3268, 3269, 3270, 3273, 3280, 3290, 3304, + 3305, 3309, 3320, 3321, 3324, 3325, 3328, 3332, 3339, 3343, + 3351, 3362, 3363, 3367, 3368, 3372, 3373, 3376, 3377, 3387, + 3388, 3392, 3393, 3397, 3398, 3401, 3417, 3425, 3433, 3448, + 3466, 3467, 3470, 3471, 3474, 3478, 3479, 3483, 3484, 3487, + 3488, 3489, 3499, 3500, 3511, 3515, 3543, 3545, 3551, 3552, + 3555, 3557, 3567, 3570, 3581, 3585, 3589, 3601, 3605, 3614, + 3621, 3659, 3663, 3667, 3671, 3675, 3679, 3683, 3689, 3690, + 3706, 3707, 3708, 3711, 3712, 3718, 3719, 3720, 3723, 3724, + 3725, 3728, 3729, 3730, 3733, 3734, 3737, 3739, 3744, 3745, + 3748, 3756, 3757, 3758, 3759, 3762, 3763, 3766, 7, 18, + 19, 23, 24, 25, 26, 7, 26, 54, 61, 66, + 67, 68, 69, 8, 33, 62, 66, 67, 72, 73, + 78, 79, 83, 84, 89, 90, 7, 16, 25, 34, + 43, 52, 5, 12, 22, 23, 7, 19, 33, 9, + 16, 26, 33, 44, 45, 50, 51, 52, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 90, 91, + 92, 97, 98, 103, 107, 115, 116, 121, 122, 123, + 129, 134, 142, 143, 10, 16, 22, 28, 38, 39, + 47, 58, 70, 78, 86, 93, 103, 105, 111, 115, + 119, 134, 141, 142, 143, 147, 148, 7, 14, 20, + 28, 29, 8, 22, 36, 48, 56, 70, 71, 72, + 73, 74, 87, 88, 93, 94, 98, 99, 7, 18, + 31, 35, 42, 53, 54, 60, 61, 9, 19, 7, + 18, 28, 38, 50, 51, 55, 56, 59, 62, 63, + 2, 7, 15, 26, 27, 34, 3, 10, 17, 24, + 31, 38, 45, 52, 61, 61, 63, 64, 68, 69, + 6, 8, 21, 34, 47, 65, 87, 88, 89, 90, + 11, 24, 37, 54, 55, 56, 61, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, @@ -296259,19 +310053,20 @@ static const yytype_uint16 yyrline[] = 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 75, 75, 75, 75, 75, + 74, 74, 74, 74, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 75, 75, 75, 75, 75, 76, + 75, 75, 75, 75, 75, 75, 75, 75, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 76, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, - 77, 77, 77, 77, 78, 78, 78, 78, 78, 78, + 77, 77, 77, 77, 77, 78, 78, 78, 78, 78, + 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, @@ -296279,18 +310074,17 @@ static const yytype_uint16 yyrline[] = 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, - 78, 78, 78, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, - 79, 79, 79, 80, 80, 80, 80, 80, 80, 80, + 79, 79, 79, 79, 79, 79, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, - 80, 80, 80, 80, 80 + 80, 80, 80, 80, 80, 80, 80, 80 }; #endif @@ -296348,9 +310142,9 @@ static const char *const yytname[] = "OPERATOR", "OPTION", "OPTIONS", "OR", "ORDER", "ORDINALITY", "OUT_P", "OUTER_P", "OVER", "OVERLAPS", "OVERLAY", "OVERRIDING", "OWNED", "OWNER", "PARALLEL", "PARSER", "PARTIAL", "PARTITION", "PASSING", "PASSWORD", - "PERCENT", "PLACING", "PLANS", "POLICY", "POSITION", "PRAGMA_P", - "PRECEDING", "PRECISION", "PREPARE", "PREPARED", "PRESERVE", "PRIMARY", - "PRIOR", "PRIVILEGES", "PROCEDURAL", "PROCEDURE", "PROGRAM", + "PERCENT", "PLACING", "PLANS", "POLICY", "POSITION", "POSITIONAL", + "PRAGMA_P", "PRECEDING", "PRECISION", "PREPARE", "PREPARED", "PRESERVE", + "PRIMARY", "PRIOR", "PRIVILEGES", "PROCEDURAL", "PROCEDURE", "PROGRAM", "PUBLICATION", "QUALIFY", "QUOTE", "RANGE", "READ_P", "REAL", "REASSIGN", "RECHECK", "RECURSIVE", "REF", "REFERENCES", "REFERENCING", "REFRESH", "REINDEX", "RELATIVE_P", "RELEASE", "RENAME", "REPEATABLE", "REPLACE", @@ -296369,32 +310163,33 @@ static const char *const yytname[] = "TRANSFORM", "TREAT", "TRIGGER", "TRIM", "TRUE_P", "TRUNCATE", "TRUSTED", "TRY_CAST", "TYPE_P", "TYPES_P", "UNBOUNDED", "UNCOMMITTED", "UNENCRYPTED", "UNION", "UNIQUE", "UNKNOWN", "UNLISTEN", "UNLOGGED", - "UNTIL", "UPDATE", "USER", "USING", "VACUUM", "VALID", "VALIDATE", - "VALIDATOR", "VALUE_P", "VALUES", "VARCHAR", "VARIADIC", "VARYING", - "VERBOSE", "VERSION_P", "VIEW", "VIEWS", "VIRTUAL", "VOLATILE", "WHEN", - "WHERE", "WHITESPACE_P", "WINDOW", "WITH", "WITHIN", "WITHOUT", "WORK", - "WRAPPER", "WRITE_P", "XML_P", "XMLATTRIBUTES", "XMLCONCAT", - "XMLELEMENT", "XMLEXISTS", "XMLFOREST", "XMLNAMESPACES", "XMLPARSE", - "XMLPI", "XMLROOT", "XMLSERIALIZE", "XMLTABLE", "YEAR_P", "YEARS_P", - "YES_P", "ZONE", "NOT_LA", "NULLS_LA", "WITH_LA", "'<'", "'>'", "'='", - "POSTFIXOP", "'+'", "'-'", "'*'", "'/'", "'%'", "'^'", "UMINUS", "'['", - "']'", "'('", "')'", "'.'", "';'", "','", "'#'", "'?'", "'{'", "'}'", - "':'", "$accept", "stmtblock", "stmtmulti", "stmt", "AlterTableStmt", - "alter_identity_column_option_list", "alter_column_default", - "alter_identity_column_option", "alter_generic_option_list", - "alter_table_cmd", "alter_using", "alter_generic_option_elem", - "alter_table_cmds", "alter_generic_options", "opt_set_data", - "DeallocateStmt", "RenameStmt", "opt_column", "InsertStmt", - "insert_rest", "insert_target", "opt_conf_expr", "opt_with_clause", - "insert_column_item", "set_clause", "opt_on_conflict", "index_elem", - "returning_clause", "override_kind", "set_target_list", "opt_collate", - "opt_class", "insert_column_list", "set_clause_list", - "set_clause_list_opt_comma", "index_params", "set_target", - "CreateTypeStmt", "opt_enum_val_list", "enum_val_list", "PragmaStmt", + "UNTIL", "UPDATE", "USE_P", "USER", "USING", "VACUUM", "VALID", + "VALIDATE", "VALIDATOR", "VALUE_P", "VALUES", "VARCHAR", "VARIADIC", + "VARYING", "VERBOSE", "VERSION_P", "VIEW", "VIEWS", "VIRTUAL", + "VOLATILE", "WHEN", "WHERE", "WHITESPACE_P", "WINDOW", "WITH", "WITHIN", + "WITHOUT", "WORK", "WRAPPER", "WRITE_P", "XML_P", "XMLATTRIBUTES", + "XMLCONCAT", "XMLELEMENT", "XMLEXISTS", "XMLFOREST", "XMLNAMESPACES", + "XMLPARSE", "XMLPI", "XMLROOT", "XMLSERIALIZE", "XMLTABLE", "YEAR_P", + "YEARS_P", "YES_P", "ZONE", "NOT_LA", "NULLS_LA", "WITH_LA", "'<'", + "'>'", "'='", "POSTFIXOP", "'+'", "'-'", "'*'", "'/'", "'%'", "'^'", + "UMINUS", "'['", "']'", "'('", "')'", "'.'", "';'", "','", "'#'", "'$'", + "'?'", "'{'", "'}'", "':'", "$accept", "stmtblock", "stmtmulti", "stmt", + "AlterTableStmt", "alter_identity_column_option_list", + "alter_column_default", "alter_identity_column_option", + "alter_generic_option_list", "alter_table_cmd", "alter_using", + "alter_generic_option_elem", "alter_table_cmds", "alter_generic_options", + "opt_set_data", "DeallocateStmt", "RenameStmt", "opt_column", + "InsertStmt", "insert_rest", "insert_target", "opt_conf_expr", + "opt_with_clause", "insert_column_item", "set_clause", "opt_or_action", + "opt_on_conflict", "index_elem", "returning_clause", "override_kind", + "set_target_list", "opt_collate", "opt_class", "insert_column_list", + "set_clause_list", "set_clause_list_opt_comma", "index_params", + "set_target", "CreateTypeStmt", "opt_enum_val_list", "enum_val_list", + "PragmaStmt", "CreateDatabaseStmt", "opt_extension_name", "CreateSeqStmt", "OptSeqOptList", "ExecuteStmt", "execute_param_clause", "AlterSeqStmt", "SeqOptList", "opt_with", "NumericOnly", "SeqOptElem", "opt_by", "SignedIconst", "TransactionStmt", "opt_transaction", - "CreateStmt", "ConstraintAttributeSpec", "def_arg", + "UseStmt", "CreateStmt", "ConstraintAttributeSpec", "def_arg", "OptParenthesizedSeqOptList", "generic_option_arg", "key_action", "ColConstraint", "ColConstraintElem", "GeneratedColumnType", "opt_GeneratedColumnType", "GeneratedConstraintElem", @@ -296447,7 +310242,7 @@ static const char *const yytname[] = "opt_timezone", "year_keyword", "month_keyword", "day_keyword", "hour_keyword", "minute_keyword", "second_keyword", "millisecond_keyword", "microsecond_keyword", "opt_interval", "a_expr", - "b_expr", "c_expr", "func_application", "func_expr", + "b_expr", "c_expr", "indirection_expr", "func_application", "func_expr", "func_expr_windowless", "func_expr_common_subexpr", "list_comprehension", "within_group_clause", "filter_clause", "export_clause", "window_clause", "window_definition_list", "window_definition", "over_clause", @@ -296470,11 +310265,12 @@ static const char *const yytname[] = "attr_name", "func_name", "AexprConst", "Iconst", "Sconst", "ColId", "ColIdOrString", "type_function_name", "function_name_token", "type_name_token", "any_name", "attrs", "opt_name_list", "param_name", - "ColLabel", "ColLabelOrString", "PrepareStmt", "prep_type_clause", - "PreparableStmt", "CreateSchemaStmt", "OptSchemaEltList", "schema_stmt", - "IndexStmt", "access_method", "access_method_clause", "opt_concurrently", - "opt_index_name", "opt_reloptions", "opt_unique", - "AlterObjectSchemaStmt", "CheckPointStmt", "ExportStmt", "ImportStmt", + "ColLabel", "ColLabelOrString", "named_param", "PrepareStmt", + "prep_type_clause", "PreparableStmt", "CreateSchemaStmt", + "OptSchemaEltList", "schema_stmt", "IndexStmt", "access_method", + "access_method_clause", "opt_concurrently", "opt_index_name", + "opt_reloptions", "opt_unique", "AlterObjectSchemaStmt", + "CheckPointStmt", "opt_col_id", "ExportStmt", "ImportStmt", "ExplainStmt", "opt_verbose", "explain_option_arg", "ExplainableStmt", "NonReservedWord", "NonReservedWord_or_Sconst", "explain_option_list", "analyze_keyword", "opt_boolean_or_string", "explain_option_elem", @@ -296482,13 +310278,14 @@ static const char *const yytname[] = "var_value", "zone_value", "var_list", "LoadStmt", "file_name", "VacuumStmt", "vacuum_option_elem", "opt_full", "vacuum_option_list", "opt_freeze", "DeleteStmt", "relation_expr_opt_alias", - "where_or_current_clause", "using_clause", "AnalyzeStmt", - "VariableResetStmt", "generic_reset", "reset_rest", "VariableShowStmt", - "show_or_describe", "var_name", "table_id", "CallStmt", "ViewStmt", - "opt_check_option", "CreateAsStmt", "opt_with_data", "create_as_target", - "unreserved_keyword", "col_name_keyword", "func_name_keyword", - "type_name_keyword", "other_keyword", "type_func_name_keyword", - "reserved_keyword", 0 + "where_or_current_clause", "using_clause", "AnalyzeStmt", "AttachStmt", + "DetachStmt", "opt_database", "opt_database_alias", "ident_name", + "ident_list", "VariableResetStmt", "generic_reset", "reset_rest", + "VariableShowStmt", "show_or_describe", "var_name", "table_id", + "CallStmt", "ViewStmt", "opt_check_option", "CreateAsStmt", + "opt_with_data", "create_as_target", "unreserved_keyword", + "col_name_keyword", "func_name_keyword", "type_name_keyword", + "other_keyword", "type_func_name_keyword", "reserved_keyword", 0 }; #endif @@ -296545,210 +310342,215 @@ static const yytype_uint16 yytoknum[] = 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, - 735, 736, 737, 738, 739, 740, 60, 62, 61, 741, - 43, 45, 42, 47, 37, 94, 742, 91, 93, 40, - 41, 46, 59, 44, 35, 63, 123, 125, 58 + 735, 736, 737, 738, 739, 740, 741, 742, 60, 62, + 61, 743, 43, 45, 42, 47, 37, 94, 744, 91, + 93, 40, 41, 46, 59, 44, 35, 36, 63, 123, + 125, 58 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint16 yyr1[] = { - 0, 509, 510, 511, 511, 512, 512, 512, 512, 512, - 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, - 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, - 512, 512, 512, 512, 512, 512, 512, 512, 512, 512, - 513, 513, 513, 513, 513, 513, 513, 513, 514, 514, - 515, 515, 516, 516, 516, 516, 517, 517, 518, 518, - 518, 518, 518, 518, 518, 518, 518, 518, 518, 518, - 518, 518, 518, 518, 518, 518, 518, 518, 518, 518, - 518, 518, 518, 518, 518, 518, 518, 519, 519, 520, - 520, 520, 520, 521, 521, 522, 523, 523, 523, 524, - 524, 524, 524, 525, 525, 525, 525, 525, 525, 525, - 525, 525, 525, 525, 525, 525, 526, 526, 527, 528, - 528, 528, 528, 528, 529, 529, 530, 530, 530, 531, - 531, 532, 533, 533, 534, 534, 534, 535, 535, 535, - 536, 536, 537, 537, 538, 538, 539, 539, 540, 540, - 541, 541, 542, 542, 543, 543, 544, 544, 545, 546, - 546, 546, 547, 547, 548, 548, 549, 549, 549, 550, - 550, 551, 551, 552, 552, 552, 553, 553, 554, 554, - 555, 555, 556, 556, 556, 557, 557, 557, 557, 558, - 558, 558, 558, 558, 558, 558, 558, 558, 558, 558, - 558, 558, 558, 559, 559, 560, 560, 560, 561, 561, - 561, 561, 561, 561, 562, 562, 562, 563, 563, 563, - 564, 564, 565, 565, 565, 565, 565, 565, 566, 566, - 567, 568, 568, 568, 568, 568, 569, 569, 569, 569, - 570, 570, 570, 570, 570, 570, 570, 570, 571, 571, - 572, 572, 573, 573, 573, 574, 575, 576, 576, 576, - 576, 576, 577, 577, 577, 577, 578, 579, 579, 580, - 580, 581, 581, 581, 581, 581, 581, 581, 581, 582, - 582, 583, 584, 584, 584, 584, 585, 585, 585, 585, - 586, 587, 587, 587, 588, 589, 589, 589, 589, 589, - 589, 590, 590, 591, 591, 592, 593, 593, 593, 594, - 594, 595, 595, 596, 596, 596, 597, 598, 598, 599, - 599, 600, 601, 601, 601, 601, 602, 602, 603, 603, - 604, 604, 604, 605, 605, 605, 605, 605, 605, 606, - 606, 607, 607, 607, 607, 608, 609, 609, 609, 609, - 609, 609, 609, 609, 610, 610, 611, 611, 611, 611, - 611, 611, 611, 611, 612, 612, 612, 612, 612, 612, - 612, 612, 612, 612, 612, 612, 612, 612, 612, 612, - 613, 613, 613, 613, 613, 613, 613, 614, 614, 615, - 615, 615, 616, 616, 616, 617, 617, 618, 618, 618, - 618, 618, 618, 619, 619, 620, 620, 621, 622, 622, - 623, 623, 624, 624, 625, 625, 626, 626, 627, 627, - 628, 628, 629, 629, 630, 630, 630, 630, 630, 631, - 632, 632, 633, 633, 634, 634, 635, 635, 635, 635, - 635, 635, 635, 635, 635, 635, 635, 635, 635, 635, - 636, 637, 637, 637, 638, 638, 639, 639, 640, 640, - 641, 641, 641, 641, 641, 641, 641, 641, 642, 642, - 643, 643, 644, 644, 644, 644, 644, 644, 644, 644, - 644, 644, 645, 645, 645, 646, 646, 647, 648, 648, - 649, 649, 649, 649, 649, 649, 649, 649, 649, 650, - 650, 651, 651, 651, 652, 653, 653, 654, 654, 655, - 655, 655, 656, 656, 657, 657, 657, 658, 658, 659, - 659, 660, 660, 660, 661, 661, 661, 662, 662, 662, - 662, 663, 663, 664, 664, 664, 664, 665, 665, 666, - 666, 666, 666, 666, 666, 667, 667, 668, 668, 669, - 669, 669, 669, 670, 671, 671, 672, 672, 673, 673, - 673, 673, 673, 674, 675, 675, 675, 676, 676, 677, - 677, 678, 678, 679, 679, 679, 679, 680, 680, 681, - 681, 682, 682, 682, 682, 682, 683, 684, 685, 686, - 687, 687, 688, 688, 689, 689, 690, 690, 691, 691, - 692, 692, 693, 694, 694, 694, 694, 695, 695, 696, - 696, 696, 697, 697, 698, 698, 699, 699, 700, 700, - 701, 701, 702, 702, 702, 702, 702, 702, 702, 702, - 703, 703, 703, 703, 703, 703, 704, 704, 704, 704, - 705, 705, 706, 706, 706, 706, 706, 707, 707, 707, - 707, 708, 708, 709, 709, 710, 710, 710, 710, 711, - 711, 712, 713, 713, 714, 714, 715, 715, 716, 716, - 717, 717, 718, 719, 719, 720, 720, 721, 721, 722, - 722, 723, 723, 723, 723, 723, 723, 723, 723, 723, - 724, 724, 724, 725, 725, 725, 725, 725, 725, 725, - 726, 726, 726, 726, 727, 728, 728, 729, 729, 729, - 729, 729, 729, 729, 729, 729, 729, 729, 730, 730, - 731, 731, 732, 732, 733, 734, 735, 735, 736, 736, - 737, 738, 739, 739, 739, 739, 739, 739, 740, 740, - 741, 741, 741, 741, 742, 743, 743, 743, 744, 744, - 745, 745, 746, 746, 747, 747, 748, 748, 749, 749, - 750, 750, 751, 751, 752, 752, 752, 752, 752, 752, - 752, 752, 752, 752, 752, 752, 752, 752, 752, 752, - 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, - 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, - 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, - 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, - 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, - 753, 753, 753, 753, 753, 753, 753, 753, 753, 753, - 753, 753, 753, 753, 753, 753, 753, 753, 754, 754, - 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, - 754, 754, 754, 754, 754, 754, 754, 754, 754, 754, - 754, 754, 755, 755, 755, 755, 755, 755, 755, 755, - 755, 755, 755, 755, 755, 755, 755, 755, 755, 755, - 756, 756, 756, 756, 756, 756, 756, 757, 757, 758, - 758, 759, 759, 759, 759, 759, 759, 759, 759, 759, - 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, + 0, 512, 513, 514, 514, 515, 515, 515, 515, 515, + 515, 515, 515, 515, 515, 515, 515, 515, 515, 515, + 515, 515, 515, 515, 515, 515, 515, 515, 515, 515, + 515, 515, 515, 515, 515, 515, 515, 515, 515, 515, + 515, 515, 515, 515, 516, 516, 516, 516, 516, 516, + 516, 516, 517, 517, 518, 518, 519, 519, 519, 519, + 520, 520, 521, 521, 521, 521, 521, 521, 521, 521, + 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, + 521, 521, 521, 521, 521, 521, 521, 521, 521, 521, + 521, 522, 522, 523, 523, 523, 523, 524, 524, 525, + 526, 526, 526, 527, 527, 527, 527, 528, 528, 528, + 528, 528, 528, 528, 528, 528, 528, 528, 528, 528, + 529, 529, 530, 531, 531, 531, 531, 531, 532, 532, + 533, 533, 533, 534, 534, 535, 536, 536, 537, 537, + 537, 538, 538, 538, 539, 539, 539, 540, 540, 541, + 541, 542, 542, 543, 543, 544, 544, 545, 545, 546, + 546, 547, 547, 548, 548, 549, 550, 550, 550, 551, + 551, 552, 552, 553, 553, 553, 554, 554, 554, 554, + 554, 554, 554, 555, 556, 556, 557, 557, 558, 558, + 558, 559, 559, 560, 560, 561, 561, 562, 562, 562, + 563, 563, 563, 563, 564, 564, 564, 564, 564, 564, + 564, 564, 564, 564, 564, 564, 564, 564, 565, 565, + 566, 566, 566, 567, 567, 567, 567, 567, 567, 568, + 568, 568, 569, 570, 570, 570, 571, 571, 572, 572, + 572, 572, 572, 572, 573, 573, 574, 575, 575, 575, + 575, 575, 576, 576, 576, 576, 577, 577, 577, 577, + 577, 577, 577, 577, 578, 578, 579, 579, 580, 580, + 580, 581, 582, 583, 583, 583, 583, 583, 584, 584, + 584, 584, 585, 586, 586, 587, 587, 588, 588, 588, + 588, 588, 588, 588, 588, 589, 589, 590, 591, 591, + 591, 591, 592, 592, 592, 592, 593, 594, 594, 594, + 595, 596, 596, 596, 596, 596, 596, 597, 597, 598, + 598, 599, 600, 600, 600, 601, 601, 602, 602, 603, + 603, 603, 604, 605, 605, 606, 606, 607, 608, 608, + 608, 608, 609, 609, 610, 610, 611, 611, 611, 612, + 612, 612, 612, 612, 612, 613, 613, 614, 614, 614, + 614, 615, 616, 616, 616, 616, 616, 616, 616, 616, + 617, 617, 618, 618, 618, 618, 618, 618, 618, 618, + 619, 619, 619, 619, 619, 619, 619, 619, 619, 619, + 619, 619, 619, 619, 619, 619, 619, 619, 620, 620, + 620, 620, 620, 620, 621, 621, 622, 622, 622, 623, + 623, 623, 624, 624, 625, 625, 625, 625, 625, 625, + 626, 626, 627, 627, 628, 629, 629, 630, 630, 631, + 631, 632, 632, 633, 633, 634, 634, 635, 635, 636, + 636, 637, 637, 637, 637, 637, 638, 639, 639, 640, + 640, 641, 641, 642, 642, 642, 642, 642, 642, 642, + 642, 642, 642, 642, 642, 642, 642, 642, 642, 643, + 644, 644, 644, 645, 645, 646, 646, 647, 647, 648, + 648, 648, 648, 648, 648, 648, 648, 649, 649, 650, + 650, 651, 651, 651, 651, 651, 651, 651, 651, 651, + 651, 652, 652, 652, 653, 653, 654, 655, 655, 656, + 656, 656, 656, 656, 656, 656, 656, 656, 657, 657, + 658, 658, 658, 659, 660, 660, 661, 661, 662, 662, + 662, 663, 663, 664, 664, 664, 665, 665, 666, 666, + 667, 667, 667, 668, 668, 668, 669, 669, 669, 669, + 670, 670, 671, 671, 671, 671, 672, 672, 673, 673, + 673, 673, 673, 673, 674, 674, 675, 675, 676, 676, + 676, 676, 677, 678, 678, 679, 679, 680, 680, 680, + 680, 680, 681, 682, 682, 682, 683, 683, 684, 684, + 685, 685, 686, 686, 686, 686, 687, 687, 688, 688, + 689, 689, 689, 689, 689, 690, 691, 692, 693, 694, + 694, 695, 695, 696, 696, 697, 697, 698, 698, 699, + 699, 700, 701, 701, 701, 701, 702, 702, 703, 703, + 703, 704, 704, 705, 705, 706, 706, 707, 707, 708, + 708, 709, 709, 709, 709, 709, 709, 709, 709, 710, + 710, 710, 710, 710, 710, 710, 711, 711, 711, 711, + 712, 712, 713, 713, 713, 713, 713, 714, 714, 714, + 714, 715, 715, 716, 716, 717, 717, 717, 717, 718, + 718, 719, 720, 720, 721, 721, 722, 722, 723, 723, + 724, 724, 725, 726, 726, 727, 727, 728, 728, 729, + 729, 730, 730, 730, 730, 730, 730, 730, 730, 730, + 731, 731, 731, 732, 732, 732, 732, 732, 732, 732, + 733, 733, 733, 733, 734, 735, 735, 736, 736, 736, + 736, 736, 736, 736, 736, 736, 736, 736, 737, 737, + 738, 738, 739, 739, 740, 741, 742, 742, 743, 743, + 744, 745, 746, 746, 746, 746, 746, 746, 747, 747, + 748, 748, 748, 748, 749, 750, 750, 750, 751, 751, + 752, 752, 753, 753, 754, 754, 755, 755, 756, 756, + 757, 757, 758, 758, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, 759, - 760, 760, 761, 761, 762, 762, 762, 763, 763, 764, - 764, 765, 765, 766, 767, 767, 767, 768, 769, 769, - 770, 770, 771, 771, 771, 772, 772, 773, 773, 773, - 773, 773, 774, 774, 775, 775, 776, 777, 777, 778, - 778, 779, 779, 779, 780, 780, 781, 781, 781, 781, - 781, 781, 781, 781, 781, 781, 781, 781, 781, 782, - 782, 783, 783, 784, 784, 784, 784, 784, 784, 784, - 784, 785, 785, 786, 786, 787, 787, 788, 788, 789, - 789, 790, 790, 790, 791, 791, 792, 792, 793, 793, - 793, 793, 793, 793, 793, 793, 793, 793, 794, 794, - 795, 796, 796, 797, 797, 797, 797, 797, 797, 798, - 799, 800, 800, 800, 801, 801, 802, 803, 803, 804, - 805, 805, 806, 806, 807, 807, 808, 808, 808, 809, - 809, 810, 810, 811, 811, 812, 812, 813, 813, 814, - 814, 815, 815, 816, 816, 816, 816, 816, 817, 817, - 818, 818, 819, 820, 820, 821, 821, 822, 822, 822, - 823, 823, 824, 824, 825, 825, 826, 826, 827, 828, - 829, 829, 830, 830, 830, 830, 830, 830, 830, 830, - 830, 830, 830, 830, 830, 830, 831, 832, 833, 833, - 833, 834, 834, 835, 835, 835, 836, 836, 836, 837, - 837, 837, 838, 838, 839, 839, 840, 840, 841, 842, - 842, 842, 842, 843, 843, 844, 845, 845, 846, 846, - 846, 846, 847, 847, 848, 848, 849, 849, 849, 849, - 850, 850, 851, 852, 852, 853, 853, 854, 854, 855, - 855, 856, 856, 857, 857, 857, 857, 857, 857, 858, - 858, 859, 860, 861, 861, 861, 861, 862, 862, 863, - 863, 863, 864, 864, 864, 864, 864, 864, 864, 864, - 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, - 864, 864, 864, 864, 864, 864, 864, 864, 864, 864, - 864, 864, 865, 865, 865, 866, 866, 867, 867, 868, - 868, 869, 869, 869, 869, 870, 871, 871, 872, 872, - 872, 872, 873, 873, 873, 873, 874, 874, 874, 874, - 875, 875, 876, 876, 876, 876, 876, 876, 876, 877, - 877, 878, 878, 878, 879, 879, 880, 880, 880, 880, - 880, 881, 881, 881, 881, 881, 882, 882, 883, 883, - 884, 884, 885, 885, 886, 886, 886, 887, 887, 888, - 888, 889, 889, 890, 891, 891, 892, 892, 892, 893, - 893, 893, 893, 893, 893, 893, 893, 894, 894, 895, - 895, 896, 896, 897, 898, 898, 898, 898, 899, 899, - 899, 899, 900, 900, 900, 901, 901, 901, 902, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 903, 903, 903, 903, 903, - 903, 903, 903, 903, 903, 904, 904, 904, 904, 904, - 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, - 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, - 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, - 904, 904, 904, 904, 904, 904, 904, 904, 904, 904, - 904, 904, 904, 904, 904, 904, 904, 904, 904, 905, - 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, - 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, - 905, 905, 905, 905, 905, 905, 905, 905, 905, 905, - 905, 905, 906, 906, 906, 906, 906, 906, 906, 906, - 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, - 906, 906, 906, 906, 906, 906, 906, 906, 906, 906, - 906, 906, 906, 906, 907, 907, 907, 907, 907, 907, - 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, - 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, - 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, - 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, - 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, - 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, - 907, 907, 907, 907, 907, 907, 907, 907, 907, 907, - 907, 907, 907, 907, 907, 907, 907, 907, 908, 908, - 908, 908, 908, 908, 908, 908, 908, 908, 908, 908, - 908, 908, 908, 908, 908, 908, 908, 908, 908, 908, - 908, 908, 908, 908, 908, 908, 908, 908, 908, 908, - 908, 908, 908, 909, 909, 909, 909, 909, 909, 909, - 909, 909, 909, 909, 909, 909, 909, 909, 909, 909, - 909, 909, 909, 909, 909, 909, 909, 909, 909, 909, - 909, 909, 909, 909, 909, 909, 909, 909, 909, 909, - 909, 909, 909, 909, 909, 909, 909, 909, 909, 909, - 909, 909, 909, 909, 909, 909, 909, 909, 909, 909, - 909, 909, 909, 909, 909, 909, 909, 909, 909, 909, - 909, 909, 909, 909, 909 + 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, + 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, + 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, + 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, + 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, + 760, 760, 760, 760, 760, 760, 760, 760, 760, 760, + 760, 760, 760, 760, 760, 760, 760, 760, 761, 761, + 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, + 761, 761, 761, 761, 761, 761, 761, 761, 761, 761, + 761, 761, 762, 762, 762, 762, 762, 762, 762, 762, + 762, 762, 762, 762, 762, 762, 762, 763, 763, 763, + 763, 763, 764, 764, 764, 764, 764, 764, 764, 765, + 765, 766, 766, 767, 767, 767, 767, 767, 767, 767, + 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, + 767, 767, 767, 767, 767, 767, 767, 767, 767, 767, + 767, 767, 768, 768, 769, 769, 770, 770, 770, 771, + 771, 772, 772, 773, 773, 774, 775, 775, 775, 776, + 777, 777, 778, 778, 779, 779, 779, 780, 780, 781, + 781, 781, 781, 781, 782, 782, 783, 783, 784, 785, + 785, 786, 786, 787, 787, 787, 788, 788, 789, 789, + 789, 789, 789, 789, 789, 789, 789, 789, 789, 789, + 789, 790, 790, 791, 791, 792, 792, 792, 792, 792, + 792, 792, 792, 793, 793, 794, 794, 795, 795, 796, + 796, 797, 797, 798, 798, 798, 799, 799, 800, 800, + 801, 801, 801, 801, 801, 801, 801, 801, 801, 801, + 802, 802, 803, 804, 804, 805, 805, 805, 805, 805, + 805, 806, 807, 808, 808, 808, 809, 809, 810, 811, + 811, 812, 813, 813, 814, 814, 815, 815, 816, 816, + 816, 817, 817, 818, 818, 819, 819, 820, 820, 821, + 821, 822, 822, 823, 823, 824, 824, 824, 824, 824, + 825, 825, 826, 826, 827, 828, 828, 829, 829, 830, + 830, 830, 831, 831, 832, 832, 833, 833, 834, 834, + 835, 836, 837, 837, 838, 838, 838, 838, 838, 838, + 838, 838, 838, 838, 838, 838, 838, 838, 839, 840, + 841, 841, 841, 842, 842, 843, 843, 843, 844, 844, + 844, 845, 845, 845, 846, 846, 847, 847, 848, 848, + 849, 850, 850, 850, 850, 851, 851, 852, 853, 854, + 854, 855, 855, 855, 855, 856, 856, 857, 857, 858, + 858, 858, 858, 859, 859, 860, 861, 861, 862, 862, + 863, 863, 864, 864, 865, 865, 866, 866, 866, 866, + 866, 866, 867, 867, 868, 868, 869, 869, 870, 871, + 871, 871, 871, 872, 872, 873, 873, 873, 874, 874, + 874, 874, 874, 874, 874, 874, 874, 874, 874, 874, + 874, 874, 874, 874, 874, 874, 874, 874, 874, 874, + 874, 874, 874, 874, 874, 874, 874, 874, 875, 875, + 875, 876, 876, 877, 877, 878, 878, 879, 879, 879, + 879, 880, 881, 881, 882, 882, 882, 882, 883, 883, + 883, 883, 884, 884, 884, 884, 885, 885, 886, 886, + 886, 886, 886, 886, 886, 887, 887, 888, 888, 888, + 889, 889, 890, 890, 890, 890, 890, 891, 891, 891, + 891, 891, 892, 892, 893, 893, 894, 894, 895, 895, + 896, 896, 896, 897, 897, 898, 898, 899, 899, 900, + 901, 901, 901, 902, 902, 903, 903, 904, 905, 905, + 906, 907, 907, 908, 908, 908, 909, 909, 909, 909, + 909, 909, 909, 909, 910, 910, 911, 911, 912, 912, + 913, 914, 914, 914, 914, 914, 915, 915, 915, 915, + 916, 916, 916, 917, 917, 917, 918, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, + 919, 919, 919, 919, 920, 920, 920, 920, 920, 920, + 920, 920, 920, 920, 920, 920, 920, 920, 920, 920, + 920, 920, 920, 920, 920, 920, 920, 920, 920, 920, + 920, 920, 920, 920, 920, 920, 920, 920, 920, 920, + 920, 920, 920, 920, 920, 920, 920, 920, 920, 920, + 920, 920, 920, 920, 920, 920, 920, 920, 921, 921, + 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, + 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, + 921, 921, 921, 921, 921, 921, 921, 921, 921, 921, + 921, 921, 922, 922, 922, 922, 922, 922, 922, 922, + 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, + 922, 922, 922, 922, 922, 922, 922, 922, 922, 922, + 922, 922, 922, 922, 922, 923, 923, 923, 923, 923, + 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, + 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, + 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, + 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, + 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, + 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, + 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, + 923, 923, 923, 923, 923, 923, 923, 923, 923, 923, + 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, + 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, + 924, 924, 924, 924, 924, 924, 924, 924, 924, 924, + 924, 924, 924, 924, 924, 924, 925, 925, 925, 925, + 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, + 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, + 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, + 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, + 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, + 925, 925, 925, 925, 925, 925, 925, 925, 925, 925, + 925, 925, 925, 925, 925, 925, 925, 925 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ @@ -296757,67 +310559,69 @@ static const yytype_uint8 yyr2[] = 0, 2, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, - 4, 6, 4, 6, 4, 6, 4, 6, 1, 2, - 3, 2, 1, 3, 2, 3, 1, 3, 2, 5, - 3, 6, 4, 6, 6, 6, 5, 5, 6, 9, - 4, 5, 7, 6, 4, 8, 4, 2, 4, 3, - 6, 4, 2, 2, 2, 2, 1, 2, 0, 1, - 2, 2, 2, 1, 3, 4, 2, 1, 0, 2, - 3, 2, 3, 6, 6, 8, 6, 8, 6, 8, - 6, 8, 8, 10, 8, 10, 1, 0, 7, 1, - 4, 4, 7, 2, 1, 3, 4, 3, 0, 1, - 0, 2, 3, 5, 8, 5, 0, 5, 5, 7, - 2, 0, 1, 1, 1, 3, 2, 0, 1, 0, - 1, 3, 1, 3, 1, 2, 1, 3, 2, 6, - 8, 5, 1, 0, 1, 3, 2, 4, 5, 5, - 8, 1, 0, 3, 9, 12, 3, 0, 4, 6, - 1, 2, 1, 1, 0, 1, 2, 2, 1, 2, - 2, 1, 2, 3, 2, 2, 2, 2, 3, 3, - 3, 1, 3, 1, 0, 1, 2, 2, 2, 2, - 2, 2, 2, 2, 1, 1, 0, 9, 12, 11, - 0, 2, 1, 1, 1, 1, 1, 1, 3, 0, - 1, 2, 1, 1, 2, 2, 3, 1, 1, 2, - 2, 1, 2, 3, 5, 3, 2, 5, 1, 1, - 1, 0, 5, 7, 5, 2, 3, 1, 1, 2, - 2, 0, 3, 4, 4, 0, 3, 2, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 3, 3, 1, 2, 2, 2, 2, 2, 2, 0, - 3, 3, 3, 0, 1, 2, 1, 2, 2, 2, - 2, 3, 4, 1, 3, 1, 1, 1, 1, 3, - 1, 2, 0, 1, 2, 0, 1, 3, 0, 2, - 0, 3, 3, 1, 5, 3, 1, 3, 1, 2, - 1, 4, 5, 5, 6, 3, 7, 4, 11, 1, - 3, 2, 2, 2, 0, 3, 1, 1, 2, 2, - 2, 2, 1, 0, 1, 2, 6, 4, 6, 4, - 6, 8, 4, 6, 1, 1, 1, 1, 2, 1, - 2, 1, 2, 1, 1, 1, 3, 3, 3, 3, - 2, 2, 1, 3, 1, 1, 1, 1, 3, 1, - 1, 0, 1, 1, 1, 1, 3, 8, 11, 10, - 7, 10, 9, 1, 1, 2, 3, 8, 11, 9, - 1, 1, 3, 0, 1, 3, 1, 0, 1, 0, - 1, 0, 1, 3, 1, 1, 1, 3, 0, 2, - 2, 0, 2, 0, 1, 0, 1, 1, 1, 3, - 3, 1, 1, 3, 3, 3, 3, 4, 3, 2, - 1, 1, 1, 1, 1, 3, 1, 1, 3, 3, - 1, 2, 4, 4, 2, 3, 5, 5, 1, 1, - 3, 0, 11, 11, 10, 12, 1, 2, 5, 4, - 4, 4, 2, 2, 3, 1, 3, 6, 2, 0, - 3, 3, 4, 4, 4, 4, 3, 2, 1, 1, - 0, 1, 1, 0, 2, 1, 5, 1, 0, 2, - 2, 0, 1, 0, 3, 5, 5, 1, 3, 4, - 3, 1, 1, 0, 2, 2, 0, 2, 2, 1, - 1, 1, 0, 2, 4, 5, 4, 2, 3, 2, - 2, 2, 2, 1, 2, 3, 0, 1, 0, 5, - 1, 4, 6, 2, 1, 0, 4, 0, 1, 1, - 2, 2, 2, 1, 1, 2, 2, 1, 1, 1, - 1, 1, 1, 3, 3, 3, 0, 1, 3, 1, - 2, 1, 1, 1, 1, 1, 2, 4, 4, 5, - 1, 1, 2, 0, 2, 0, 1, 3, 1, 0, - 1, 2, 3, 2, 4, 2, 3, 2, 0, 1, - 2, 0, 4, 5, 1, 2, 2, 0, 1, 3, - 1, 2, 3, 3, 3, 3, 3, 3, 1, 4, - 3, 4, 5, 4, 5, 4, 5, 2, 4, 1, + 1, 1, 1, 0, 4, 6, 4, 6, 4, 6, + 4, 6, 1, 2, 3, 2, 1, 3, 2, 3, + 1, 3, 2, 5, 3, 6, 4, 6, 6, 6, + 5, 5, 6, 9, 4, 5, 7, 6, 4, 8, + 4, 2, 4, 3, 6, 4, 2, 2, 2, 2, + 1, 2, 0, 1, 2, 2, 2, 1, 3, 4, + 2, 1, 0, 2, 3, 2, 3, 6, 6, 8, + 6, 8, 6, 8, 6, 8, 8, 10, 8, 10, + 1, 0, 8, 1, 4, 4, 7, 2, 1, 3, + 4, 3, 0, 1, 0, 2, 3, 5, 2, 2, + 0, 8, 5, 0, 5, 5, 7, 2, 0, 1, + 1, 1, 3, 2, 0, 1, 0, 1, 3, 1, + 3, 1, 2, 1, 3, 2, 6, 8, 5, 1, + 0, 1, 3, 2, 4, 5, 3, 4, 6, 5, + 5, 8, 7, 1, 5, 8, 1, 0, 3, 9, + 12, 3, 0, 4, 6, 1, 2, 1, 1, 0, + 1, 2, 2, 1, 2, 2, 1, 2, 3, 2, + 2, 2, 2, 3, 3, 3, 1, 3, 1, 0, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 1, + 1, 0, 2, 9, 12, 11, 0, 2, 1, 1, + 1, 1, 1, 1, 3, 0, 1, 2, 1, 1, + 2, 2, 3, 1, 1, 2, 2, 1, 2, 3, + 5, 3, 2, 5, 1, 1, 1, 0, 5, 7, + 5, 2, 3, 1, 1, 2, 2, 0, 3, 4, + 4, 0, 3, 2, 0, 3, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 3, 3, 1, 2, + 2, 2, 2, 2, 2, 0, 3, 3, 3, 0, + 1, 2, 1, 2, 2, 2, 2, 3, 4, 1, + 3, 1, 1, 1, 1, 3, 1, 2, 0, 1, + 2, 0, 1, 3, 0, 2, 0, 3, 3, 1, + 5, 3, 1, 3, 1, 2, 1, 4, 5, 5, + 6, 3, 7, 4, 11, 1, 3, 2, 2, 2, + 0, 3, 1, 1, 2, 2, 2, 2, 1, 0, + 1, 2, 6, 4, 6, 4, 6, 8, 4, 6, + 1, 1, 1, 1, 1, 2, 1, 2, 1, 2, + 1, 1, 1, 1, 3, 3, 3, 3, 2, 2, + 1, 3, 1, 1, 1, 3, 1, 1, 0, 1, + 1, 1, 1, 3, 8, 11, 10, 7, 10, 9, + 1, 1, 2, 3, 8, 11, 9, 1, 1, 3, + 0, 1, 3, 1, 0, 1, 0, 1, 0, 1, + 3, 1, 1, 1, 3, 0, 2, 2, 0, 2, + 0, 1, 0, 1, 1, 1, 3, 3, 1, 1, + 3, 3, 3, 3, 3, 3, 4, 3, 2, 1, + 1, 1, 1, 1, 3, 1, 1, 3, 3, 1, + 2, 4, 4, 2, 3, 5, 5, 1, 1, 3, + 0, 11, 11, 10, 12, 1, 2, 5, 4, 4, + 4, 2, 2, 3, 1, 3, 6, 2, 0, 3, + 3, 4, 4, 4, 4, 3, 2, 1, 1, 0, + 1, 1, 0, 2, 1, 5, 1, 0, 2, 2, + 0, 1, 0, 3, 5, 5, 1, 3, 4, 3, + 1, 1, 0, 2, 2, 0, 2, 2, 1, 1, + 1, 0, 2, 4, 5, 4, 2, 3, 2, 2, + 2, 2, 1, 2, 3, 0, 1, 0, 5, 1, + 4, 6, 2, 1, 0, 4, 0, 1, 1, 2, + 2, 2, 1, 1, 2, 2, 1, 1, 1, 1, + 1, 1, 3, 3, 3, 0, 1, 3, 1, 2, + 1, 1, 1, 1, 1, 2, 4, 4, 5, 1, + 1, 2, 0, 2, 0, 1, 3, 1, 0, 1, + 2, 3, 2, 4, 2, 3, 2, 0, 1, 2, + 0, 4, 5, 1, 2, 2, 0, 1, 3, 1, + 2, 3, 3, 3, 3, 3, 3, 1, 4, 3, + 4, 5, 4, 5, 4, 4, 5, 2, 4, 1, 1, 0, 1, 4, 5, 4, 0, 2, 2, 2, 1, 1, 0, 4, 2, 1, 2, 2, 4, 2, 6, 2, 1, 3, 4, 0, 2, 0, 2, 0, @@ -296841,52 +310645,54 @@ static const yytype_uint8 yyr2[] = 7, 3, 4, 4, 6, 1, 6, 4, 1, 3, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 5, 6, - 6, 7, 1, 1, 2, 2, 2, 4, 1, 3, - 3, 1, 2, 4, 1, 2, 1, 2, 2, 4, - 3, 6, 7, 9, 7, 7, 4, 5, 1, 1, - 1, 5, 1, 1, 4, 1, 4, 1, 4, 1, - 4, 1, 1, 1, 1, 1, 1, 6, 6, 4, - 4, 4, 4, 6, 5, 5, 5, 4, 6, 4, - 7, 9, 5, 0, 5, 4, 0, 1, 0, 2, - 0, 1, 3, 3, 2, 2, 0, 6, 1, 0, - 3, 0, 2, 2, 0, 1, 4, 2, 2, 2, - 2, 2, 4, 3, 1, 5, 3, 1, 3, 1, - 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 6, 7, 1, 1, 2, 2, 2, 1, 3, 1, + 2, 4, 1, 1, 2, 2, 4, 1, 1, 3, + 3, 1, 3, 6, 7, 9, 7, 7, 4, 5, + 1, 1, 1, 5, 1, 1, 4, 1, 4, 1, + 4, 1, 4, 1, 1, 1, 1, 1, 1, 6, + 6, 4, 4, 4, 4, 6, 5, 5, 5, 4, + 6, 4, 7, 9, 5, 0, 5, 4, 0, 1, + 0, 2, 0, 1, 3, 3, 2, 2, 0, 6, + 1, 0, 3, 0, 2, 2, 0, 1, 4, 2, + 2, 2, 2, 2, 4, 3, 1, 5, 3, 1, + 3, 1, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 4, 1, 4, 1, 4, 1, 2, 1, + 2, 1, 2, 1, 3, 1, 3, 1, 2, 1, + 0, 1, 3, 1, 3, 3, 1, 3, 3, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 4, 3, 2, 3, 0, 3, 3, 2, 2, 1, + 0, 2, 2, 3, 2, 1, 1, 3, 5, 1, + 2, 4, 2, 0, 1, 0, 1, 2, 2, 3, + 5, 1, 0, 1, 2, 0, 2, 1, 0, 1, + 0, 1, 3, 1, 2, 3, 2, 1, 3, 5, + 4, 2, 1, 0, 3, 1, 3, 1, 2, 4, + 2, 0, 1, 3, 1, 2, 1, 3, 1, 2, + 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, + 7, 2, 5, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 4, 1, 4, 1, 4, 1, 2, 1, 2, 1, - 2, 1, 3, 1, 3, 1, 2, 1, 0, 1, - 3, 1, 3, 3, 1, 3, 3, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 4, 3, - 2, 3, 0, 3, 3, 2, 2, 1, 0, 2, - 2, 3, 2, 1, 1, 3, 5, 1, 2, 4, - 2, 0, 1, 0, 1, 2, 2, 3, 5, 1, - 0, 1, 2, 0, 2, 1, 0, 1, 0, 1, - 3, 1, 2, 3, 2, 1, 3, 5, 4, 2, - 1, 0, 3, 1, 3, 1, 2, 4, 2, 0, - 1, 3, 1, 2, 1, 3, 1, 2, 1, 1, - 1, 2, 1, 1, 2, 1, 1, 2, 7, 2, - 5, 3, 3, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 2, 3, 3, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 5, 3, + 0, 1, 1, 1, 1, 4, 7, 2, 0, 1, + 1, 1, 1, 13, 16, 1, 2, 0, 1, 0, + 1, 0, 2, 0, 1, 0, 6, 8, 6, 8, + 6, 8, 3, 2, 1, 0, 4, 6, 3, 2, + 4, 3, 5, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 2, 3, 3, 0, 1, 1, - 1, 1, 1, 1, 1, 5, 3, 0, 1, 1, - 1, 1, 4, 7, 2, 0, 1, 1, 1, 1, - 13, 16, 1, 2, 0, 1, 0, 1, 0, 2, - 0, 1, 0, 6, 8, 6, 8, 6, 8, 2, - 1, 4, 3, 2, 4, 3, 5, 1, 0, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, - 1, 1, 1, 1, 1, 2, 1, 1, 2, 3, - 3, 3, 1, 3, 3, 2, 3, 3, 3, 3, - 1, 1, 1, 1, 3, 5, 1, 1, 1, 1, - 3, 2, 2, 3, 1, 1, 4, 5, 5, 4, - 6, 1, 1, 1, 1, 1, 1, 0, 1, 3, - 1, 0, 7, 3, 1, 2, 3, 2, 0, 2, - 0, 2, 4, 2, 1, 1, 1, 2, 3, 2, - 2, 2, 2, 3, 4, 2, 1, 1, 1, 1, - 3, 1, 3, 2, 9, 11, 12, 14, 3, 4, - 4, 0, 7, 10, 9, 2, 3, 0, 4, 1, + 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, + 1, 2, 1, 1, 2, 3, 3, 3, 1, 3, + 3, 2, 3, 3, 3, 3, 1, 1, 1, 1, + 3, 5, 1, 1, 1, 1, 3, 2, 2, 3, + 1, 1, 4, 5, 5, 4, 6, 1, 1, 1, + 1, 1, 1, 0, 1, 3, 1, 0, 7, 3, + 1, 2, 3, 2, 0, 2, 0, 2, 4, 5, + 3, 2, 5, 1, 0, 2, 0, 1, 1, 3, + 2, 1, 1, 1, 2, 3, 2, 2, 2, 2, + 3, 4, 2, 1, 1, 1, 1, 3, 1, 3, + 2, 9, 12, 11, 12, 14, 3, 4, 4, 0, + 7, 10, 9, 2, 3, 0, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -296948,7 +310754,7 @@ static const yytype_uint8 yyr2[] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 + 1, 1, 1, 1, 1, 1, 1, 1 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -296956,7637 +310762,7778 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint16 yydefact[] = { - 130, 216, 0, 1230, 1229, 216, 0, 1180, 216, 435, - 353, 0, 1308, 0, 216, 0, 130, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 216, 508, 0, 1307, - 216, 0, 0, 500, 1277, 0, 0, 0, 0, 0, - 2, 4, 7, 18, 30, 26, 0, 17, 28, 15, - 21, 6, 32, 16, 20, 13, 33, 11, 31, 469, - 456, 513, 468, 129, 614, 476, 29, 14, 25, 5, - 10, 23, 24, 22, 1188, 36, 27, 34, 19, 8, - 35, 37, 1306, 9, 38, 12, 215, 214, 208, 0, - 0, 0, 0, 0, 209, 1118, 1329, 1330, 1331, 1332, - 1333, 1334, 1335, 1336, 1337, 1338, 1339, 1340, 1341, 1342, - 1343, 1344, 1689, 1345, 1346, 1347, 1635, 1636, 1690, 1637, - 1638, 1348, 1349, 1350, 1351, 1352, 1353, 1354, 1355, 1639, - 1640, 1356, 1357, 1358, 1359, 1360, 1641, 1691, 1642, 1361, - 1362, 1363, 1364, 1365, 1692, 1366, 1367, 1368, 1369, 1370, - 1371, 1372, 1373, 1374, 1693, 1375, 1376, 1377, 1694, 1695, - 1696, 1697, 1698, 1378, 1379, 1380, 1381, 1382, 1383, 1384, - 1643, 1644, 1385, 1386, 1387, 1388, 1389, 1390, 1391, 1392, - 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 1402, - 1403, 1404, 1405, 1406, 1407, 1408, 1409, 1410, 1411, 1412, - 1645, 1413, 1414, 1415, 1416, 1417, 1646, 1418, 1419, 1420, - 1647, 1421, 1422, 1423, 1699, 1700, 1424, 1425, 1648, 1702, - 1426, 1427, 1649, 1650, 1428, 1429, 1430, 1431, 1432, 1433, - 1434, 1435, 1703, 1436, 1437, 1438, 1439, 1440, 1441, 1442, - 1443, 1444, 1445, 1446, 1704, 1651, 1447, 1448, 1449, 1450, - 1451, 1652, 1653, 1654, 1452, 1705, 1706, 1453, 1707, 1454, - 1455, 1456, 1457, 1458, 1459, 1460, 1708, 1461, 1709, 1462, - 1463, 1464, 1465, 1466, 1467, 1468, 1469, 1655, 1470, 1471, - 1472, 1473, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1481, - 1482, 1483, 1484, 1485, 1486, 1487, 1656, 1711, 1657, 1488, - 1489, 1490, 1658, 1491, 1492, 1712, 1493, 1659, 1494, 1660, - 1495, 1496, 1497, 1498, 1499, 1500, 1501, 1502, 1503, 1661, - 1713, 1504, 1714, 1662, 1505, 1506, 1507, 1508, 1509, 1510, - 1511, 1512, 1513, 1514, 1515, 1516, 1663, 1517, 1518, 1664, - 1519, 1520, 1521, 1522, 1523, 1524, 1525, 1526, 1527, 1528, - 1529, 1530, 1665, 1531, 1532, 1533, 1534, 1535, 1536, 1537, - 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545, 1546, 1547, - 1548, 1549, 1715, 1550, 1551, 1552, 1666, 1553, 1554, 1555, - 1556, 1557, 1558, 1559, 1560, 1561, 1562, 1563, 1564, 1565, - 1566, 1567, 1568, 1716, 1569, 1667, 1570, 1571, 1572, 1717, - 1573, 1574, 1668, 1575, 1576, 1577, 1578, 1579, 1580, 1581, - 1582, 1583, 1584, 1585, 1586, 1587, 1669, 1588, 1670, 1589, - 1590, 1591, 1592, 1719, 1593, 1594, 1595, 1596, 1597, 1671, - 1672, 1598, 1599, 1673, 1600, 1674, 1601, 1602, 1675, 1603, - 1604, 1605, 1606, 1607, 1608, 1609, 1610, 1611, 1612, 1720, - 1613, 1614, 1615, 1616, 1617, 1676, 1677, 1618, 1721, 1619, - 1620, 1621, 1622, 1623, 1624, 1625, 1626, 1627, 1628, 1629, - 1630, 1678, 1679, 1680, 1681, 1682, 1683, 1684, 1685, 1686, - 1687, 1688, 1631, 1632, 1633, 1634, 1313, 0, 0, 1100, - 1119, 1120, 1128, 211, 434, 0, 0, 0, 0, 0, - 0, 347, 346, 0, 1171, 352, 0, 0, 1118, 1122, - 101, 1648, 1655, 1519, 1669, 99, 1121, 1098, 1119, 0, - 373, 374, 0, 382, 0, 366, 371, 367, 0, 392, - 384, 393, 385, 365, 386, 375, 364, 0, 394, 0, - 369, 0, 0, 0, 212, 177, 130, 0, 1194, 1204, - 1213, 1209, 1203, 1211, 1201, 1207, 1193, 1215, 1202, 1206, - 1199, 1216, 1197, 1214, 1212, 1200, 1208, 1192, 1196, 1183, - 1188, 1219, 1210, 1217, 1205, 1218, 1220, 1195, 1221, 1198, - 0, 1179, 0, 0, 1641, 1691, 915, 902, 911, 916, - 903, 905, 912, 1646, 0, 907, 909, 1659, 0, 1662, - 1663, 1553, 913, 1670, 1673, 1674, 1675, 914, 1676, 0, - 641, 0, 471, 618, 628, 641, 646, 899, 667, 900, - 655, 1121, 1092, 0, 1117, 1264, 1265, 1262, 1261, 166, - 1147, 1295, 1671, 1598, 1309, 1296, 1293, 1294, 213, 507, - 505, 0, 1068, 1426, 1464, 1557, 1568, 1671, 1238, 1242, - 0, 210, 1300, 0, 1311, 1301, 477, 1121, 499, 0, - 1276, 0, 1281, 0, 1533, 482, 485, 1137, 483, 469, - 0, 1, 130, 0, 0, 0, 503, 503, 0, 503, - 0, 461, 469, 464, 468, 615, 1187, 1291, 1305, 1671, - 1598, 1299, 1302, 1434, 0, 0, 1434, 0, 1434, 0, - 1434, 0, 0, 1060, 0, 1061, 1101, 0, 318, 351, - 350, 349, 348, 353, 1434, 1155, 1132, 0, 403, 404, - 0, 0, 0, 0, 0, 1166, 102, 100, 380, 381, - 0, 372, 368, 370, 0, 1129, 1722, 710, 1723, 739, - 717, 739, 739, 1724, 1725, 1726, 1727, 1728, 1729, 1730, - 1731, 1732, 706, 706, 1400, 719, 1733, 1734, 1735, 1434, - 1736, 1737, 707, 708, 744, 1738, 1739, 1740, 1741, 1742, - 0, 0, 1743, 739, 1744, 706, 1745, 1746, 711, 1747, - 677, 1748, 0, 1749, 709, 678, 1750, 747, 747, 1751, - 0, 1752, 734, 1753, 391, 0, 395, 692, 693, 694, - 695, 720, 721, 696, 726, 727, 731, 697, 779, 706, - 1130, 1131, 1434, 391, 387, 1434, 391, 1094, 1434, 0, - 0, 173, 1185, 1222, 1754, 1755, 1756, 1757, 1758, 1759, - 1761, 1760, 1762, 1763, 1764, 1765, 1766, 1767, 1768, 1769, - 1770, 1771, 1772, 1773, 1774, 1775, 1776, 1777, 1778, 1779, - 1780, 1781, 1782, 1783, 1784, 1785, 1788, 1786, 1787, 1789, - 1790, 1791, 1792, 1793, 1794, 1795, 1796, 1797, 1798, 1799, - 1800, 1801, 1803, 1802, 1804, 1805, 1806, 1807, 1808, 1809, - 1810, 1811, 1812, 1813, 1814, 1815, 1816, 1817, 1818, 1819, - 1820, 1821, 1822, 1823, 1824, 1825, 1826, 1827, 1828, 1829, - 1830, 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1236, 0, - 1237, 1227, 1191, 1223, 1224, 130, 433, 1263, 0, 0, - 0, 0, 0, 1017, 641, 646, 0, 0, 0, 0, - 657, 0, 1032, 0, 1038, 0, 0, 0, 469, 476, - 0, 628, 0, 640, 555, 639, 555, 508, 0, 489, - 0, 652, 650, 0, 652, 0, 652, 0, 555, 0, - 642, 555, 639, 0, 659, 656, 1093, 1182, 0, 0, - 0, 0, 1297, 0, 0, 0, 1103, 1105, 1106, 989, - 1116, 1063, 0, 1636, 1637, 1638, 1053, 1639, 1640, 1642, - 1643, 1644, 845, 1645, 1114, 1647, 1649, 1650, 1652, 1653, - 1654, 1656, 1657, 0, 1115, 1660, 1500, 1665, 1666, 1668, - 1671, 1672, 1113, 1677, 0, 0, 0, 1081, 1008, 0, - 0, 1063, 0, 886, 0, 0, 700, 701, 722, 723, - 702, 728, 729, 703, 0, 1075, 780, 933, 1063, 898, - 881, 964, 878, 0, 884, 872, 1071, 489, 1069, 0, - 873, 1102, 1063, 1054, 489, 1067, 1241, 1239, 1245, 1240, - 0, 0, 0, 0, 0, 1093, 1284, 1283, 1275, 1273, - 1274, 1272, 1271, 1278, 0, 1280, 1188, 1003, 1005, 0, - 1054, 484, 0, 0, 0, 459, 458, 3, 0, 0, - 0, 501, 502, 0, 0, 0, 0, 0, 0, 0, - 0, 599, 529, 530, 532, 596, 600, 608, 0, 465, - 0, 1137, 1303, 0, 0, 0, 117, 117, 0, 0, - 0, 0, 0, 93, 42, 86, 0, 0, 0, 0, - 191, 204, 0, 0, 0, 0, 0, 201, 0, 0, - 184, 44, 178, 180, 0, 117, 0, 40, 0, 0, - 0, 46, 1118, 0, 1689, 1690, 1691, 1642, 1692, 1693, - 915, 902, 911, 916, 912, 0, 1699, 1700, 1648, 1702, - 1703, 1704, 1705, 1706, 1707, 1708, 1709, 1655, 1711, 1712, - 1713, 1714, 1715, 913, 1717, 1669, 1719, 1675, 914, 0, - 1721, 0, 890, 1011, 513, 1009, 1138, 0, 1119, 1125, - 1059, 0, 1139, 1873, 1874, 1875, 1876, 1877, 1878, 1879, - 1880, 1881, 1882, 1883, 1884, 1885, 1886, 1887, 1888, 1889, - 1890, 1891, 1892, 1893, 1894, 1895, 1896, 1897, 1898, 1899, - 1900, 1901, 1902, 1903, 1904, 1905, 1906, 1907, 1908, 1909, - 1910, 1911, 1912, 1913, 1914, 1915, 1916, 1917, 1918, 1919, - 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1929, - 1930, 1931, 1932, 1933, 1934, 1935, 1936, 1937, 1938, 1939, - 1824, 1940, 1941, 1942, 1943, 1944, 1056, 1099, 1141, 1140, - 1142, 1062, 0, 0, 431, 0, 0, 1152, 0, 1133, - 0, 0, 1434, 172, 1434, 318, 0, 318, 1434, 0, - 1165, 1168, 383, 379, 377, 376, 378, 738, 725, 733, - 732, 1008, 715, 714, 713, 0, 712, 0, 0, 739, - 739, 737, 716, 692, 0, 0, 0, 743, 0, 741, - 0, 389, 390, 0, 362, 0, 685, 681, 0, 752, - 753, 754, 755, 762, 763, 760, 761, 756, 757, 750, - 751, 758, 759, 748, 749, 0, 764, 765, 766, 767, - 768, 769, 770, 771, 698, 704, 0, 0, 357, 0, - 0, 359, 0, 0, 0, 130, 0, 185, 1232, 1233, - 1231, 0, 0, 1190, 188, 205, 1226, 1235, 1225, 1234, - 1189, 1184, 0, 1181, 422, 0, 0, 0, 0, 0, - 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 0, - 0, 1027, 627, 625, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 848, 878, 0, 0, 0, 1003, 1037, - 0, 0, 0, 0, 0, 0, 1003, 1043, 0, 0, - 630, 637, 548, 554, 626, 0, 624, 0, 1068, 619, - 0, 669, 0, 651, 647, 0, 648, 0, 0, 649, - 0, 622, 0, 637, 623, 0, 666, 1251, 1250, 1259, - 167, 0, 1014, 0, 130, 1298, 1310, 0, 876, 1008, - 882, 1052, 0, 0, 888, 804, 0, 0, 805, 784, - 785, 0, 1080, 1089, 1003, 1007, 0, 886, 1003, 0, - 874, 875, 967, 969, 0, 0, 887, 0, 1109, 0, - 779, 779, 1074, 989, 0, 982, 0, 0, 986, 987, - 988, 0, 0, 0, 1066, 0, 997, 999, 0, 0, - 820, 995, 0, 823, 0, 0, 0, 0, 983, 984, - 985, 976, 977, 978, 979, 980, 981, 993, 975, 801, - 0, 0, 936, 885, 0, 800, 1072, 617, 0, 1107, - 1104, 0, 1055, 617, 1253, 1257, 1258, 1256, 0, 1252, - 1244, 1243, 1248, 1246, 1249, 1247, 1312, 0, 1285, 1269, - 0, 1266, 1006, 612, 486, 1096, 0, 0, 1290, 0, - 124, 0, 481, 480, 523, 523, 514, 517, 523, 0, - 479, 0, 571, 572, 0, 0, 0, 0, 605, 603, - 1103, 1116, 559, 533, 558, 0, 0, 537, 0, 563, - 780, 598, 463, 527, 528, 531, 462, 0, 601, 0, - 611, 599, 532, 0, 1292, 1304, 0, 0, 0, 0, - 0, 1434, 0, 0, 77, 58, 270, 680, 116, 0, - 0, 0, 0, 0, 0, 0, 85, 82, 83, 84, - 0, 0, 0, 0, 189, 190, 203, 0, 194, 195, - 192, 196, 197, 0, 0, 182, 183, 0, 0, 0, - 0, 181, 0, 0, 0, 0, 0, 0, 0, 0, - 513, 513, 513, 896, 0, 511, 512, 0, 0, 1057, - 1060, 421, 326, 0, 316, 0, 0, 0, 0, 0, - 0, 0, 353, 1158, 1156, 1154, 1157, 1159, 1134, 0, - 1406, 161, 0, 0, 169, 171, 0, 315, 289, 0, - 1170, 0, 0, 0, 1434, 1167, 305, 0, 0, 0, - 0, 391, 0, 736, 735, 686, 682, 0, 0, 0, - 0, 0, 0, 396, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 391, 388, 391, 1095, 0, 391, 176, - 1186, 1228, 186, 206, 187, 207, 454, 0, 428, 436, - 441, 419, 0, 419, 0, 438, 442, 419, 437, 419, - 432, 0, 929, 0, 904, 906, 919, 0, 908, 910, - 0, 658, 0, 0, 920, 850, 851, 0, 0, 0, + 134, 231, 0, 1256, 1255, 1324, 231, 0, 1205, 231, + 452, 369, 0, 1345, 0, 0, 231, 0, 134, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 231, 527, + 0, 1344, 231, 0, 0, 519, 0, 1303, 0, 0, + 0, 0, 0, 2, 4, 7, 20, 33, 29, 0, + 19, 31, 14, 17, 24, 6, 35, 37, 18, 23, + 15, 36, 12, 34, 488, 475, 532, 487, 133, 633, + 495, 32, 16, 28, 5, 11, 26, 27, 25, 1214, + 40, 30, 38, 21, 8, 9, 22, 39, 41, 1343, + 10, 42, 13, 230, 229, 223, 0, 0, 0, 0, + 0, 1323, 0, 224, 1140, 1367, 1368, 1369, 1370, 1371, + 1372, 1373, 1374, 1375, 1376, 1377, 1378, 1379, 1380, 1381, + 1382, 1728, 1383, 1384, 1385, 1674, 1675, 1729, 1676, 1677, + 1386, 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1678, 1679, + 1394, 1395, 1396, 1397, 1398, 1680, 1730, 1681, 1399, 1400, + 1401, 1402, 1403, 1731, 1404, 1405, 1406, 1407, 1408, 1409, + 1410, 1411, 1412, 1732, 1413, 1414, 1415, 1733, 1734, 1735, + 1736, 1737, 1416, 1417, 1418, 1419, 1420, 1421, 1422, 1682, + 1683, 1423, 1424, 1425, 1426, 1427, 1428, 1429, 1430, 1431, + 1432, 1433, 1434, 1435, 1436, 1437, 1438, 1439, 1440, 1441, + 1442, 1443, 1444, 1445, 1446, 1447, 1448, 1449, 1450, 1684, + 1451, 1452, 1453, 1454, 1455, 1685, 1456, 1457, 1458, 1686, + 1459, 1460, 1461, 1738, 1739, 1462, 1463, 1687, 1741, 1464, + 1465, 1688, 1689, 1466, 1467, 1468, 1469, 1470, 1471, 1472, + 1473, 1742, 1474, 1475, 1476, 1477, 1478, 1479, 1480, 1481, + 1482, 1483, 1484, 1743, 1690, 1485, 1486, 1487, 1488, 1489, + 1691, 1692, 1693, 1490, 1744, 1745, 1491, 1746, 1492, 1493, + 1494, 1495, 1496, 1497, 1498, 1747, 1499, 1748, 1500, 1501, + 1502, 1503, 1504, 1505, 1506, 1507, 1694, 1508, 1509, 1510, + 1511, 1512, 1513, 1514, 1515, 1516, 1517, 1518, 1519, 1520, + 1521, 1522, 1523, 1524, 1525, 1695, 1750, 1696, 1526, 1527, + 1528, 1697, 1529, 1530, 1751, 1531, 1698, 1532, 1699, 1533, + 1534, 1535, 1536, 1537, 1538, 1539, 1540, 1541, 1700, 1752, + 1542, 1753, 1701, 1543, 1544, 1545, 1546, 1547, 1548, 1549, + 1550, 1551, 1552, 1553, 1554, 1702, 1754, 1555, 1556, 1703, + 1557, 1558, 1559, 1560, 1561, 1562, 1563, 1564, 1565, 1566, + 1567, 1568, 1704, 1569, 1570, 1571, 1572, 1573, 1574, 1575, + 1576, 1577, 1578, 1579, 1580, 1581, 1582, 1583, 1584, 1585, + 1586, 1587, 1755, 1588, 1589, 1590, 1705, 1591, 1592, 1593, + 1594, 1595, 1596, 1597, 1598, 1599, 1600, 1601, 1602, 1603, + 1604, 1605, 1606, 1756, 1607, 1706, 1608, 1609, 1610, 1757, + 1611, 1612, 1707, 1613, 1614, 1615, 1616, 1617, 1618, 1619, + 1620, 1621, 1622, 1623, 1624, 1625, 1708, 1626, 1709, 1627, + 1628, 1629, 1630, 1759, 1631, 1632, 1633, 1634, 1635, 1710, + 1711, 1636, 1637, 1712, 1638, 1713, 1639, 1640, 1714, 1641, + 1642, 1643, 1644, 1645, 1646, 1647, 1648, 1649, 1650, 1651, + 1760, 1652, 1653, 1654, 1655, 1656, 1715, 1716, 1657, 1761, + 1658, 1659, 1660, 1661, 1662, 1663, 1664, 1665, 1666, 1667, + 1668, 1669, 1717, 1718, 1719, 1720, 1721, 1722, 1723, 1724, + 1725, 1726, 1727, 1670, 1671, 1672, 1673, 1350, 0, 0, + 1122, 1141, 1142, 1150, 1140, 1687, 1694, 1708, 1204, 1203, + 1141, 226, 451, 0, 0, 1139, 0, 0, 0, 0, + 0, 363, 362, 0, 1194, 368, 0, 0, 183, 0, + 1144, 105, 1557, 103, 1143, 1120, 1327, 0, 1328, 1321, + 0, 390, 391, 381, 0, 400, 0, 383, 388, 384, + 0, 409, 402, 410, 392, 382, 403, 393, 380, 0, + 411, 0, 386, 0, 0, 0, 227, 192, 369, 134, + 0, 1220, 1230, 1239, 1235, 1229, 1237, 1227, 1233, 1219, + 1241, 1228, 1232, 1225, 1242, 1223, 1240, 1238, 1226, 1234, + 1218, 1222, 1209, 1214, 1245, 1236, 1243, 1231, 1244, 1246, + 1221, 1247, 1224, 0, 1205, 0, 0, 1680, 1730, 937, + 924, 933, 938, 925, 927, 934, 1685, 0, 929, 931, + 1698, 0, 1701, 1702, 1591, 935, 1709, 1712, 1713, 1714, + 936, 1715, 0, 661, 0, 490, 637, 647, 661, 666, + 921, 687, 922, 675, 1143, 1114, 0, 1290, 1291, 1288, + 1287, 173, 1170, 1332, 1710, 1636, 1346, 1333, 1330, 1331, + 228, 526, 524, 0, 1090, 1464, 1502, 1595, 1606, 1710, + 1264, 1268, 0, 225, 1337, 0, 1348, 1338, 496, 1143, + 518, 0, 232, 1302, 0, 1307, 0, 1571, 501, 504, + 1159, 502, 488, 0, 1, 134, 0, 140, 0, 522, + 522, 0, 522, 0, 480, 488, 483, 487, 634, 1213, + 1317, 1342, 1710, 1636, 1336, 1339, 1472, 0, 0, 1472, + 0, 1472, 0, 1472, 0, 1326, 0, 1082, 0, 1083, + 1123, 0, 334, 1472, 176, 367, 366, 365, 364, 369, + 1472, 1178, 0, 0, 420, 421, 0, 0, 0, 0, + 0, 1189, 106, 104, 1472, 1320, 1154, 404, 0, 398, + 399, 0, 389, 385, 387, 0, 1151, 1762, 730, 1763, + 759, 737, 759, 759, 1764, 1765, 1766, 1767, 1768, 1769, + 1770, 1771, 1772, 726, 726, 1438, 739, 1773, 1774, 1775, + 1472, 1776, 1777, 727, 728, 764, 1778, 1779, 1780, 1781, + 1782, 0, 0, 1783, 759, 1784, 726, 1785, 1786, 1787, + 731, 1788, 697, 1789, 0, 1790, 729, 698, 1791, 767, + 767, 1792, 0, 1793, 754, 1794, 408, 0, 412, 712, + 713, 714, 715, 740, 741, 716, 746, 747, 751, 717, + 799, 726, 1152, 1153, 1472, 408, 1472, 408, 1116, 1472, + 0, 0, 188, 0, 1211, 1248, 1795, 1796, 1797, 1798, + 1799, 1800, 1802, 1801, 1803, 1804, 1805, 1806, 1807, 1808, + 1809, 1810, 1811, 1812, 1813, 1814, 1815, 1816, 1817, 1818, + 1819, 1820, 1821, 1822, 1823, 1824, 1825, 1826, 1829, 1827, + 1828, 1830, 1831, 1832, 1833, 1834, 1835, 1836, 1837, 1838, + 1839, 1840, 1841, 1842, 1844, 1843, 1845, 1846, 1847, 1848, + 1849, 1850, 1851, 1852, 1853, 1854, 1855, 1856, 1857, 1858, + 1859, 1860, 1861, 1862, 1863, 1864, 1865, 1866, 1867, 1868, + 1869, 1870, 1871, 1872, 1873, 1874, 1875, 1876, 1877, 1878, + 1879, 1262, 0, 1263, 1253, 1217, 1249, 1250, 134, 450, + 0, 1202, 1289, 0, 0, 0, 0, 0, 1039, 661, + 666, 0, 0, 0, 0, 677, 0, 1054, 0, 1060, + 0, 0, 0, 661, 495, 0, 647, 0, 660, 574, + 659, 574, 527, 0, 508, 0, 672, 670, 0, 672, + 0, 0, 672, 0, 574, 0, 662, 574, 659, 0, + 679, 676, 1115, 1208, 0, 0, 0, 0, 1334, 0, + 0, 0, 1125, 1127, 1128, 1011, 1138, 908, 0, 1675, + 1676, 1677, 1075, 1678, 1679, 1681, 1682, 1683, 865, 1684, + 1136, 1686, 1688, 1689, 1691, 1692, 1693, 1695, 1696, 0, + 1137, 1699, 1538, 1704, 1705, 1707, 1710, 1711, 1135, 1716, + 0, 0, 0, 1103, 1030, 0, 0, 0, 907, 0, + 903, 0, 0, 720, 721, 742, 743, 722, 748, 749, + 723, 0, 1097, 800, 1085, 955, 911, 920, 899, 986, + 897, 0, 902, 892, 1093, 508, 1091, 0, 893, 1124, + 1085, 1076, 508, 1089, 1267, 1265, 1271, 1266, 0, 0, + 0, 0, 0, 1115, 1310, 1309, 1301, 1299, 1300, 1298, + 1297, 1304, 0, 1306, 1214, 1025, 1027, 0, 1076, 503, + 0, 0, 0, 478, 477, 3, 0, 0, 0, 0, + 520, 521, 0, 0, 0, 0, 0, 0, 0, 0, + 618, 548, 549, 551, 615, 619, 627, 0, 484, 0, + 1159, 1340, 0, 0, 0, 121, 121, 0, 0, 0, + 0, 0, 97, 46, 90, 0, 0, 0, 0, 206, + 219, 0, 0, 0, 0, 0, 216, 0, 0, 199, + 48, 193, 195, 0, 121, 0, 44, 0, 0, 0, + 50, 0, 450, 1140, 0, 1728, 1729, 1730, 1681, 1731, + 1732, 937, 924, 933, 938, 934, 0, 1738, 1739, 1687, + 1741, 1742, 1743, 1744, 1745, 1746, 1747, 1748, 1694, 1750, + 1751, 1752, 1753, 1754, 1755, 935, 1757, 1708, 1759, 1714, + 936, 0, 1761, 0, 912, 1033, 532, 1031, 1160, 0, + 1141, 1147, 1081, 0, 1161, 1916, 1917, 1918, 1919, 1920, + 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1929, 1930, + 1931, 1932, 1933, 1934, 1935, 1936, 1937, 1938, 1939, 1940, + 1941, 1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949, 1950, + 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, + 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, + 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, + 1981, 1982, 1866, 1983, 1984, 1985, 1986, 1987, 1078, 1121, + 1163, 1162, 1164, 1084, 0, 0, 448, 0, 0, 0, + 0, 0, 1175, 0, 177, 0, 1472, 187, 1472, 334, + 0, 1472, 334, 1472, 0, 1188, 1191, 0, 0, 0, + 1155, 1329, 401, 397, 395, 394, 396, 758, 745, 753, + 752, 1030, 735, 734, 733, 0, 732, 0, 0, 759, + 759, 757, 736, 712, 0, 0, 0, 763, 0, 761, + 0, 406, 407, 0, 378, 0, 705, 701, 0, 772, + 773, 774, 775, 782, 783, 780, 781, 776, 777, 770, + 771, 778, 779, 768, 769, 0, 784, 785, 786, 787, + 788, 789, 790, 791, 718, 724, 0, 373, 0, 0, + 375, 0, 0, 0, 369, 134, 0, 200, 1258, 1259, + 1257, 0, 0, 1216, 203, 220, 1252, 1261, 1251, 1260, + 1215, 1210, 0, 1206, 439, 0, 0, 0, 0, 0, + 0, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, + 0, 0, 1049, 646, 644, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 868, 897, 0, 0, 0, 1025, + 1059, 0, 0, 0, 0, 0, 0, 1025, 1065, 0, + 0, 649, 657, 567, 573, 645, 0, 643, 0, 1090, + 638, 0, 689, 0, 671, 667, 0, 668, 0, 0, + 0, 669, 0, 641, 0, 657, 642, 0, 686, 1277, + 1276, 1285, 174, 0, 1036, 0, 134, 1335, 1347, 0, + 1030, 900, 1074, 0, 0, 905, 824, 0, 0, 825, + 804, 805, 0, 1102, 1111, 1025, 1029, 0, 903, 1025, + 0, 894, 1167, 896, 989, 991, 0, 0, 904, 0, + 1131, 0, 799, 799, 1096, 1011, 0, 1004, 0, 0, + 1008, 1009, 1010, 0, 0, 0, 1088, 0, 1019, 1021, + 0, 0, 840, 1017, 0, 843, 0, 0, 0, 0, + 1005, 1006, 1007, 998, 999, 1000, 1001, 1002, 1003, 1015, + 997, 821, 0, 895, 0, 958, 0, 820, 1094, 636, + 0, 1129, 1126, 0, 1077, 636, 1279, 1283, 1284, 1282, + 0, 1278, 1270, 1269, 1274, 1272, 1275, 1273, 1349, 0, + 1311, 1295, 0, 1292, 1028, 631, 505, 1118, 0, 0, + 1316, 139, 138, 0, 0, 500, 499, 542, 542, 533, + 536, 542, 0, 498, 0, 590, 591, 0, 0, 0, + 0, 624, 622, 1125, 1138, 578, 552, 577, 0, 0, + 556, 0, 582, 800, 617, 482, 546, 547, 550, 481, + 0, 620, 0, 630, 618, 551, 0, 1318, 1341, 0, + 0, 0, 0, 0, 1472, 0, 0, 81, 62, 286, + 700, 120, 0, 0, 0, 0, 0, 0, 0, 89, + 86, 87, 88, 0, 0, 0, 0, 204, 205, 218, + 0, 209, 210, 207, 211, 212, 0, 0, 197, 198, + 0, 0, 0, 0, 196, 0, 0, 0, 0, 0, + 0, 0, 0, 1325, 1319, 532, 532, 532, 918, 0, + 530, 531, 0, 0, 1079, 1082, 438, 342, 0, 332, + 0, 0, 0, 180, 179, 0, 0, 0, 0, 0, + 369, 1181, 1179, 1177, 1180, 1182, 1444, 168, 0, 0, + 184, 186, 0, 331, 305, 0, 0, 1193, 0, 0, + 0, 1472, 1190, 321, 0, 1322, 405, 1156, 0, 0, + 0, 0, 408, 0, 756, 755, 706, 702, 0, 0, + 0, 0, 0, 0, 413, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 408, 408, 1117, 0, 408, 191, + 1212, 1254, 201, 221, 202, 222, 473, 0, 445, 453, + 458, 436, 0, 436, 0, 455, 459, 436, 454, 0, + 436, 449, 450, 0, 951, 0, 926, 928, 941, 0, + 930, 932, 0, 678, 0, 0, 942, 870, 871, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 867, 866, 921, 662, 0, 665, - 0, 0, 1035, 1036, 0, 922, 0, 0, 1042, 0, - 0, 0, 927, 0, 629, 0, 0, 543, 550, 0, - 553, 547, 0, 489, 470, 1426, 1464, 0, 500, 500, - 500, 488, 498, 0, 576, 631, 0, 0, 633, 635, - 0, 0, 0, 670, 0, 0, 0, 1098, 0, 168, - 0, 1146, 0, 1149, 1150, 1148, 1145, 1151, 0, 1064, - 0, 0, 1051, 1047, 1081, 0, 974, 982, 986, 987, - 988, 983, 984, 985, 976, 977, 978, 979, 980, 981, - 1001, 0, 0, 963, 0, 0, 1079, 0, 1076, 0, - 880, 1063, 0, 970, 879, 0, 0, 0, 1111, 1112, - 781, 792, 824, 825, 796, 797, 798, 802, 1144, 1143, - 1073, 0, 1065, 0, 0, 782, 806, 811, 0, 1044, - 841, 0, 829, 0, 819, 0, 827, 831, 807, 822, - 0, 803, 0, 1066, 998, 1000, 0, 996, 0, 793, - 794, 795, 786, 787, 788, 789, 790, 791, 799, 973, - 971, 972, 0, 0, 0, 938, 0, 0, 826, 1070, - 0, 669, 513, 1081, 669, 0, 779, 1286, 1137, 1279, - 1267, 1268, 1004, 1097, 1136, 130, 0, 1288, 0, 0, - 0, 136, 119, 0, 0, 152, 154, 617, 0, 1063, - 521, 522, 526, 526, 0, 0, 526, 504, 478, 1666, - 1553, 0, 0, 0, 0, 564, 606, 0, 597, 561, - 562, 0, 560, 1103, 565, 1102, 566, 569, 570, 538, - 607, 1090, 609, 0, 602, 467, 466, 613, 0, 43, - 0, 1434, 60, 0, 0, 0, 0, 0, 0, 220, - 0, 320, 220, 98, 1434, 391, 1434, 391, 1333, 1401, - 1569, 0, 56, 89, 0, 294, 110, 0, 279, 323, - 79, 94, 103, 0, 0, 45, 179, 193, 198, 106, - 202, 199, 1175, 200, 117, 0, 41, 0, 104, 0, - 1173, 0, 0, 47, 108, 1177, 511, 511, 511, 0, - 1010, 0, 0, 0, 1012, 1013, 1059, 0, 420, 0, - 317, 0, 430, 410, 411, 421, 0, 318, 0, 318, - 0, 1155, 0, 0, 1135, 163, 159, 0, 0, 0, - 0, 308, 306, 339, 0, 313, 307, 316, 0, 0, - 265, 0, 1327, 0, 0, 0, 405, 0, 0, 0, - 0, 0, 705, 718, 363, 692, 0, 746, 745, 747, - 747, 692, 0, 675, 692, 0, 690, 0, 730, 699, - 772, 773, 774, 775, 776, 777, 778, 356, 358, 0, - 360, 423, 0, 426, 0, 425, 429, 424, 418, 0, - 449, 0, 0, 0, 0, 0, 0, 0, 901, 1016, - 0, 1030, 1029, 849, 858, 862, 863, 864, 1031, 0, - 0, 0, 859, 860, 861, 852, 853, 854, 855, 856, - 857, 865, 667, 0, 0, 661, 1040, 1039, 1033, 1034, - 0, 924, 925, 926, 1041, 0, 0, 541, 539, 542, - 544, 540, 0, 0, 638, 669, 500, 500, 500, 500, - 497, 0, 0, 0, 668, 0, 593, 654, 0, 634, - 632, 643, 0, 674, 0, 645, 1260, 1015, 506, 883, - 0, 0, 1048, 0, 1089, 847, 990, 0, 962, 0, - 0, 0, 1088, 0, 877, 1004, 968, 966, 889, 779, - 0, 0, 0, 0, 0, 0, 0, 830, 821, 0, - 828, 832, 0, 0, 0, 815, 0, 0, 813, 842, - 809, 0, 0, 843, 0, 0, 937, 946, 620, 616, - 576, 511, 1089, 576, 0, 1254, 1270, 0, 1289, 0, - 141, 123, 143, 142, 0, 150, 0, 1063, 0, 141, - 125, 0, 144, 155, 1288, 0, 158, 0, 515, 516, - 518, 0, 991, 526, 520, 568, 567, 0, 536, 604, - 534, 0, 610, 0, 0, 0, 269, 0, 0, 0, - 220, 0, 328, 0, 335, 0, 0, 320, 301, 78, - 0, 0, 0, 52, 97, 70, 62, 48, 76, 0, - 0, 81, 0, 74, 91, 92, 90, 95, 0, 255, - 230, 266, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 513, 509, - 510, 891, 1058, 452, 453, 184, 451, 327, 0, 0, - 315, 0, 1170, 0, 1153, 353, 0, 0, 162, 164, - 0, 172, 318, 0, 293, 289, 314, 287, 286, 288, - 0, 1328, 177, 0, 1322, 1169, 0, 0, 406, 0, - 400, 0, 1164, 724, 688, 0, 742, 740, 689, 0, - 687, 683, 691, 391, 455, 0, 414, 450, 439, 444, - 0, 448, 446, 445, 440, 443, 917, 928, 1028, 0, - 0, 0, 0, 660, 663, 0, 923, 918, 636, 0, - 0, 576, 0, 0, 0, 0, 491, 490, 496, 0, - 0, 940, 0, 671, 0, 672, 644, 0, 1050, 1046, - 0, 1002, 1078, 1003, 1083, 1085, 0, 0, 0, 965, - 1110, 783, 0, 0, 812, 1045, 833, 0, 0, 0, - 808, 990, 0, 0, 0, 0, 0, 817, 0, 0, - 0, 0, 0, 897, 621, 593, 0, 1077, 593, 0, - 487, 1287, 0, 1282, 0, 0, 0, 131, 128, 118, - 0, 0, 153, 141, 132, 524, 525, 0, 519, 535, - 1091, 111, 220, 0, 0, 59, 0, 337, 281, 329, - 312, 296, 0, 0, 0, 221, 0, 354, 0, 0, - 302, 0, 0, 0, 0, 282, 0, 0, 241, 0, - 0, 312, 0, 319, 237, 238, 0, 51, 71, 0, - 67, 0, 96, 0, 0, 0, 0, 0, 54, 66, - 0, 49, 0, 391, 391, 57, 280, 1129, 1722, 1723, - 1724, 1725, 1726, 1727, 1728, 1729, 1730, 1731, 1732, 1733, - 1734, 1851, 1735, 1736, 1737, 1738, 1739, 1740, 1741, 1742, - 1860, 1743, 227, 1744, 1500, 1745, 1746, 1747, 1748, 0, - 1749, 678, 1750, 1751, 1937, 1752, 1753, 976, 977, 225, - 322, 222, 330, 224, 226, 0, 1130, 223, 325, 107, - 1176, 0, 105, 0, 1174, 114, 112, 109, 1178, 894, - 895, 892, 511, 433, 413, 0, 0, 1327, 0, 0, - 0, 1434, 0, 160, 0, 1170, 170, 315, 0, 345, - 265, 340, 0, 1327, 1325, 0, 1321, 0, 397, 0, - 0, 0, 684, 676, 361, 427, 0, 447, 868, 0, - 0, 0, 0, 551, 0, 557, 593, 495, 494, 493, - 492, 574, 1376, 1649, 1552, 575, 0, 579, 573, 577, - 582, 584, 583, 585, 581, 592, 0, 595, 653, 673, - 1049, 846, 1086, 1087, 1082, 0, 780, 839, 837, 834, - 0, 835, 816, 0, 0, 814, 810, 0, 844, 932, - 0, 935, 949, 944, 945, 940, 891, 940, 1255, 140, - 120, 0, 121, 151, 0, 0, 0, 0, 145, 407, - 0, 333, 61, 0, 312, 0, 220, 298, 297, 300, - 295, 299, 0, 355, 0, 0, 239, 0, 246, 284, - 285, 283, 240, 312, 318, 242, 0, 0, 0, 63, - 53, 50, 55, 64, 0, 0, 65, 68, 674, 80, - 73, 1860, 1868, 0, 0, 0, 0, 0, 0, 409, - 416, 184, 0, 0, 289, 1324, 0, 0, 402, 0, - 0, 315, 165, 0, 0, 0, 1327, 0, 0, 217, - 0, 262, 0, 174, 1326, 0, 1314, 0, 0, 1162, - 1163, 0, 415, 869, 0, 870, 664, 0, 0, 549, - 940, 0, 0, 0, 586, 580, 939, 941, 0, 0, - 546, 1084, 930, 0, 836, 840, 838, 818, 934, 951, - 948, 595, 1108, 595, 0, 0, 0, 0, 156, 0, - 147, 147, 0, 133, 992, 0, 220, 0, 311, 334, - 251, 229, 0, 0, 0, 236, 243, 344, 245, 0, - 72, 88, 0, 0, 324, 115, 113, 893, 433, 0, - 1170, 265, 1321, 399, 0, 0, 0, 289, 177, 1323, - 278, 271, 272, 273, 274, 275, 276, 277, 292, 291, - 263, 264, 0, 0, 0, 0, 401, 1164, 0, 871, - 552, 0, 595, 0, 0, 0, 578, 0, 0, 594, - 0, 474, 0, 0, 513, 546, 546, 0, 127, 0, - 669, 0, 0, 149, 149, 135, 0, 318, 336, 0, - 303, 310, 249, 248, 250, 254, 0, 252, 0, 268, - 0, 261, 229, 0, 75, 0, 331, 408, 412, 0, - 219, 1315, 315, 0, 1321, 265, 1327, 0, 1318, 0, - 398, 0, 1170, 0, 546, 588, 0, 587, 942, 943, - 548, 931, 0, 954, 473, 472, 122, 147, 126, 157, - 146, 523, 148, 523, 0, 344, 290, 0, 0, 0, - 251, 0, 244, 341, 342, 343, 0, 257, 247, 258, - 69, 87, 332, 0, 315, 1316, 218, 175, 1319, 1320, - 0, 669, 556, 475, 589, 545, 950, 0, 0, 0, - 149, 526, 526, 669, 261, 304, 309, 228, 253, 267, - 0, 0, 0, 259, 0, 260, 1321, 0, 1160, 1635, - 1377, 1605, 0, 952, 955, 953, 947, 523, 138, 137, - 134, 220, 233, 0, 232, 0, 321, 256, 1317, 1170, - 0, 959, 958, 957, 961, 960, 526, 338, 231, 235, - 234, 669, 0, 139, 1161, 956 + 0, 0, 0, 0, 0, 0, 887, 886, 943, 682, + 0, 685, 0, 0, 1057, 1058, 0, 944, 0, 0, + 1064, 0, 0, 0, 949, 0, 648, 0, 0, 562, + 569, 0, 572, 566, 0, 508, 489, 1464, 1502, 0, + 519, 519, 519, 507, 517, 0, 595, 650, 0, 0, + 652, 654, 0, 655, 0, 0, 690, 0, 0, 0, + 1120, 0, 175, 0, 1169, 0, 1172, 1173, 1171, 1168, + 1174, 0, 0, 0, 1073, 1069, 1103, 0, 996, 1004, + 1008, 1009, 1010, 1005, 1006, 1007, 998, 999, 1000, 1001, + 1002, 1003, 1023, 0, 0, 985, 0, 0, 1101, 0, + 1098, 0, 898, 909, 0, 992, 910, 0, 0, 0, + 1133, 1134, 801, 812, 844, 845, 816, 817, 818, 822, + 1166, 1165, 1095, 0, 1087, 0, 0, 802, 826, 831, + 0, 1066, 861, 0, 849, 0, 839, 0, 847, 851, + 827, 842, 0, 823, 0, 1088, 1020, 1022, 0, 1018, + 0, 813, 814, 815, 806, 807, 808, 809, 810, 811, + 819, 995, 993, 994, 0, 1086, 0, 0, 960, 0, + 0, 846, 1092, 0, 689, 532, 1103, 689, 0, 799, + 1312, 1159, 1305, 1293, 1294, 1026, 1119, 1158, 134, 0, + 1314, 0, 128, 0, 159, 161, 636, 0, 1085, 540, + 541, 545, 545, 0, 0, 545, 523, 497, 1705, 1591, + 0, 0, 0, 0, 583, 625, 0, 616, 580, 581, + 0, 579, 1125, 584, 1124, 585, 588, 589, 557, 626, + 1112, 628, 0, 621, 486, 485, 632, 0, 47, 0, + 1472, 64, 0, 0, 0, 0, 0, 0, 236, 0, + 336, 236, 102, 1472, 408, 1472, 408, 1371, 1439, 1607, + 0, 60, 93, 0, 310, 114, 0, 295, 339, 83, + 98, 107, 0, 0, 49, 194, 208, 213, 110, 217, + 214, 1198, 215, 121, 0, 45, 0, 108, 0, 1196, + 0, 0, 51, 112, 1200, 530, 530, 530, 0, 1032, + 0, 0, 0, 1034, 1035, 1081, 0, 437, 0, 333, + 0, 447, 427, 428, 438, 178, 0, 0, 334, 0, + 334, 0, 1178, 0, 0, 170, 166, 0, 0, 0, + 0, 324, 322, 355, 0, 329, 323, 332, 0, 0, + 281, 0, 1365, 0, 0, 0, 0, 422, 0, 0, + 0, 0, 1157, 0, 725, 738, 379, 712, 0, 766, + 765, 767, 767, 712, 0, 695, 712, 0, 710, 0, + 750, 719, 792, 793, 794, 795, 796, 797, 798, 372, + 374, 0, 376, 440, 0, 443, 0, 442, 446, 441, + 435, 0, 468, 0, 0, 0, 0, 0, 0, 0, + 1207, 0, 923, 1038, 0, 1052, 1051, 869, 878, 882, + 883, 884, 1053, 0, 0, 0, 879, 880, 881, 872, + 873, 874, 875, 876, 877, 885, 687, 0, 0, 681, + 1062, 1061, 1055, 1056, 0, 946, 947, 948, 1063, 0, + 0, 560, 558, 561, 563, 559, 0, 0, 658, 689, + 519, 519, 519, 519, 516, 0, 0, 0, 688, 0, + 612, 674, 0, 653, 651, 663, 0, 694, 0, 665, + 1286, 1037, 525, 901, 0, 0, 1070, 0, 1111, 867, + 1012, 0, 984, 0, 0, 0, 1110, 0, 1026, 990, + 988, 906, 799, 0, 0, 0, 0, 0, 0, 0, + 850, 841, 0, 848, 852, 0, 0, 0, 835, 0, + 0, 833, 862, 829, 0, 0, 863, 0, 0, 959, + 968, 639, 635, 595, 530, 1111, 595, 0, 1280, 1296, + 0, 1315, 0, 148, 0, 0, 0, 143, 123, 0, + 0, 151, 162, 1314, 0, 165, 0, 534, 535, 537, + 0, 1013, 545, 539, 587, 586, 0, 555, 623, 553, + 0, 629, 0, 0, 0, 285, 0, 0, 0, 236, + 0, 344, 0, 351, 0, 0, 336, 317, 82, 0, + 0, 0, 56, 101, 74, 66, 52, 80, 0, 0, + 85, 0, 78, 95, 96, 94, 99, 0, 271, 246, + 282, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 532, 528, 529, + 913, 1080, 471, 472, 199, 470, 343, 0, 0, 182, + 0, 331, 0, 1193, 0, 1176, 369, 0, 0, 169, + 171, 0, 187, 334, 0, 309, 305, 330, 303, 302, + 304, 0, 1366, 192, 0, 1360, 334, 1192, 0, 0, + 423, 0, 417, 0, 1187, 744, 708, 0, 762, 760, + 709, 0, 707, 703, 711, 408, 474, 0, 431, 469, + 456, 461, 0, 467, 463, 462, 457, 465, 464, 460, + 939, 950, 1050, 0, 0, 0, 0, 680, 683, 0, + 945, 940, 656, 0, 0, 595, 0, 0, 0, 0, + 510, 509, 515, 0, 0, 962, 0, 691, 0, 692, + 664, 0, 1072, 1068, 0, 1024, 1100, 1025, 1105, 1107, + 0, 0, 0, 987, 1132, 803, 0, 0, 832, 1067, + 853, 0, 0, 0, 828, 1012, 0, 0, 0, 0, + 0, 837, 0, 0, 0, 0, 0, 919, 640, 612, + 0, 1099, 612, 0, 506, 1313, 0, 1308, 127, 150, + 149, 0, 157, 0, 1085, 0, 148, 129, 0, 0, + 160, 148, 136, 543, 544, 0, 538, 554, 1113, 115, + 236, 0, 0, 63, 0, 353, 297, 345, 328, 312, + 0, 0, 0, 237, 0, 370, 0, 0, 318, 0, + 0, 0, 0, 298, 0, 0, 257, 0, 0, 328, + 0, 335, 253, 254, 0, 55, 75, 0, 71, 0, + 100, 0, 0, 0, 0, 0, 58, 70, 0, 53, + 0, 408, 408, 61, 296, 1151, 1762, 1763, 1764, 1765, + 1766, 1767, 1768, 1769, 1770, 1771, 1772, 1773, 1774, 1893, + 1775, 1776, 1777, 1778, 1779, 1780, 1781, 1782, 1902, 1783, + 243, 1784, 1538, 1785, 1786, 1787, 1788, 1789, 0, 1790, + 698, 1791, 1792, 1980, 1793, 1794, 998, 999, 241, 338, + 238, 346, 240, 242, 0, 1152, 239, 341, 111, 1199, + 0, 109, 0, 1197, 118, 116, 113, 1201, 916, 917, + 914, 530, 450, 430, 181, 0, 0, 1365, 0, 0, + 0, 1472, 0, 167, 0, 1193, 185, 331, 0, 361, + 281, 356, 0, 1365, 1363, 0, 1193, 1359, 0, 414, + 0, 0, 0, 704, 696, 377, 444, 0, 466, 888, + 0, 0, 0, 0, 570, 0, 576, 612, 514, 513, + 512, 511, 593, 1414, 1688, 1590, 594, 0, 598, 592, + 596, 601, 603, 602, 604, 600, 611, 0, 614, 673, + 693, 1071, 866, 1108, 1109, 1104, 0, 800, 859, 857, + 854, 0, 855, 836, 0, 0, 834, 830, 0, 864, + 954, 0, 957, 971, 966, 967, 962, 913, 962, 1281, + 147, 0, 0, 0, 135, 132, 122, 0, 152, 424, + 0, 349, 65, 0, 328, 0, 236, 314, 313, 316, + 311, 315, 0, 371, 0, 0, 255, 0, 262, 300, + 301, 299, 256, 328, 334, 258, 0, 0, 0, 67, + 57, 54, 59, 68, 0, 0, 69, 72, 694, 84, + 77, 1902, 1911, 0, 0, 0, 0, 0, 0, 426, + 433, 199, 0, 0, 305, 1362, 0, 0, 419, 0, + 0, 331, 172, 0, 0, 0, 1365, 0, 0, 233, + 0, 278, 0, 189, 1364, 0, 0, 1351, 0, 0, + 1185, 1186, 0, 432, 889, 0, 890, 684, 0, 0, + 568, 962, 0, 0, 0, 605, 599, 961, 963, 0, + 0, 565, 1106, 952, 0, 856, 860, 858, 838, 956, + 973, 970, 614, 1130, 614, 0, 124, 0, 125, 158, + 0, 0, 0, 137, 1014, 0, 236, 0, 327, 350, + 267, 245, 0, 0, 0, 252, 259, 360, 261, 0, + 76, 92, 0, 0, 340, 119, 117, 915, 450, 0, + 1193, 281, 1359, 416, 0, 0, 0, 305, 192, 1361, + 294, 287, 288, 289, 290, 291, 292, 293, 308, 307, + 279, 280, 0, 0, 0, 0, 0, 418, 1187, 0, + 163, 0, 154, 154, 891, 571, 0, 614, 0, 0, + 0, 597, 0, 0, 613, 0, 493, 0, 0, 532, + 565, 565, 0, 0, 0, 0, 334, 352, 0, 319, + 326, 265, 264, 266, 270, 0, 268, 0, 284, 0, + 277, 245, 0, 79, 0, 347, 425, 429, 0, 235, + 1353, 331, 0, 1359, 281, 1365, 1359, 0, 1356, 0, + 415, 0, 0, 1193, 0, 0, 156, 156, 0, 565, + 607, 0, 606, 964, 965, 567, 953, 0, 976, 492, + 491, 0, 131, 689, 142, 0, 360, 306, 0, 0, + 0, 267, 0, 260, 357, 358, 359, 0, 273, 263, + 274, 73, 91, 348, 0, 331, 1354, 234, 190, 1352, + 1357, 1358, 0, 154, 689, 164, 153, 542, 155, 542, + 575, 494, 608, 564, 972, 0, 0, 0, 126, 130, + 0, 277, 320, 325, 244, 269, 283, 0, 0, 0, + 275, 0, 276, 1359, 0, 156, 1183, 545, 545, 1674, + 1415, 1643, 0, 974, 977, 975, 969, 689, 236, 249, + 0, 248, 0, 337, 272, 1355, 1193, 542, 145, 144, + 0, 981, 980, 979, 983, 982, 141, 354, 247, 251, + 250, 689, 545, 0, 1184, 146, 978 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 39, 40, 41, 548, 2405, 2406, 2407, 2081, 1123, - 3054, 2082, 1124, 1125, 2409, 549, 550, 1650, 551, 2011, - 1589, 2826, 46, 2355, 2015, 2359, 2948, 2583, 2354, 2361, - 3033, 3091, 2356, 2016, 2017, 2949, 2018, 552, 2457, 2458, - 553, 554, 1724, 555, 821, 556, 1725, 1677, 1467, 1143, - 1667, 1384, 557, 88, 558, 2394, 2700, 3047, 2419, 3166, - 2633, 2634, 3044, 3045, 2397, 2083, 3107, 3108, 2471, 1659, - 3102, 2151, 2998, 2087, 2069, 2635, 2160, 2958, 2739, 2084, - 2615, 2152, 3039, 1735, 2153, 3040, 2836, 2154, 1702, 1728, - 2398, 3109, 2088, 1703, 2393, 2701, 1646, 2155, 3051, 2156, - 506, 2619, 559, 541, 542, 813, 1334, 543, 794, 560, - 724, 1733, 561, 562, 2135, 2881, 2495, 2882, 2209, 2129, - 1393, 2206, 1776, 1706, 1394, 496, 1790, 2496, 2445, 1777, - 563, 1023, 60, 61, 949, 62, 653, 665, 666, 1451, - 1861, 659, 1093, 1601, 641, 642, 2123, 680, 1696, 1596, - 1597, 2022, 2368, 1625, 1626, 1102, 1103, 1848, 3021, 1849, - 1850, 1443, 1444, 2919, 1613, 1617, 1618, 2044, 2034, 1604, - 2276, 2777, 2778, 2779, 2780, 2781, 2782, 2783, 1024, 2531, - 2930, 1621, 1622, 1105, 1106, 1107, 1630, 2054, 64, 65, - 1991, 2338, 2339, 613, 614, 943, 944, 961, 957, 1454, - 1868, 615, 616, 1827, 1828, 2245, 964, 1864, 1872, 1873, - 2535, 1751, 795, 2070, 1472, 1337, 797, 1025, 798, 1312, - 1026, 1316, 800, 1027, 1028, 1029, 803, 1030, 1031, 1032, - 806, 1308, 1033, 1034, 1327, 1356, 1357, 1358, 1359, 1360, - 1361, 1362, 1363, 1364, 1077, 1422, 1036, 1037, 1038, 618, - 1039, 1040, 1552, 1985, 2337, 2787, 2926, 2927, 2573, 2813, - 2939, 3024, 3129, 3153, 3154, 1041, 1042, 1502, 1503, 1504, - 1982, 1547, 1548, 1043, 2703, 1550, 1911, 1078, 1437, 1496, - 1194, 1195, 1473, 1409, 1410, 1419, 1803, 1426, 1430, 1832, - 1833, 1438, 1950, 1044, 1892, 1893, 2293, 1482, 1045, 705, - 1201, 706, 1478, 1944, 1054, 1046, 1055, 1048, 1492, 1493, - 2302, 2545, 2546, 1918, 2050, 620, 1585, 1852, 817, 1276, - 1049, 1050, 1051, 1052, 1080, 622, 1196, 489, 809, 3092, - 1289, 1084, 1197, 2085, 1940, 564, 971, 1886, 565, 1287, - 1715, 566, 2910, 2751, 1301, 1737, 2164, 507, 567, 568, - 71, 72, 73, 687, 1387, 569, 1388, 1389, 909, 74, - 1468, 911, 912, 571, 648, 649, 1469, 1570, 1470, 572, - 627, 573, 1073, 662, 1074, 1076, 574, 1067, 2350, 2007, - 79, 575, 635, 636, 576, 82, 650, 655, 577, 578, - 2906, 579, 2474, 1296, 518, 491, 492, 811, 1279, 1199, - 1280 + -1, 42, 43, 44, 571, 2464, 2465, 2466, 2140, 1162, + 3123, 2141, 1163, 1164, 2468, 572, 573, 1703, 574, 2417, + 2071, 3022, 49, 2652, 2074, 1128, 2656, 3080, 2647, 2651, + 2420, 3146, 3197, 2653, 2075, 2076, 3081, 2077, 575, 2518, + 2519, 576, 52, 526, 577, 1780, 578, 852, 579, 1781, + 1730, 1519, 1182, 1720, 1434, 580, 95, 57, 581, 2453, + 2769, 3116, 2478, 3243, 2701, 2702, 3113, 3114, 2456, 2142, + 3178, 3179, 2532, 1712, 3173, 2211, 3068, 2146, 2128, 2703, + 2220, 3028, 2809, 2143, 2683, 2212, 3108, 1792, 2213, 3109, + 2906, 2214, 1757, 1784, 2457, 3180, 2147, 1758, 2452, 2770, + 1699, 2215, 3120, 2216, 527, 2687, 582, 563, 564, 755, + 1384, 565, 826, 583, 750, 1790, 584, 585, 2194, 2951, + 2557, 2952, 2271, 2188, 1443, 2268, 1836, 1761, 1444, 514, + 1851, 2558, 2504, 1837, 586, 1060, 65, 66, 984, 67, + 675, 688, 689, 1502, 1923, 681, 1132, 1654, 663, 664, + 2182, 703, 1751, 1649, 1650, 2081, 2427, 1678, 1679, 1141, + 1142, 1910, 3096, 1911, 1912, 1494, 1495, 2990, 1666, 1670, + 1671, 2103, 2093, 1657, 2340, 2848, 2849, 2850, 2851, 2852, + 2853, 2854, 1061, 2595, 3001, 1674, 1675, 1144, 1145, 1146, + 1683, 2113, 69, 70, 2054, 2401, 2402, 636, 637, 978, + 979, 997, 993, 1505, 1930, 638, 639, 1889, 1890, 2309, + 1000, 1926, 1935, 1936, 2599, 1812, 827, 2129, 1524, 1387, + 829, 1062, 830, 1362, 1063, 1366, 832, 1064, 1065, 1066, + 835, 1067, 1068, 1069, 838, 1358, 1070, 1071, 1377, 1406, + 1407, 1408, 1409, 1410, 1411, 1412, 1413, 1414, 1115, 1473, + 1073, 1074, 1075, 1076, 641, 1077, 1078, 1605, 2048, 2400, + 2858, 2997, 2998, 2637, 2884, 3010, 3099, 3207, 3233, 3234, + 1079, 1080, 1554, 1555, 1556, 2044, 1599, 1600, 1081, 2772, + 1602, 1973, 1116, 1488, 1547, 1236, 1237, 1525, 1460, 1461, + 1470, 1865, 1477, 1481, 1894, 1895, 1489, 2012, 1082, 1954, + 1955, 2357, 1533, 1083, 729, 1243, 730, 1603, 2006, 1092, + 1084, 1093, 1086, 1543, 1544, 2366, 2609, 2610, 1980, 2109, + 643, 1637, 1914, 848, 1318, 1087, 1088, 1089, 1090, 1118, + 645, 1238, 500, 841, 757, 1350, 1122, 1239, 2144, 2002, + 1553, 587, 1007, 1949, 588, 1332, 1773, 589, 2981, 2822, + 1346, 1794, 2225, 529, 590, 591, 509, 76, 77, 78, + 710, 1437, 592, 1438, 1439, 942, 79, 1520, 944, 945, + 594, 670, 671, 1521, 1622, 1522, 595, 649, 596, 1111, + 685, 1112, 1114, 597, 1105, 2413, 2070, 84, 85, 86, + 102, 1192, 538, 539, 598, 657, 658, 599, 89, 672, + 677, 600, 601, 2977, 602, 2535, 1340, 510, 502, 503, + 843, 1321, 1241, 1322 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -2632 +#define YYPACT_NINF -2784 static const int yypact[] = { - 6348, -50, 849, -2632, -2632, -50, 38804, -2632, -50, 156, - 2783, 41189, -2632, 3816, -50, 45464, 58856, 296, 268, 23934, - 458, 45944, 45944, 53144, 45464, 46424, -50, 375, 53624, -2632, - -50, 26334, 41669, 307, 30, 299, 46904, 45464, 1806, 841, - 357, -2632, -2632, -2632, -2632, -2632, 123, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, 144, - -2632, 204, 149, 153, 110, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, 431, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, 25854, -2632, -2632, -2632, -2632, -2632, -2632, 47384, - 45464, 47864, 42149, 48344, -2632, 151, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, 164, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, 186, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, 196, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, 400, -75, -2632, - 201, -2632, -2632, -2632, -2632, 1806, 45464, 612, 706, 630, - 54104, -2632, -2632, 53144, -2632, -2632, 1355, 757, -2632, -2632, - -2632, -2632, -2632, 42629, -2632, -2632, -2632, -2632, -2632, 739, - -2632, -2632, 618, -2632, 133, -2632, -2632, 641, 626, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, 719, -2632, 43109, - -2632, 54584, 48824, 49304, -2632, 589, 58857, 24414, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - 431, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - 1103, -2632, 45944, 643, 650, 951, 206, 211, 213, 216, - 662, 666, 227, 688, 24894, 693, 698, 701, 26815, 748, - 752, 1053, 229, 767, 772, 779, 786, 231, 299, 22971, - 49784, 49784, -37, 1382, -2632, 49784, 50264, -2632, 743, -2632, - 746, -75, -2632, 1103, -2632, -2632, -2632, -2632, -2632, 489, - 793, -2632, 835, 1082, -2632, -2632, -2632, 819, -2632, -2632, - 1054, 10917, 10917, 55064, 55064, 1103, 55064, 875, -2632, -2632, - 13, -2632, -2632, 153, -2632, 868, -2632, -75, -2632, 41669, - -2632, 272, 1211, 15957, 45464, 889, -2632, 911, 889, 900, - 906, -2632, 6348, 1246, 1220, 41669, 418, 418, 1396, 418, - 700, 910, -2632, 1052, -2632, 944, -2632, 45464, -2632, 988, - 1243, -2632, 868, 1323, 907, 1144, 1347, 2810, 1365, 1181, - 1389, 1329, 7893, 15957, 36404, -2632, -75, 1030, 1057, -2632, - -2632, -2632, -2632, 817, 1275, -2632, 1063, 1539, -2632, -2632, - 1128, 50744, 51224, 45464, 51704, 1502, -2632, -2632, -2632, -2632, - 1130, -2632, -2632, -2632, 207, -2632, -2632, -2632, -2632, 1149, - -2632, 1149, 1149, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, 1107, 1107, 1286, 1113, -2632, -2632, -2632, 1467, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - 1140, 873, -2632, 1149, -2632, 1107, -2632, -2632, -2632, -2632, - -2632, -2632, 57929, -2632, -2632, -2632, -2632, 460, 620, -2632, - 1163, -2632, -2632, -2632, 90, 1169, -2632, 1628, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, 1171, -2632, 3848, 1107, - -2632, -2632, 1520, 214, -2632, 1522, 230, -2632, 1535, 1403, - 15957, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, 299, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, 599, - -2632, -2632, 33910, -2632, -2632, 58857, 1194, -2632, 15957, 15957, - 1197, 1692, 1692, 2378, 49784, 50264, 1692, 1692, 15957, 45464, - -2632, 15957, 19989, 1205, 15957, 15957, 8901, 15957, 22491, 49784, - 1382, 1209, 45464, -2632, 1314, 1224, 1314, 375, 23934, 1507, - 1505, 1440, -2632, 23934, 1440, 1042, 1440, 1508, 1314, 27295, - -2632, 1314, 1235, 1447, -2632, -2632, 655, -2632, 33910, 16461, - 43574, 1701, -2632, 1509, 53144, 1244, -2632, -2632, -2632, -2632, - -2632, -2632, 802, 1743, 146, 1745, 15957, 146, 146, 1252, - 232, 232, -2632, 1253, -2632, 233, 1254, 1261, 1757, 1759, - 162, 873, 146, 15957, -2632, 232, 1267, 1762, 1270, 1763, - 143, 154, -2632, 235, 15957, 15957, 15957, 1627, 15957, 8397, - 1768, -2632, 45464, -75, 1272, 1103, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, 176, 6181, -2632, 1316, -2632, -2632, - -2632, -2632, 1481, 15957, -2632, -2632, 1277, 1507, -2632, 236, - -2632, -2632, -2632, 581, 1507, -2632, -2632, -2632, -2632, -2632, - 310, 1684, 32950, 33430, 53144, -75, 55544, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, 657, -2632, 431, 35373, 1279, 1284, - -75, 889, 45464, 45464, 1749, -2632, -2632, -2632, 41669, 45464, - 1412, -2632, -2632, 153, 153, 9909, 708, 249, 73, 11421, - 16965, 1624, 1511, 173, 559, 1626, -2632, 1515, 700, 910, - 15957, 911, -2632, 1560, 45464, 39284, 615, 982, 1299, 1383, - 1300, 68, 1719, -2632, 1318, -2632, 1402, 45464, 57929, 179, - -2632, 1766, 179, 179, 193, 1767, 1410, 341, 1569, 59, - -95, 1318, 3358, -2632, 41669, 169, 322, 1318, 45464, 1419, - 611, 1318, 148, 16461, 1166, 1191, 344, 122, 1196, 1203, - 159, 161, 163, 165, 182, 16461, 1219, 1335, 184, 1434, - 1445, 1556, 1602, 1604, 1609, 1616, 1623, 200, 1637, 1639, - 1643, 1645, 1647, 210, 1650, 212, 1653, 141, 215, 16461, - 1667, 1338, -2632, 35373, 28, -2632, -2632, 1672, 217, -2632, - 31348, 1321, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, 1422, 53144, 1379, 583, 1689, 1747, 36404, 1342, - 44039, 45464, 1572, 3358, 1573, 1349, 1808, 1057, 1578, 1352, - -2632, 56024, -2632, -2632, -2632, -2632, -2632, -2632, 1353, -2632, - -2632, 15957, -2632, -2632, -2632, 1692, -2632, 43574, 43574, 1149, - 1149, -2632, -2632, 1816, 1439, 1444, 1692, -2632, 1692, -2632, - 53144, -2632, -2632, 43574, -2632, 53144, 1358, 1372, 1692, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, 1692, 1453, -2632, 1460, 1461, - 1462, -2632, -2632, -2632, -2632, -2632, 53144, 53144, -2632, 45464, - 45464, -2632, 45464, 53144, 1362, 58857, 38324, -2632, -2632, -2632, - -2632, 809, 853, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, 36404, -2632, 270, 34449, 1391, 15957, 1394, 1399, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, 1400, - 1711, -2632, -2632, -2632, 1404, 1405, 5385, 1406, 34485, 1407, - 19989, 19989, 1476, -2632, -2632, 19989, 1408, 37364, 34400, 1380, - 1409, 34530, 11925, 15957, 11925, 11925, 34939, -2632, 1417, 35018, - 49784, 1411, 44504, -2632, -2632, 45464, -2632, 10917, 10917, 1382, - 44984, 1454, 23934, -2632, -2632, 1858, -2632, 23934, 1700, -2632, - 23934, -2632, 45464, 1424, -2632, 45464, -2632, -2632, -2632, -2632, - 1425, 670, -2632, 765, 1710, -2632, -2632, 15957, -75, 15957, - -2632, 35373, 1474, 142, -2632, 31361, 29698, 12429, 31361, 1922, - 1922, 27775, -2632, 1590, 35047, -2632, 1441, 2858, 30186, 1433, - -2632, -75, -2632, 1437, 1448, 1436, -75, 15957, -2632, 15957, - 4361, 4361, -2632, 174, 43574, 15957, 15957, 15957, 15957, 15957, - 15957, 15957, 35924, 1530, 191, 53144, 15957, 15957, 1452, 954, - -2632, 15957, 1669, -2632, 1459, 15957, 1543, 257, 15957, 15957, - 15957, 15957, 15957, 15957, 15957, 15957, 15957, -2632, -2632, 22005, - 281, 1772, 1785, -75, -41, 510, 10917, 1794, 7893, -2632, - -75, 31990, 132, 1794, -2632, -2632, -2632, -2632, 245, -2632, - -2632, -2632, -2632, 1425, -2632, 1425, -2632, 53144, -2632, 45464, - 272, 40709, 15957, -2632, -2632, 1470, 1478, 1480, 1546, 1098, - 1950, 28255, 1765, -2632, 308, 308, 1486, -2632, 34387, 1728, - 1765, 153, -2632, -2632, 20493, 1625, 1779, 1717, -2632, -2632, - 1697, 1699, -2632, 1513, 35449, 17469, 17469, -2632, -3, 35373, - 1269, -2632, -2632, -2632, -2632, -2632, -2632, 67, -2632, 45464, - 33, 1624, 559, 1510, -2632, -2632, 1387, 1523, 56504, 45464, - 1788, 1753, 1797, -61, -2632, -2632, -2632, 43574, -2632, 45464, - 53144, 52184, 56984, 36884, 45464, 36404, -2632, -2632, -2632, -2632, - 45464, 1683, 45464, 3353, -2632, -2632, -2632, 179, -2632, -2632, - -2632, -2632, -2632, 53144, 45464, -2632, -2632, 179, 53144, 45464, - 179, -2632, 1542, 45464, 45464, 45464, 45464, 1652, 45464, 45464, - 46, 46, 1733, -2632, 12933, 168, -2632, 15957, 15957, -2632, - 15957, 1708, -2632, 773, -2632, 1754, 91, 1587, 45464, 45464, - 45464, 53144, 930, -2632, -2632, -2632, -2632, -2632, -2632, 36404, - 1547, -2632, 1548, 1893, -2632, 3358, 1897, 39764, 1029, 950, - 1589, 1903, 13437, 2018, 1791, -2632, -2632, 1770, 15957, 1567, - 1568, 90, 810, -2632, -2632, 1563, 1372, 1584, 1588, 1571, - 1577, 821, 43574, -2632, 822, 1692, 125, 1581, 1582, 1438, - 1378, 1006, 1336, 214, -2632, 230, -2632, 1782, 195, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, 831, 23454, -2632, - -2632, 2045, 1103, 2045, 815, -2632, -2632, 2045, -2632, 2045, - -2632, 43574, -2632, 30215, -2632, -2632, -2632, 15957, -2632, -2632, - 15957, -2632, 15957, 1913, -2632, 2074, 2074, 43574, 19989, 19989, - 19989, 19989, 19989, 562, 1267, 19989, 19989, 19989, 19989, 19989, - 19989, 19989, 19989, 19989, 20997, 525, -2632, -2632, 843, 2048, - 15957, 15957, 1923, 1913, 15957, -2632, 43574, 1591, -2632, 1592, - 1594, 15957, -2632, 43574, -2632, 45464, -25, 26, 1596, 1603, - -2632, -2632, 1610, 1507, -2632, 1095, 1150, 45464, 2605, 3035, - 3573, -2632, -2632, 15957, 1908, -2632, 15957, 1615, -2632, -2632, - 23934, 1858, 852, -2632, 43574, 45464, 862, 43574, 33910, -2632, - 16461, -2632, 43574, -2632, -2632, -2632, -2632, -2632, 1612, -2632, - 1617, 15957, 121, -2632, 1627, 1621, -2632, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, 1622, 1629, -2632, 1631, 45464, -2632, 17973, -2632, 53144, - -2632, -2632, 15957, 45464, -2632, 15957, 1636, 30251, -2632, -2632, - -2632, 353, 6750, 510, 4923, 4923, 4923, 31361, -2632, -2632, - -2632, 1641, -2632, 19989, 19989, -2632, 4800, 1264, 8397, -2632, - -2632, 1954, -2632, 909, -2632, 1630, -2632, -2632, 1942, -2632, - 29698, 5474, 15957, 240, -2632, 15957, 1452, 15957, 1709, 4923, - 4923, 4923, 253, 253, 265, 265, 265, 353, 510, -2632, - -2632, -2632, 1642, 1651, 1654, 1973, 1270, 15957, -2632, -2632, - 23934, 1454, 28, 1627, 1454, 1692, 4361, -2632, 911, -2632, - -2632, -2632, 35373, 45464, -2632, 1710, 23934, 1680, 1693, -17, - 26334, 1855, -2632, 53144, 53144, -2632, 1655, 1794, 1658, -2632, - -2632, -2632, 1664, 1664, 15957, 1613, 1664, -2632, 1765, -27, - 1864, 882, 882, -3, 1866, -2632, -2632, 1720, -2632, -2632, - -2632, 15957, 9405, 1354, -2632, 1361, -2632, -2632, -2632, -2632, - 1660, -2632, -2632, 1918, -2632, -2632, -2632, -2632, 1748, 1318, - 15957, 1894, -2632, 130, 1671, 2016, 364, 1972, 53144, -2632, - 285, 288, -2632, 894, 2021, 195, 2022, 195, 36404, 36404, - 36404, 863, -2632, -2632, 1103, -2632, -2632, 874, -2632, -94, - -2632, -2632, -2632, 1761, 625, 1318, 3358, -2632, -2632, -2632, - -2632, -2632, -2632, -2632, 170, 738, 1318, 1769, -2632, 1773, - -2632, 1774, 807, 1318, -2632, -2632, 168, 168, 168, 16461, - -2632, 1900, 1901, 1685, 35373, 35373, 35373, 1691, -2632, 325, - -2632, 53144, -2632, -2632, -2632, 1708, 45464, 1694, 2154, 1057, - 1352, -2632, 1839, 797, -2632, 697, -2632, 53144, 45464, 45464, - 45464, -2632, -2632, -2632, 1703, 1696, -2632, 40244, -31, 1912, - 1914, 45464, 1739, 1300, 2166, 45464, -2632, 876, 13941, 2053, - 45464, 1706, -2632, -2632, -2632, -2632, 1692, -2632, -2632, 470, - 470, -2632, 53144, -2632, -2632, 1712, -2632, 1715, -2632, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, 53144, - -2632, -2632, 36404, -2632, 37844, -2632, -2632, -2632, -2632, 1103, - -2632, 1103, 1930, 53144, 32470, 1103, 1103, 1718, -2632, 35373, - 30280, 35373, 1923, -2632, 2074, 2957, 2957, 2957, 2785, 2037, - 220, 1716, 2957, 2957, 2957, 380, 380, 171, 171, 171, - 2074, 525, 743, 37364, 1721, -2632, 35373, 35373, -2632, -2632, - 1726, -2632, -2632, -2632, -2632, 1727, 1729, -2632, -2632, -2632, - -2632, -2632, 53144, 989, -2632, 1454, 307, 307, 307, 307, - -2632, 45464, 45464, 45464, 35373, 2161, 2035, 35373, 45464, -2632, - -2632, -2632, 45464, 2153, 880, -2632, -2632, -2632, -2632, -2632, - 35166, 15957, -2632, 2087, 1590, -2632, -2632, 29698, -2632, 1732, - 8397, 35297, -2632, 2036, -75, 30378, -2632, 35373, -2632, 4361, - 15957, 1878, 2023, 15957, 1734, 15957, 2069, -2632, -2632, 1742, - -2632, -2632, 43574, 15957, 1750, 3357, 19989, 19989, 4144, -2632, - 4242, 15957, 8397, -2632, 1733, 14445, -2632, 1946, 1744, -2632, - 1908, 168, 1590, 1908, 1751, -2632, -2632, 1752, -2632, 15957, - 1899, -2632, -2632, -2632, 1809, -2632, 885, -2632, 2168, 1899, - -2632, 887, -2632, 28255, 1680, 15957, -75, 197, -2632, -2632, - -2632, 1758, -2632, 1664, -2632, -2632, -2632, 1970, -2632, -2632, - -2632, 45464, -2632, 45464, 30608, 2107, -2632, 53144, 53144, 53144, - -2632, 53144, 1771, 1764, 782, 1776, 354, -2632, 2377, 782, - 2090, 778, 1300, 341, 1944, 22, -2632, -2632, -2632, 1834, - 45464, -2632, 53144, -2632, -2632, -2632, -2632, -2632, 36884, -2632, - -2632, -2632, 36404, 29217, 36404, 45464, 45464, 45464, 45464, 45464, - 45464, 45464, 45464, 45464, 45464, 1795, 1800, 1803, 1733, -2632, - -2632, -2632, -2632, -2632, -2632, -95, -2632, -2632, 325, 1780, - 39764, 1806, 1589, 2230, 1747, 817, 52664, 1810, 1805, -2632, - 893, 3358, 1783, 2231, -2632, 1029, 39764, -2632, -2632, -2632, - 2189, -2632, 589, 239, -2632, -2632, 1806, 1352, -2632, 1806, - 35373, 53144, 1865, -2632, 1372, 1813, -2632, -2632, 1372, 43574, - 1372, -2632, -2632, 195, -2632, 901, -2632, -2632, -2632, -2632, - 53144, 1812, -2632, 1812, -2632, -2632, -2632, -2632, -2632, 19989, - 2142, 1819, 43574, -2632, -2632, 45464, -2632, -2632, -2632, 905, - 1824, 1908, 45464, 45464, 45464, 45464, -2632, -2632, -2632, 10413, - 15957, 1859, 1827, -2632, 53144, -2632, -2632, 15957, 35373, -2632, - 1828, -2632, -2632, 6724, -2632, 1830, 1831, 53144, 15957, -2632, - -2632, 729, 15957, 15957, 4800, -2632, 35326, 15957, 43574, 913, - 4800, 282, 15957, 2814, 3275, 15957, 15957, 4301, 30712, 1835, - 15957, 30774, 28735, -2632, 23934, 2035, 1840, -2632, 2035, 1103, - -2632, 35373, 10917, -2632, 1806, 1778, 53144, -75, -21, -2632, - 1842, 53144, -2632, 1899, 35373, -2632, -2632, 29698, -2632, -2632, - -2632, -2632, -2632, 53144, 1841, -2632, 1844, 782, -2632, 53144, - 1885, -2632, 242, 2146, 85, -2632, 15957, -2632, 2232, 2314, - 2377, 1854, 53144, 45464, 19989, -2632, 569, 223, -2632, 2136, - 45464, 1885, 2278, -2632, -2632, -2632, 354, -2632, 2173, 2097, - -2632, 179, -2632, 15957, 354, 2098, 234, 53144, -2632, -2632, - 3117, -2632, 43574, 195, 195, -2632, -2632, 1875, 1876, 1877, - 1879, 1881, 1883, 1884, 1886, 1887, 1888, 1889, 1891, 1892, - 1895, -2632, 1896, 1898, 1902, 1904, 1905, 1906, 1907, 1909, - 1140, 1919, -2632, 1920, 1758, 1921, 1925, 1927, 1929, 57464, - 1937, 1938, 1939, 1940, 1163, 1941, 1943, 809, 853, -2632, - -2632, -2632, -2632, -2632, -2632, 1063, 1947, -2632, 1910, -2632, - -2632, 1962, -2632, 1969, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, 168, 1194, 83, 53144, 1867, 1739, 2356, 14949, - 491, 2129, 1915, -2632, 1103, 1589, -2632, 39764, 1566, 624, - 1914, -2632, 219, 1739, -2632, 2295, 1948, 2381, -2632, 2128, - 53144, 1924, -2632, -2632, -2632, -2632, 37844, 1812, 3564, 19989, - 43574, 920, 922, -2632, 2415, 2102, 2035, -2632, -2632, -2632, - -2632, -2632, 1951, 35, 1952, -2632, 7389, 1953, -2632, -2632, - -2632, -2632, -2632, -2632, 35373, 35373, 53144, 2120, -2632, -2632, - 35373, -2632, 15957, -2632, -2632, 31451, 2259, 4800, 4800, 35326, - 976, -2632, 4800, 15957, 15957, 4800, 4800, 15957, -2632, -2632, - 30839, -2632, 58394, -2632, -2632, 1859, 1103, 1859, -2632, 1955, - -2632, -17, -2632, -2632, 2365, 25374, 2321, 15957, -2632, -2632, - 1957, 782, -2632, 2119, 1885, 1964, -2632, -2632, -2632, -2632, - -2632, -2632, 30957, -2632, 38, 15957, -2632, 761, 2785, -2632, - -2632, -2632, -2632, 1885, 1057, -2632, 45464, 2428, 2315, -2632, - -2632, 35373, -2632, -2632, 1692, 1692, -2632, -2632, 2153, -2632, - -2632, -2632, -2632, 1063, 426, 29217, 45464, 45464, 1968, -2632, - -2632, -95, 2345, 997, 1029, -2632, 1806, 1806, 35373, 45464, - 2320, 39764, -2632, 2435, 1974, 45464, 1739, 264, 264, -2632, - 2118, -2632, 2121, -2632, -2632, 318, -2632, 15453, 45464, -2632, - -2632, 25374, -2632, 3564, 1046, -2632, -2632, 1978, 1981, -2632, - 1859, 15957, 1985, 15957, -2632, 18477, 1983, -2632, 2449, 15957, - 2047, -2632, -2632, 15957, -2632, 4800, 4800, 4800, -2632, 2185, - -2632, 2120, -2632, 2120, 10917, 2046, 45464, 15957, -2632, 1048, - 2418, 254, -10, 35373, -2632, 45464, -2632, 36404, -2632, 782, - 369, 1996, 15957, 31121, 2220, -2632, -2632, 2250, -2632, 2310, - -2632, 2059, 531, 2073, -2632, -2632, -2632, -2632, 1194, 1103, - 1589, 1914, 1948, -2632, 2003, 45464, 1806, 1029, 589, -2632, - -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, -2632, - -2632, -2632, 2436, 2217, 2443, 1806, 35373, 1865, 1058, -2632, - -2632, 2510, 2120, 2020, 18477, 2025, -2632, 53144, 2027, 35373, - 2167, -2632, 31512, 2472, 1733, 2047, 2047, 1806, -2632, 31208, - 1454, 25374, 53144, 53144, 53144, -2632, 2156, 1057, 782, 1071, - -2632, 2041, -2632, -2632, -2632, -2632, 3358, -2632, 31285, 2264, - 447, 2248, 1996, 15957, -2632, 2109, -2632, -2632, -2632, 2500, - -2632, -2632, 39764, 2040, 1948, 1914, 1739, 2251, -2632, 2253, - -2632, 2049, 1589, 2044, 2047, -2632, 2050, -2632, -2632, -2632, - 44504, -2632, 15957, 487, -2632, -2632, -2632, 2418, -2632, -2632, - -2632, 308, -2632, 308, 28255, 2250, -2632, 36404, 29217, 725, - 369, 2338, -2632, -2632, -2632, -2632, 131, 2258, -2632, 2262, - -2632, 35373, -2632, 1806, 39764, -2632, -2632, -2632, -2632, -2632, - 25374, 1454, -2632, -2632, -2632, -2632, 1380, 18981, 18981, 2054, - 53144, 1664, 1664, 1454, 2248, -2632, -2632, -2632, -2632, -2632, - 736, 736, 2431, -2632, 2116, -2632, 1948, 1075, -2632, 21501, - 2200, 208, 34436, -2632, -2632, -2632, -2632, 308, -2632, -2632, - -2632, -2632, -2632, 2534, -2632, 187, -2632, -2632, -2632, 1589, - 2526, -2632, -2632, -2632, -2632, -2632, 1664, 782, -2632, -2632, - -2632, 1454, 19485, -2632, -2632, -2632 + 5571, 375, 773, -2784, -2784, 267, 375, 39697, 56010, 375, + 103, 1661, 43493, -2784, 335, 3579, 375, 46385, 61279, 285, + 255, 24341, 304, 46867, 46867, 56010, 46385, 47349, 375, 421, + 56492, -2784, 375, 26751, 43975, 13, 46385, 80, -62, 47831, + 46385, 797, 453, 30, -2784, -2784, -2784, -2784, -2784, 251, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, 128, -2784, 720, 138, 106, 39, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, 114, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, 26269, + -2784, -2784, -2784, -2784, -2784, -2784, 48313, 46385, 48795, 44457, + 49277, -2784, 743, -2784, 157, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, 160, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, 163, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, 179, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, 277, 534, + -2784, 187, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, 797, 46385, -2784, 49759, 377, 609, 515, + 50241, -2784, -2784, 46385, -2784, -2784, 886, 961, -2784, 754, + -2784, -2784, 44939, -2784, -2784, -2784, -2784, 56974, -2784, 504, + 779, -2784, -2784, -2784, 598, -2784, 131, -2784, -2784, 629, + 594, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, 698, + -2784, 41610, -2784, 57456, 50723, 51205, -2784, 567, 1405, 61280, + 24823, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, 114, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, 46867, 56010, 46867, 576, 582, 921, 208, + 210, 216, 222, 599, 613, 223, 624, 25305, 657, 683, + 691, 27234, 707, 713, 1049, 226, 737, 741, 766, 782, + 227, -62, 23374, 51687, 51687, 42, 2101, -2784, 51687, 52169, + -2784, 738, -2784, 740, 534, -2784, 743, -2784, -2784, -2784, + -2784, 281, 802, -2784, 788, 1099, -2784, -2784, -2784, 830, + -2784, -2784, 1025, 11247, 11247, 57938, 57938, 743, 57938, 856, + -2784, -2784, 75, -2784, -2784, 106, -2784, 848, -2784, 534, + -2784, 43975, -2784, -2784, 265, 1193, 16317, 46385, 865, -2784, + 877, 865, 891, 896, -2784, 5571, 1217, 1112, 43975, 666, + 666, 1355, 666, 947, 1013, -2784, 1494, -2784, 917, -2784, + 46385, -2784, 954, 1223, -2784, 848, 1297, 1053, 1109, 1330, + 3988, 1336, 1074, 1363, 1169, 1489, 8205, 16317, 37287, -2784, + 534, 1068, 1077, 1326, 1438, -2784, -2784, -2784, -2784, 857, + 1358, -2784, 1594, 46385, -2784, -2784, 1198, 52651, 53133, 53615, + 54097, 1564, -2784, -2784, 1504, 1159, 1189, -2784, 1691, -2784, + -2784, 1229, -2784, -2784, -2784, 257, -2784, -2784, -2784, -2784, + 1246, -2784, 1246, 1246, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, 1199, 1199, 1387, 1205, -2784, -2784, -2784, + 1561, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, 1232, 510, -2784, 1246, -2784, 1199, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, 60348, -2784, -2784, -2784, -2784, 701, + 894, -2784, 1237, -2784, -2784, -2784, 166, 1248, -2784, 1716, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, 1254, -2784, + 4176, 1199, -2784, -2784, 1578, 170, 1595, 224, -2784, 1617, + 1473, 16317, -2784, 1427, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -62, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, 670, -2784, -2784, 34541, -2784, -2784, 61280, 1273, + 1357, -2784, -2784, 16317, 16317, 1275, 1779, 1779, 2891, 51687, + 52169, 1779, 1779, 16317, 46385, -2784, 16317, 20373, 1289, 16317, + 16317, 9219, 16317, 22892, 51687, 2101, 1287, 46385, -2784, 1384, + 1308, 1384, 421, 24341, 1593, 1573, 1515, -2784, 24341, 1515, + 225, 1590, 1515, 1592, 1384, 27716, -2784, 1384, 1314, 1523, + -2784, -2784, 690, -2784, 34541, 16824, 42077, 1781, -2784, 1587, + 56010, 1323, -2784, -2784, -2784, -2784, -2784, -2784, 644, 1821, + 161, 1822, 16317, 161, 161, 1327, 229, 229, -2784, 1328, + -2784, 230, 1329, 1331, 1828, 1830, 158, 510, 161, 16317, + -2784, 229, 1335, 1832, 1338, 1837, 147, 149, -2784, 231, + 16317, 16317, 16317, 1697, 16317, 8712, 1838, 1845, -2784, 46385, + 534, 1349, 743, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, 213, 6179, -2784, -2784, 1385, -2784, -2784, -2784, -2784, + 1555, 16317, -2784, -2784, 1351, 1593, -2784, 232, -2784, -2784, + -2784, 552, 1593, -2784, -2784, -2784, -2784, -2784, 246, 1755, + 33577, 34059, 56010, 534, 58420, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, 711, -2784, 114, 36004, 1353, 1367, 534, 865, + 46385, 46385, 1842, -2784, -2784, -2784, 43975, 125, 1642, 1506, + -2784, -2784, 106, 106, 10233, 88, 258, 85, 11754, 17331, + 1728, 1576, 198, 176, 1731, -2784, 1618, 947, 1013, 16317, + 877, -2784, 1670, 46385, 40179, 901, 903, 1404, 1488, 1408, + 454, 1823, -2784, 1407, -2784, 1492, 46385, 60348, 220, -2784, + 1857, 220, 220, 291, 1858, 1497, 330, 1653, 31, 388, + 1407, 2246, -2784, 43975, 247, 50, 1407, 46385, 1499, 637, + 1407, 56010, 1273, 137, 16824, 811, 1294, 396, 146, 1444, + 1461, 159, 165, 169, 172, 175, 16824, 1480, 1528, 182, + 1537, 1600, 1623, 1638, 1654, 1656, 1658, 1660, 186, 1662, + 1664, 1666, 1669, 1671, 1673, 189, 1676, 196, 1689, 192, + 203, 16824, 1698, 1417, -2784, 36004, -22, -2784, -2784, 1710, + 206, -2784, 31586, 1411, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, 1511, 56010, 1468, 1772, 743, 46385, + 992, 1780, 1840, 42544, -2784, 46385, 1667, 2246, 1668, 1440, + 1906, 1675, 1077, 1677, 1447, -2784, 58902, 56010, 56010, 37287, + 1442, -2784, -2784, -2784, -2784, -2784, -2784, -2784, 1449, -2784, + -2784, 16317, -2784, -2784, -2784, 1779, -2784, 42077, 42077, 1246, + 1246, -2784, -2784, 1915, 1539, 1542, 1779, -2784, 1779, -2784, + 56010, -2784, -2784, 42077, -2784, 56010, 1460, 1465, 1779, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, 1779, 1547, -2784, 1548, 1550, + 1556, -2784, -2784, -2784, -2784, -2784, 56010, -2784, 46385, 46385, + -2784, 46385, 56010, 1458, 994, 61280, 39215, -2784, -2784, -2784, + -2784, 907, 1003, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, 37287, -2784, 1983, 743, 35082, 1471, 16317, 1477, + 1481, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + 1482, 1805, -2784, -2784, -2784, 1484, 1487, 5885, 1495, 35118, + 1500, 20373, 20373, 338, -2784, -2784, 20373, 1503, 38251, 35033, + 1485, 1507, 35163, 12261, 16317, 12261, 12261, 35574, -2784, 1512, + 35653, 51687, 1505, 45421, -2784, -2784, 46385, -2784, 11247, 11247, + 2101, 45903, 1522, 24341, -2784, -2784, 1043, -2784, 24341, 1796, + 24341, -2784, 24341, -2784, 46385, 1518, -2784, 46385, -2784, -2784, + -2784, -2784, 1516, 724, -2784, 748, 1749, -2784, -2784, 16317, + 16317, -2784, 36004, 1566, 143, -2784, 36328, 30129, 12768, 36328, + 2012, 2012, 28198, -2784, 1681, 35698, -2784, 1530, 1493, 6734, + 1526, -2784, -2784, -2784, -2784, 1529, 1527, 1525, 534, 16317, + -2784, 16317, 4193, 4193, -2784, 212, 42077, 16317, 16317, 16317, + 16317, 16317, 16317, 16317, 36805, 1622, 183, 56010, 16317, 16317, + 1532, 697, -2784, 16317, 1762, -2784, 1544, 16317, 1630, 685, + 16317, 16317, 16317, 16317, 16317, 16317, 16317, 16317, 16317, -2784, + -2784, 22401, 218, 534, 1869, 1888, -37, 853, 11247, 1880, + 8205, -2784, 534, 32131, 152, 1880, -2784, -2784, -2784, -2784, + 233, -2784, -2784, -2784, -2784, 1516, -2784, 1516, -2784, 56010, + -2784, 46385, 265, 43011, 16317, -2784, -2784, 1553, 1551, 1554, + 1609, -2784, -2784, 46385, 28680, 1844, -2784, 733, 733, 1560, + -2784, 35020, 1797, 1844, 106, -2784, -2784, 20880, 1686, 1846, + 1773, -2784, -2784, 1769, 1774, -2784, 1581, 36192, 17838, 17838, + -2784, 1368, 36004, 1377, -2784, -2784, -2784, -2784, -2784, -2784, + 56, -2784, 46385, 46, 1728, 176, 1585, -2784, -2784, 1192, + 1588, 59384, 46385, 1873, 1829, 1878, -83, -2784, -2784, -2784, + 42077, -2784, 46385, 56010, 54579, 59866, 37769, 46385, 37287, -2784, + -2784, -2784, -2784, 46385, 1288, 46385, 5809, -2784, -2784, -2784, + 220, -2784, -2784, -2784, -2784, -2784, 56010, 46385, -2784, -2784, + 220, 56010, 46385, 220, -2784, 1286, 46385, 46385, 46385, 46385, + 1348, 46385, 46385, -2784, -2784, 2, 2, 1810, -2784, 13275, + 124, -2784, 16317, 16317, -2784, 16317, 1782, -2784, 753, -2784, + 1820, 112, 46385, -2784, 1936, 1655, 46385, 46385, 46385, 46385, + 2102, -2784, -2784, -2784, -2784, -2784, 1610, -2784, 1612, 1968, + -2784, 2246, 1969, 40661, 906, 1474, 1970, 1663, 1973, 13782, + 2091, 1861, -2784, -2784, 1848, 1159, -2784, -2784, 37287, 16317, + 1635, 1636, 166, 757, -2784, -2784, 1640, 1465, 1657, 1659, + 1643, 1644, 759, 42077, -2784, 761, 1779, 181, 1645, 1646, + 1483, 1700, 784, 1373, 170, 224, -2784, 1853, 214, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, 771, 23859, -2784, + -2784, 2104, 743, 2104, 729, -2784, -2784, 2104, -2784, 2093, + 2104, -2784, 1273, 42077, -2784, 6797, -2784, -2784, -2784, 16317, + -2784, -2784, 16317, -2784, 16317, 1980, -2784, 2143, 2143, 42077, + 20373, 20373, 20373, 20373, 20373, 274, 1335, 20373, 20373, 20373, + 20373, 20373, 20373, 20373, 20373, 20373, 21387, 456, -2784, -2784, + 826, 2117, 16317, 16317, 1991, 1980, 16317, -2784, 42077, 1665, + -2784, 1672, 1678, 16317, -2784, 42077, -2784, 46385, 1, -42, + 1680, 1682, -2784, -2784, 1683, 1593, -2784, 981, 1011, 46385, + 3330, 3596, 5352, -2784, -2784, 16317, 1978, -2784, 16317, 1685, + -2784, -2784, 24341, -2784, 1043, 862, -2784, 42077, 46385, 881, + 42077, 34541, -2784, 16824, -2784, 42077, -2784, -2784, -2784, -2784, + -2784, 1688, 1703, 16317, 133, -2784, 1697, 1702, -2784, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, 1705, 1679, -2784, 1706, 46385, -2784, 18345, + -2784, 56010, -2784, -2784, 16317, 46385, -2784, 16317, 1707, 6968, + -2784, -2784, -2784, 1014, 36310, 853, 3360, 3360, 3360, 36328, + -2784, -2784, -2784, 1715, -2784, 20373, 20373, -2784, 3711, 4077, + 8712, -2784, -2784, 1988, -2784, 879, -2784, 1713, -2784, -2784, + 4265, -2784, 30129, 4728, 16317, 202, -2784, 16317, 1532, 16317, + 1742, 3360, 3360, 3360, 448, 448, 254, 254, 254, 1014, + 853, -2784, -2784, -2784, 1725, -2784, 1730, 1736, 2008, 1338, + 16317, -2784, -2784, 24341, 1522, -22, 1697, 1522, 1779, 4193, + -2784, 877, -2784, -2784, -2784, 36004, 46385, -2784, 1749, 24341, + 1704, 770, 2127, 56010, -2784, 1695, 1880, 1726, -2784, -2784, + -2784, 1684, 1684, 16317, 1992, 1684, -2784, 1844, 14, 1881, + 1153, 1153, 1368, 1884, -2784, -2784, 1733, -2784, -2784, -2784, + 16317, 9726, 1393, -2784, 1399, -2784, -2784, -2784, -2784, 1724, + -2784, -2784, 1989, -2784, -2784, -2784, -2784, 1825, 1407, 16317, + 1967, -2784, 249, 1740, 2092, -74, 2046, 56010, -2784, 328, + 358, -2784, 821, 2095, 214, 2096, 214, 37287, 37287, 37287, + 885, -2784, -2784, 743, -2784, -2784, 904, -2784, 433, -2784, + -2784, -2784, 1831, 717, 1407, 2246, -2784, -2784, -2784, -2784, + -2784, -2784, -2784, 256, 876, 1407, 1833, -2784, 1834, -2784, + 1836, 884, 1407, -2784, -2784, 124, 124, 124, 16824, -2784, + 1977, 1979, 1759, 36004, 36004, 36004, 1764, -2784, 363, -2784, + 56010, -2784, -2784, -2784, 1782, 2094, 743, 46385, 1761, 2229, + 1077, 1447, -2784, 1926, 934, 122, -2784, 56010, 46385, 46385, + 46385, -2784, -2784, -2784, 1770, 1777, -2784, 41143, -19, 1990, + 1987, 46385, 1814, 46385, 1408, 2240, 46385, -2784, 924, 14289, + 2134, 46385, -2784, 1785, -2784, -2784, -2784, -2784, 1779, -2784, + -2784, 447, 447, -2784, 56010, -2784, -2784, 1788, -2784, 1798, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, 56010, -2784, -2784, 37287, -2784, 38733, -2784, -2784, -2784, + -2784, 743, -2784, 743, 2019, 56010, 32613, 743, 33095, 743, + -2784, 1795, -2784, 36004, 30619, 36004, 1991, -2784, 2143, 1699, + 1699, 1699, 4704, 2133, 240, 1804, 1699, 1699, 1699, 489, + 489, 132, 132, 132, 2143, 456, 738, 38251, 1807, -2784, + 36004, 36004, -2784, -2784, 1808, -2784, -2784, -2784, -2784, 1812, + 1813, -2784, -2784, -2784, -2784, -2784, 56010, 1160, -2784, 1522, + 13, 13, 13, 13, -2784, 46385, 46385, 46385, 36004, 2250, + 2135, 36004, 46385, -2784, -2784, -2784, 46385, 2242, 926, -2784, + -2784, -2784, -2784, -2784, 35817, 16317, -2784, 2177, 1681, -2784, + -2784, 30129, -2784, 1819, 8712, 35942, -2784, 2125, 30648, -2784, + 36004, -2784, 4193, 16317, 271, 2438, 16317, 1824, 16317, 2156, + -2784, -2784, 1827, -2784, -2784, 42077, 16317, 1835, 4902, 20373, + 20373, 5085, -2784, 7072, 16317, 8712, -2784, 1810, 14796, -2784, + 2034, 1839, -2784, 1978, 124, 1681, 1978, 1843, -2784, -2784, + 1847, -2784, 16317, 1981, 1886, -23, 26751, 2051, -2784, 56010, + 951, -2784, 28680, 1704, 16317, 534, 612, -2784, -2784, -2784, + 1850, -2784, 1684, -2784, -2784, -2784, 2053, -2784, -2784, -2784, + 46385, -2784, 46385, 30684, 2187, -2784, 56010, 56010, 56010, -2784, + 56010, 1841, 1856, 718, 1851, 844, -2784, 2255, 718, 2172, + 234, 1408, 330, 4861, 508, -2784, -2784, -2784, 1930, 46385, + -2784, 56010, -2784, -2784, -2784, -2784, -2784, 37769, -2784, -2784, + -2784, 37287, 29646, 37287, 46385, 46385, 46385, 46385, 46385, 46385, + 46385, 46385, 46385, 46385, 1860, 1862, 1863, 1810, -2784, -2784, + -2784, -2784, -2784, -2784, 388, -2784, -2784, 363, 743, -2784, + 1854, 40661, 797, 1663, 2322, 1840, 994, 55061, 1866, 1865, + -2784, 968, 2246, 1872, 2325, -2784, 906, 40661, -2784, -2784, + -2784, 2294, -2784, 567, 238, -2784, 1077, -2784, 797, 1447, + -2784, 797, 36004, 56010, 1933, -2784, 1465, 1885, -2784, -2784, + 1465, 42077, 1465, -2784, -2784, 214, -2784, 979, -2784, -2784, + -2784, -2784, 56010, 1875, -2784, 1875, -2784, -2784, 1875, -2784, + -2784, -2784, -2784, 20373, 2210, 1883, 42077, -2784, -2784, 46385, + -2784, -2784, -2784, 985, 1887, 1978, 46385, 46385, 46385, 46385, + -2784, -2784, -2784, 10740, 16317, 1924, 1890, -2784, 56010, -2784, + -2784, 16317, 36004, -2784, 1891, -2784, -2784, 6116, -2784, 1892, + 1894, 56010, 16317, -2784, -2784, 365, 16317, 16317, 3711, -2784, + 6715, 16317, 42077, 993, 3711, 276, 16317, 3648, 4104, 16317, + 16317, 7087, 30713, 1897, 16317, 30963, 29162, -2784, 24341, 2135, + 1898, -2784, 2135, 743, -2784, 36004, 11247, -2784, -2784, -2784, + -2784, 1942, -2784, 1005, -2784, 2315, 1981, -2784, 1912, 56010, + -2784, 1981, 36004, -2784, -2784, 30129, -2784, -2784, -2784, -2784, + -2784, 56010, 1902, -2784, 1905, 718, -2784, 56010, 1945, -2784, + 627, 2207, 139, -2784, 16317, -2784, 2293, 2373, 2255, 1911, + 56010, 46385, 20373, -2784, 654, 235, -2784, 2189, 46385, 1945, + 2331, -2784, -2784, -2784, 844, -2784, 2226, 2141, -2784, 220, + -2784, 16317, 844, 2144, 261, 56010, -2784, -2784, 1693, -2784, + 42077, 214, 214, -2784, -2784, 1917, 1919, 1920, 1921, 1922, + 1929, 1940, 1944, 1948, 1951, 1957, 1958, 1959, 1960, -2784, + 1961, 1962, 1963, 1966, 1974, 1975, 1976, 1994, 1232, 1995, + -2784, 1996, 1850, 1997, 1998, 1999, 2002, 2003, 55543, 2004, + 2006, 2007, 2009, 1237, 2011, 2014, 907, 1003, -2784, -2784, + -2784, -2784, -2784, -2784, 1189, 2015, -2784, 1993, -2784, -2784, + 2073, -2784, 2074, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, 124, 1273, 177, -2784, 56010, 2023, 1814, 2433, 15303, + -3, 2221, 2010, -2784, 743, 1663, -2784, 40661, 1608, 547, + 1987, -2784, 174, 1814, -2784, 2385, 1663, 2032, 2488, -2784, + 2241, 56010, 2028, -2784, -2784, -2784, -2784, 38733, 1875, 4778, + 20373, 42077, 1006, 1016, -2784, 2521, 2190, 2135, -2784, -2784, + -2784, -2784, -2784, 2030, -52, 2035, -2784, 7698, 2033, -2784, + -2784, -2784, -2784, -2784, -2784, 36004, 36004, 56010, 2211, -2784, + -2784, 36004, -2784, 16317, -2784, -2784, 31615, 2345, 3711, 3711, + 6715, 1024, -2784, 3711, 16317, 16317, 3711, 3711, 16317, -2784, + -2784, 30992, -2784, 60815, -2784, -2784, 1924, 743, 1924, -2784, + 2036, 797, 672, 56010, 534, -24, -2784, 16317, -2784, -2784, + 2040, 718, -2784, 2206, 1945, 2044, -2784, -2784, -2784, -2784, + -2784, -2784, 31028, -2784, 67, 16317, -2784, 809, 4704, -2784, + -2784, -2784, -2784, 1945, 1077, -2784, 46385, 2508, 2396, -2784, + -2784, 36004, -2784, -2784, 1779, 1779, -2784, -2784, 2242, -2784, + -2784, -2784, -2784, 1189, 410, 29646, 46385, 46385, 2048, -2784, + -2784, 388, 2427, 1091, 906, -2784, 797, 797, 36004, 46385, + 2401, 40661, -2784, 2516, 2054, 46385, 1814, 928, 928, -2784, + 2196, -2784, 2198, -2784, -2784, 2520, 279, -2784, 15810, 46385, + -2784, -2784, 25787, -2784, 4778, 1095, -2784, -2784, 2057, 2059, + -2784, 1924, 16317, 2062, 16317, -2784, 18852, 2060, -2784, 2526, + 16317, 2124, -2784, -2784, 16317, -2784, 3711, 3711, 3711, -2784, + 2262, -2784, 2211, -2784, 2211, 11247, -2784, -23, -2784, -2784, + 2482, 25787, 2439, 36004, -2784, 46385, -2784, 37287, -2784, 718, + 382, 2070, 16317, 31271, 2296, -2784, -2784, 2326, -2784, 2386, + -2784, 2136, 528, 2148, -2784, -2784, -2784, -2784, 1273, 743, + 1663, 1987, 2032, -2784, 2077, 46385, 797, 906, 567, -2784, + -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, -2784, + -2784, -2784, 797, 2511, 2291, 2513, 797, 36004, 1933, 16317, + -2784, 1097, 2509, 270, -2784, -2784, 2574, 2211, 2083, 18852, + 2087, -2784, 56010, 2089, 36004, 2230, -2784, 31651, 2537, 1810, + 2124, 2124, 2149, 46385, 1102, 34, 1077, 718, 1142, -2784, + 2106, -2784, -2784, -2784, -2784, 2246, -2784, 31307, 2328, 136, + 2312, 2070, 16317, -2784, 2174, -2784, -2784, -2784, 2563, -2784, + -2784, 40661, 2103, 2032, 1987, 1814, 2032, 2316, -2784, 2317, + -2784, 2107, 31336, 1663, 25787, 56010, 56010, 56010, 2109, 2124, + -2784, 2110, -2784, -2784, -2784, 45421, -2784, 16317, 636, -2784, + -2784, 797, -2784, 1522, -2784, 2236, 2326, -2784, 37287, 29646, + 1743, 382, 2414, -2784, -2784, -2784, -2784, 135, 2334, -2784, + 2337, -2784, 36004, -2784, 797, 40661, -2784, -2784, -2784, -2784, + -2784, -2784, 25787, 2509, 1522, -2784, -2784, 733, -2784, 733, + -2784, -2784, -2784, -2784, 1485, 19359, 19359, 2116, -2784, -2784, + 28680, 2312, -2784, -2784, -2784, -2784, -2784, 492, 492, 2503, + -2784, 2188, -2784, 2032, 1144, 56010, -2784, 1684, 1684, 21894, + 2271, 185, 35069, -2784, -2784, -2784, -2784, 1522, -2784, -2784, + 2606, -2784, 244, -2784, -2784, -2784, 1663, 733, -2784, -2784, + 2598, -2784, -2784, -2784, -2784, -2784, -2784, 718, -2784, -2784, + -2784, 1522, 1684, 19866, -2784, -2784, -2784 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -2632, -2632, -2632, 1890, 81, -2632, -2632, 158, -2632, 908, - -2632, 152, -629, 498, -2632, 89, 94, -1061, 14, -2632, - -2632, -2632, -2632, -14, 221, -2632, -458, -2100, -247, -2632, - -2631, -2260, -2632, -2632, -519, -2617, -1890, 95, -2632, -2632, - 97, 6, 124, 98, -2347, 99, -695, -1107, -860, -1124, - -2632, -66, 100, 1345, 7, -2013, -2594, -470, -2632, -558, - -2632, -261, -2632, -513, -2632, -498, -521, -544, -2316, -1067, - -2632, 1477, -304, -2632, 529, -2632, -2333, -2632, -2632, 517, - -2632, -1084, -2632, -1809, 134, -500, -2336, -2319, -1993, -705, - 202, -509, 180, -1928, -797, -2632, 538, -2632, -491, -2632, - -685, -2075, 103, -2632, -2632, 1241, -787, -2632, 1291, 105, - 1324, -1947, 15, 106, -2632, -2632, -2632, -2632, -599, 476, - -2511, -2632, 410, -2632, -2632, -2632, -2632, -143, 167, -2632, - 57, 127, -34, -33, -2632, -29, 19, 75, 1534, -972, - -2632, -1458, 926, -2632, 1670, 1673, -1995, -662, -56, -2632, - 597, -1549, -1968, -528, 990, 1525, 1524, 362, -2174, -2632, - -451, -2632, 53, -2632, -2632, 595, 1036, -1459, -1426, -2632, - -1975, -2632, -371, -281, -2632, -2632, -2632, -2632, -2632, -2276, - -1991, -517, 1014, -2632, 1545, -2632, -2632, -2632, -2632, -7, - -1422, 2628, 646, -572, 2051, -542, -367, 1730, 1698, 640, - 785, 18, 2063, 416, -2632, -2632, 419, -1940, -1404, 381, - -206, 1330, -2632, -2632, -475, -1215, -757, -2632, -2632, 477, - 1649, -2632, -2632, -2632, 1722, 2288, -2632, -2632, 2441, 2555, - -2632, -613, 2709, -167, -741, 1741, -843, 1755, -856, -846, - -852, 1756, 1775, -1419, 4027, -1335, -683, 3, -2632, -1389, - 17, -2632, -2632, -2632, -2632, -1743, -2632, -341, -2632, -338, - -2632, -2632, -2632, -447, -2322, -2632, 917, 754, -2632, -2632, - -2632, -1444, -2632, 4314, 659, -2632, -1856, -918, -640, -1022, - -882, -1123, -1277, -2632, -2632, -2632, -2632, -2632, -2632, -896, - -1638, -189, 716, -2632, -2632, 794, -2632, -2632, -2632, -666, - 985, -561, -973, 727, 1245, 112, -563, -1511, -2632, -1144, - -2167, -2632, -2632, -1933, -2632, 1500, -466, -1039, 241, -1143, - 5, -2632, 4307, 266, 2265, 2145, -2340, -2632, -2632, -502, - -2378, -1049, -2632, -684, -2632, 107, -2632, 686, 109, 554, - -2632, 8, -2632, -311, -2632, -2632, -2350, -2632, 111, 113, - -2632, -2632, -2632, -444, -2632, -483, -474, -2632, -2632, 27, - -895, 1326, -2632, 114, 613, -2632, 825, -2632, 658, 115, - 108, 116, 1119, -2632, -2632, -2632, 32, -440, 340, -2632, - 1124, 117, -2632, -2632, 118, -2632, 2681, 2625, 119, 10, - -2619, 120, -2476, -1566, -6, -2632, -2632, -2632, -520, -2632, - -2330 + -2784, -2784, -2784, 1939, 81, -2784, -2784, 171, -2784, 927, + -2784, 167, -650, 506, -2784, 82, 89, -1104, 47, -2784, + -2784, -2784, -2784, -253, 221, -2784, -2784, -496, -1480, -375, + -2784, -2755, -2783, -2784, -2784, -563, -2707, -1949, 90, -2784, + -2784, 91, -2784, -2784, 4, 129, 92, -2417, 94, -712, + -1152, -929, -1162, -2784, -64, 97, 1508, -2784, 5, -2097, + -2660, -469, -2784, -564, -2784, -262, -2784, -515, -2784, -700, + -522, -552, -2537, -1108, -2784, 1509, -307, -2784, 539, -2784, + -2412, -2784, -2784, 527, -2784, -1122, -2784, -2119, 140, -500, + -2418, -2415, -2009, -711, 215, -512, 188, -2014, -980, -2784, + 548, -2784, -491, -2784, -709, -1710, 99, -2784, -2784, -502, + -752, -2784, 1309, 101, 1350, -1989, 48, 102, -2784, -2784, + -2784, -2784, -732, 484, -1166, -2784, 415, -2784, -2784, -2784, + -2784, -146, 180, -2784, 11, 108, -39, -31, -2784, -26, + 55, 69, 1562, -1008, -2784, -1304, 922, -2784, 1701, 1711, + -2042, -693, -63, -2784, 601, -1589, -2032, -557, 1001, 1546, + 1565, 362, -1952, -2784, -463, -2784, -131, -2784, -2784, 595, + 1037, -1508, -1464, -2784, -2083, -2784, -392, -295, -2784, -2784, + -2784, -2784, -2784, -2339, -2632, -547, 1012, -2784, 1558, -2784, + -2784, -2784, -2784, 109, -1478, 2682, 638, -609, 2079, -571, + -393, 1745, 1719, 310, 778, 24, 2099, 411, -2784, -2784, + 413, -2016, -1460, 374, -217, 1337, -2784, -2784, -497, -1319, + -796, -2784, -2784, -419, -478, -2784, -2784, -2784, -132, 902, + -2784, -2784, 1694, 2075, -2784, -633, 2346, -495, -787, 1766, + -922, 1767, -913, -882, -891, 1771, 1775, -1477, 3885, 556, + 1394, -2784, -6, -2784, -1390, 35, -2784, -2784, -2784, -2784, + -2545, -2784, -360, -2784, -358, -2784, -2784, -2784, -467, -2483, + -2784, -592, 752, -2784, -2784, -2784, -1512, -2784, 4554, 656, + -2784, -1910, -952, -676, -1074, -918, -1191, -1322, -2784, -2784, + -2784, -2784, -2784, -2784, -1467, -1690, -300, 710, -2784, -2784, + 787, -2784, -2784, -2784, -710, 987, -573, -1059, 719, 1244, + 116, -588, -1569, -2784, -1530, -2228, -2784, -2784, -1957, -2784, + 2718, -485, -1086, 1744, -1196, 22, -2784, 3412, 457, 2194, + 3072, -2350, -2784, -2784, -1324, -2444, -1090, -2784, -716, -2784, + -2784, 104, -2784, 677, 105, 546, -2784, 6, -2784, -329, + -2784, -2784, -2435, -2784, 107, 110, 2146, -2784, -2784, -2784, + -468, -2784, -504, -501, -2784, -2784, 10, -923, 1334, -2784, + 111, 544, -2784, 812, -2784, 663, 115, 98, 117, 1120, + -2784, -2784, -2784, 49, -540, 333, -2784, 1128, -2784, -2784, + -2784, -2784, 2005, -2784, 118, -2784, -2784, 119, -2784, 2737, + 2676, 120, 7, -2748, 121, -2599, -1621, -7, -2784, -2784, + -2784, -561, -2784, -2351 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1873 +#define YYTABLE_NINF -1916 static const yytype_int16 yytable[] = { - 490, 717, 1142, 1284, 670, 681, 49, 53, 68, 486, - 84, 487, 611, 490, 45, 56, 1429, 1390, 1681, 63, - 1277, 1108, 617, 1079, 487, 1323, 1368, 914, 1285, 1371, - 683, 1645, 78, 1680, 684, 63, 619, 940, 1829, 814, - 1281, 1742, 1910, 570, 1586, 1989, 2023, 1329, 1501, 2026, - 656, 2340, 1383, 1656, 2343, 2369, 1652, 58, 2374, 2399, - 966, 1876, 1634, 822, 796, 1553, 1692, 1404, 1141, 946, - 1147, 1406, 1151, 908, 960, 1557, 816, 1405, 1047, 1560, - 1402, 42, 1563, 2705, 1685, 1805, 1806, 1471, 652, 43, - 1825, 1928, 1929, 2707, 44, 47, 1065, 48, 50, 51, - 52, 1499, 2728, 54, 2324, 55, 57, 66, 1746, 67, - 699, 69, 668, 70, 75, 76, 77, 80, 81, 83, - 85, 2435, 2436, 2437, 2362, 2743, 915, 59, 1309, 1310, - 628, 2726, 2740, 2544, 980, -1841, -1841, -1101, 2447, 691, - 2392, 1994, 2138, 59, -457, 1718, 610, 624, -747, -460, - 1331, -739, 1101, -1126, -1870, -1870, -1126, 2046, 59, -747, - 1321, -1123, -1123, 1104, -1694, 669, -1695, -744, -1696, -1701, - -1697, -744, -1844, -1844, -1845, -1845, -1846, -1846, -1847, -1847, - 1374, 624, 1807, 1377, 1061, 980, 1808, -1698, 980, -1701, - 682, -1710, 2049, 2453, 2248, -1848, -1848, -1851, -1851, 1637, - 1567, -1718, 660, -974, 2840, -1710, -1127, -417, 494, 59, - -974, -1694, 2879, -1860, -1860, -1716, -1695, -1718, -1696, 2460, - -1720, -1697, -1127, -1866, -1866, -1868, -1868, 2961, -1871, -1871, - -1124, -1124, -1698, 1942, -1716, 1090, -1720, -706, -719, -457, - -734, 624, 730, 980, -460, 673, 1648, 1648, 958, 1423, - 624, 2885, 515, 3140, 2467, 1331, 545, 1683, 2427, 2589, - 2291, -569, 2133, 3035, 1514, 630, 2824, 2903, 1515, 1665, - 1329, 1690, 1668, 1669, 1331, 1068, 1514, 667, 667, 1396, - 1515, 2974, 1942, 1691, 2257, 2501, 2503, 625, 625, 1739, - 1331, 1605, 1303, 2990, 3008, 2855, 1523, 1605, 1640, 2815, - 1281, 1670, 2817, 1657, 3179, 3, 4, 1963, 1523, 2052, - 1979, -994, 1657, 1564, 1377, 624, 1986, 1980, -994, 980, - 3034, 678, 1779, 2395, 19, 2521, -679, 2874, 1525, 3032, - 624, 695, 947, 674, 1097, 2259, 1304, 1606, 581, 678, - 1525, 2900, 2851, 1606, 2991, -184, 2576, 2020, 2744, 2873, - -184, 676, 2510, 2992, 2047, 2048, 2901, -1840, -1840, 2121, - 2595, 2540, 2837, 3061, 1514, 2575, 1675, 1780, 2578, 86, - 2403, 1664, 808, 3172, 1309, 1310, 1449, 2607, 1495, 3002, - 2067, 1455, 2993, 960, 2260, 2893, 2617, 3003, 2352, 1321, - 1676, 1807, 914, 1781, 2423, 1808, 1523, 946, 2650, 1281, - 2271, 2272, 2273, 1607, 639, 2598, 580, 2424, 1099, 2577, - 2618, 1782, 1602, 2922, 87, 1783, 2053, 1620, 2894, 677, - 2989, 1679, 703, 2353, 2899, 2596, 704, 1565, 1525, 3036, - 1062, -457, 1391, 1964, 2021, 2838, -460, 1784, 2068, 1332, - 1785, 2541, 1069, 1671, 1070, 3115, 1608, 1091, 914, 1965, - 1642, 1672, 1608, 2994, 1966, 1786, 3130, 1890, 1987, 2392, - 2396, 2392, 1506, -679, 3180, 2995, 948, 3057, 1655, 2258, - 1633, 2284, 1487, 2224, 2225, 2226, 2227, 2228, 2825, 582, - 2232, 2233, 2234, 2235, 2236, 2237, 2238, 2239, 2240, 2241, - 2920, 1967, 1562, 2829, -457, 2972, 1658, 678, 2956, -460, - 2852, 1063, 2511, 3147, 3136, 1658, 1609, 640, 2134, 2745, - 920, 1305, 1609, 670, 974, 2122, 1910, 2966, 1603, 1562, - 2261, 1514, 27, 3173, 2880, 1515, 764, 3168, 2841, 661, - 2747, 1694, 1695, 810, -590, 2705, 1807, 2962, 2902, 731, - 1808, 913, 914, 914, 1332, 2707, 2766, 1787, 1566, 1880, - 1092, 2981, 707, 1523, 2062, 1788, 3004, 1412, 1655, 32, - -974, 2857, 675, 1332, 1643, 63, 1657, 1655, 623, 2862, - 3141, 2120, 2757, 2046, 910, 670, 2144, 2345, 1891, 1332, - 1631, 2372, 2608, 2463, 2508, 1525, 1684, 2428, 490, 2831, - 3117, 1632, 1730, 1333, 1943, 2364, 1307, 617, 1789, 487, - 35, 1681, 939, 490, 1277, -457, 1324, 2377, 2311, 2312, - -460, 619, 617, 685, 487, 808, 2447, 1324, 1306, 3103, - 683, 1483, 59, 2186, 684, 2931, 619, 1109, 1325, 703, - 3059, -1101, 1581, 704, 1894, 490, 490, 679, 1968, 1325, - 937, 3066, 1326, 2326, -457, -739, -457, -1126, 1588, -460, - -1126, -460, 38, 1328, 3065, 495, 2996, 490, -1694, 2997, - -1695, -744, -1696, -1701, -1697, 3060, 1823, 1981, -994, 1381, - 1382, 1495, 2749, 59, 669, 1509, 1992, 1066, 49, 53, - 68, -1698, 84, -1701, 1686, -1710, 45, 56, 1072, 2849, - 917, 63, 1648, 1066, 2229, -1718, 1198, 490, 1278, -1710, - -1127, 2828, 624, 1649, 78, -1694, 1743, 1744, 1778, -1716, - -1695, -1718, -1696, 658, -1720, -1697, -1127, 1367, 2443, 2444, - 1097, 924, 3121, 1071, 2864, 2865, -1698, 2878, -1716, 58, - -1720, 1311, 1315, 1370, -734, 1558, 938, 1423, 1423, 1081, - 1514, 2830, 1423, 2726, 1995, 1543, 1544, 1545, 1546, 3116, - 2294, 703, 3104, 42, 727, 704, 718, 2120, 2705, 1658, - 1546, 43, 2850, 1128, 1599, 3042, 44, 47, 2707, 48, - 50, 51, 52, 2897, 3093, 54, 810, 55, 57, 66, - 682, 67, 1129, 69, 819, 70, 75, 76, 77, 80, - 81, 83, 85, 1838, 1099, 2894, 3162, 2883, 663, 59, - 1381, 1382, 1675, 808, 1525, 2067, 2256, 2097, 2522, 2523, - 2524, 2525, 1889, 1772, 490, 1721, 3127, 2100, 980, 3181, - 2103, 1655, 2898, 2959, 3043, 1707, 1676, 3170, 719, 3105, - 2621, -184, -184, 1130, 2230, 1889, 2256, 1888, 1939, 1495, - 1281, 671, 796, 1100, 2231, 3128, 916, 1914, 625, 2342, - 2167, 3084, 3085, 1910, 1829, 1657, 914, 1774, 1753, 672, - 3185, 1097, 980, 2389, 814, 1764, 1098, 1926, 19, 1657, - 3157, 1768, 1820, 1821, 1822, 1823, 2299, 1277, 2624, 19, - 1865, 2265, 686, 2207, 1853, 1869, 2375, 1889, 1871, 967, - 2550, 980, 1770, 1568, 1889, 2637, 1281, 2889, 1844, 702, - 3123, 2611, 908, 1765, 2191, 667, 913, 2222, 2193, 2195, - 2196, 1058, 490, 490, 2192, 2194, 2190, 1707, 2205, 2400, - 2973, 2035, 490, 1324, 1131, 490, 490, 1719, 490, 490, - 490, 490, 1115, 1324, 63, 1099, 1506, 2249, 1116, 1319, - 1320, 611, 490, 3038, 1709, 1325, 611, 490, 2304, 2346, - 3025, 617, 3026, 487, 2174, 1325, 617, 725, 487, 1326, - 2484, 808, 913, 1198, 810, 619, 2488, 2638, 2096, 2490, - 619, 2089, 1681, 1689, 713, 1132, 2197, 968, 2198, 2372, - 490, 2200, 1657, 1133, 1100, 670, 2612, 2426, 969, 1708, - 728, 2563, 2564, 1846, 497, 1134, 2438, 490, 1847, 1446, - 1541, 1542, 1543, 1544, 1545, 1546, 3163, 2059, 490, 490, - 490, 1461, 490, 490, 1464, 1818, 1819, 1820, 1821, 1822, - 1823, 3074, 709, 1945, 710, 3055, 1135, 2143, 2116, 2117, - 2118, 2401, 1719, 2964, 2095, 1277, 1709, 490, 2628, 1930, - 729, 2316, 59, 2429, 1117, 2559, 2366, 732, 1658, 89, - 2639, 1657, 2613, 2106, 2614, 498, 913, 913, 2113, 1648, - 1592, 1593, 1658, 1600, 684, 684, 27, 684, 2317, 1499, - 1651, -512, 2941, 1137, 2943, 610, -512, 27, 703, 733, - 610, 2629, 1561, 1324, 734, 3164, 1951, 2212, 820, 490, - 3088, 2468, 2213, 490, 490, 1138, 2475, 2630, 2171, 1375, - 2430, 2161, 1376, 32, 490, 1325, 1066, 497, 624, 1480, - 1655, 2762, 3165, 1952, 32, 1140, 711, 920, 712, 1328, - 1484, 19, 810, 808, 1655, 1423, 1423, 1423, 1423, 1423, - -1172, 720, 1423, 1423, 1423, 1423, 1423, 1423, 1423, 1423, - 1423, 1423, 918, 2214, 35, -512, 1497, 1198, 3177, 919, - 808, 808, 703, 1910, -1101, 35, 704, 1579, 36, 1198, - 1580, 921, 1682, 3158, 3159, 922, 808, 721, 498, 2434, - 1879, 2098, 2071, 1880, 2758, 1658, 2101, 3012, 1386, -1838, - -1838, 3148, 37, 1198, 2211, 1118, 2318, 923, 2215, 1411, - 2216, 2319, 926, 3160, -512, 2631, 38, 927, 1118, 676, - 928, 2254, 2632, 2456, -1839, -1839, 1115, 38, 3183, -1842, - -1842, 90, 1116, -513, 951, 2008, -1843, -1843, -513, 91, - 682, 682, 2142, 682, 933, 3137, 1953, 501, 963, 502, - 1313, 1954, -1849, -1849, 1386, 2761, 1955, 1655, 965, 2532, - 2402, 3184, 2403, 1837, 1658, 1839, 1840, 931, 952, 1119, - 723, 932, 1322, 1120, 505, 92, 1056, 1057, 914, 1059, - 1423, 1423, 1347, 1348, 1457, 1881, 934, 677, 1882, 19, - 2404, 935, 1513, 2130, 954, 1514, 2131, 2183, 936, 1515, - 2648, 2800, 1278, 1121, 810, 937, 1365, -513, 2411, 2848, - 2413, 1508, 970, 1713, 1714, 1716, 2641, 1717, 2279, 1479, - 1511, 38, 93, 973, 2605, 490, 1655, 1523, 2314, 2497, - 2175, 810, 810, 1882, -1873, 1559, 2217, 972, 1117, 27, - 974, 2181, 2184, 667, 2182, 2182, 1569, 810, 1386, 1386, - 2341, 2201, 2223, 2320, 2202, 2640, -513, 2649, 2723, 1525, - 501, 975, 502, 2242, 2321, 678, 2243, 808, -1850, -1850, - 94, 1122, 2281, 493, 1115, 2282, 32, 1060, 914, 544, - 1116, 2250, 2285, 2417, 504, 2282, 2418, 505, 2255, 1064, - 913, 638, 1351, 1352, 2421, 651, 2478, 2422, 1956, 1880, - 2536, 1075, 1499, 2282, 2587, 2585, 1278, 2590, 2586, 1957, - 2591, 490, 1082, 2735, 63, 956, 2131, 35, 2009, 2283, - 1085, 2755, 2283, 910, 2756, 2763, 1086, 2287, 2764, 2313, - 1083, 36, 1115, 2801, 490, 490, 1882, 1088, 1116, 490, - 2915, 490, 2916, 1882, 2913, 2282, 490, 490, 490, 490, - 617, 2372, 487, 1989, 2452, 37, 2950, 1089, 2486, 2487, - -1873, 490, 490, 1110, 619, 611, 490, -1852, -1852, 38, - 611, 490, 1095, 611, 490, 617, -1873, 487, -1853, -1853, - 617, -1873, 487, 617, 1113, 487, 1117, 27, 1313, 619, - 1112, 490, 1118, 490, 619, 1114, 2934, 619, 950, 1882, - 808, 490, 1322, 2914, 979, 679, 1126, 1807, 1883, 1884, - 2158, 1808, 2159, 63, 1809, 1810, 1811, 2980, -1873, 1127, - 2131, 490, 59, 490, 32, 2266, 1887, 2267, 810, 490, - 490, 490, 490, 490, 490, 490, 1278, 1144, 1778, 2832, - 490, 490, 2950, 1145, 1117, 490, 2648, 1120, 718, 490, - 1282, 1885, 490, 490, 490, 490, 490, 490, 490, 490, - 490, 1148, 3131, 490, 3132, 35, 3009, 1286, 3030, 1882, - 490, 3031, 1198, 1534, 951, 1278, 1283, 1146, 3072, 36, - 2268, 3031, 2269, 2699, 1288, 1341, 1342, 1115, 2028, -1854, - -1854, 3096, 684, 1116, 3097, 3169, 490, 1290, 3031, 610, - 2414, 1291, 2416, 37, 610, 808, 1300, 610, 952, 694, - 2604, 697, 2606, 701, 1456, 1302, 1459, 2010, 490, 1307, - 719, 59, 1314, 1094, 953, 1096, 1311, 1072, 3176, 490, - 490, 1766, 1315, 1767, 954, -1855, -1855, -1856, -1856, 1317, - 1118, 1896, -1857, -1857, 808, 1122, -564, -564, 1897, -1858, - -1858, 1898, 1899, 1900, 1347, 1348, -1859, -1859, 1889, 1318, - 808, 810, 2950, 1423, 1423, -1873, 2012, 1278, 955, 1278, - -1861, -1861, -1862, -1862, 2372, 1949, -1863, -1863, -1864, -1864, - -1865, -1865, 1330, -1867, -1867, 1336, -1869, -1869, 1335, 808, - 1338, 1149, 1366, 1812, 1369, 1120, 808, 1115, 1118, 1117, - -1872, -1872, 2071, 1116, 914, 1697, 1698, 1372, 1198, 720, - 1373, 490, 490, 1392, 490, 1813, 1397, 2493, 1349, 1350, - 1889, 980, 1351, 1352, 1427, 1150, 2754, 808, 1115, 1440, - 808, -568, -568, 1278, 1116, 808, 59, 2895, -567, -567, - 1573, 1575, 1442, 1445, 1450, 721, 1198, 1452, 682, 2058, - 1460, 2950, 490, 1120, 1465, 956, 1453, 19, 2089, 1474, - 2708, 1466, 1475, 1477, 1351, 1352, 810, -1873, -710, 1895, - -717, 1483, 38, -590, 1541, 1542, 1543, 1544, 1545, 1546, - -591, 722, -707, 1121, -708, 1814, 1486, -711, -709, 1487, - 2730, 1507, 913, 1122, 2978, 1491, 2722, 1500, 1551, 1554, - 1556, 2860, 1582, 1571, 1583, 810, 2162, 1587, 1591, 1117, - 1098, 490, 1627, 1635, 490, 1100, 490, 1629, 1653, 1655, - 1654, 810, 490, 490, 490, 490, 490, 1660, 723, 490, - 490, 490, 490, 490, 490, 490, 490, 490, 490, 1662, - 1117, 1661, 1666, 1673, 490, 490, 1423, 1674, 490, 1700, - 810, 1122, 1678, 1118, 1996, 490, 1688, 810, 1693, 1701, - 1705, 1711, 1712, 1719, 1723, 1726, 1729, 2146, 1727, 1424, - 1731, 1732, 1738, 1745, 1747, 1755, 59, 490, 1499, 1748, - 490, 2497, 1769, 611, 490, 2796, 2869, 2870, 810, 1756, - 1759, 810, 913, 617, 1198, 487, 810, 1760, 1761, 1762, - 2063, 19, 1797, 1834, 2104, 490, 979, 619, 1120, 1807, - 2072, 1792, 2075, 1808, 1794, 2086, 1809, 1810, 1811, 1795, - 1796, 2090, 2371, 2092, 1798, 1799, 1801, 1804, 1826, 1835, - 1845, 490, 1863, 2552, 670, 2099, 490, 1842, 2105, 490, - 2102, 1889, 1870, 1875, 2107, 2108, 2109, 2110, 1878, 2114, - 2115, 1891, 1323, 1514, 1917, 27, 1922, 490, 490, 1920, - 1923, 1423, 490, 1118, 1925, 1941, 1959, 1984, 2702, 19, - 1513, 1948, 1983, 1514, 950, 1924, 490, 1515, 1960, 490, - 1962, 490, 1815, 1816, 1817, 1990, 1818, 1819, 1820, 1821, - 1822, 1823, 32, 2003, 1118, 1681, 670, 19, 2004, 2005, - 677, 490, 1128, 611, 490, 1523, 1122, 2006, 2013, 2024, - 808, 2027, -1873, 617, 2111, 487, 708, 610, 1120, 611, - 490, 1129, 1449, 2037, 2036, 2038, 2039, 619, 2040, 617, - 2057, 487, 2064, 35, 2753, 2699, 2041, 1525, 490, 1883, - 1884, 2066, 2060, 619, 63, 2065, 678, 36, 2112, 1120, - 951, 979, 2789, 2128, 1807, 490, 490, 1887, 1808, 2132, - 2136, 1809, 1810, 1811, 1386, 2148, 2145, 2147, 2210, 2149, - 2163, 37, 1130, 2642, 490, 2165, 2168, 2170, 2553, 1121, - 2176, 2643, 1885, 2169, 952, 38, 2177, 2172, 2173, 2199, - 2178, 2179, 1278, 1278, 1278, 1497, 1423, 2180, 2821, 27, - 953, 2188, 2189, 2208, 1831, 1807, 2244, 2323, 2275, 1830, - 954, 2251, 2252, 1949, 2253, 2262, 1122, 1813, 930, 1901, - 1902, 1903, 2263, 1904, 1905, 1906, 1907, 1908, 1909, 2333, - 2264, 670, 2288, 1198, 2278, 2289, 32, 610, -1873, 2644, - 2846, 2295, 2296, 2310, 955, 2315, 2331, 1122, 2336, 2322, - 2297, 2298, 59, 610, -1873, 33, 2308, 669, 2349, -1873, - 2351, 2332, 2358, 1131, 1386, 1866, 2365, 27, 2367, 2967, - 2334, 810, -570, 2335, 2378, 808, 517, 35, 2363, 2379, - 517, 2382, 490, 2381, 3126, 2383, 2385, 1814, 2388, 517, - 2387, 36, 2391, 2410, 2412, 27, -1873, 2868, 2425, 2439, - 2440, 517, 517, 2455, 32, 2441, 2431, 1111, 799, 2442, - 2432, 2433, 2451, 2450, 1132, 37, 1278, 2469, 913, 2466, - 2473, 2470, 1133, 2465, 2476, 2481, 2483, 2500, 2509, 38, - 2491, 956, 32, 2492, 1134, 2512, 2645, 2529, 2506, 2530, - 2515, 1293, 1295, 1297, 1299, 35, 2516, 2517, 2534, 2518, - 2539, 1534, 2542, 2548, 2555, 517, 914, 490, 2699, 36, - 2557, 2558, 1813, 2572, 1766, 1135, 617, 2574, 487, 2582, - 2561, 2579, 2580, 35, 2588, 2584, 808, 2597, 2599, 2603, - 619, 801, 2652, 37, 2610, 2636, 670, 36, 2729, 2738, - 2742, 488, 669, 3041, 2609, 2616, 516, 38, 2569, 2725, - 516, 3013, 2737, 3015, 621, 490, 626, 626, 629, 516, - 634, 37, 1137, 634, 490, 2719, 654, 657, 670, 1867, - 2720, 516, 516, 2721, 490, 38, 2750, 490, 2734, 490, - 2733, 2752, 1814, 2759, 1138, 2131, 810, 490, 2760, 2786, - 490, 490, 808, -1873, 2765, 490, 490, 2788, 2791, 490, - 2827, 2793, 3095, 2792, 1140, 2809, 2646, 1424, 1424, 2647, - 2816, 2833, 1424, 490, 2834, 808, 2835, 654, 2839, 2843, - 2420, 3099, 2844, 2845, 657, 516, 657, 657, 657, 490, - 2853, 2856, 3083, 2858, 1815, 1816, 1817, 2884, 1818, 1819, - 1820, 1821, 1822, 1823, 2859, 2863, -1123, -1838, -1839, 2876, - -1840, 1400, -1841, 624, -1842, -1843, 2877, -1844, -1845, -1846, - -1847, 808, -1848, -1849, 2886, 2446, -1850, -1852, 2875, -1853, - 2702, 2890, 2472, -1854, 2904, -1855, -1856, -1857, -1858, 2905, - -1859, 2459, 1278, 3041, 2891, 2908, 1278, 2706, 1278, 2907, - -1861, -1862, -1863, 2911, 2917, -1873, -1864, 1497, -1865, 1417, - -1866, 799, 1541, 1542, 1543, 1544, 1545, 1546, -1867, -1868, - -1869, -1870, -1871, 1655, -1872, 2918, 2621, 2929, -1124, 2933, - 2921, 2923, 2622, 2946, 2952, 2955, 2925, 2954, 2944, 1497, - 1713, 1714, 1716, 2957, 1717, 2623, 2969, 2970, 2977, 2979, - 1386, 1988, 2985, 2986, 2987, 2498, 3000, 2499, 3010, 3001, - 3011, 2504, 2505, 810, 3014, 808, 3017, 3018, 3020, 1339, - 1340, 3023, 3027, 3032, 2624, 3046, 2625, 2852, 3050, 3052, - 3053, 3056, 3062, 490, 801, 3067, 810, 3068, 2727, 1815, - 1816, 1817, 3069, 1818, 1819, 1820, 1821, 1822, 1823, 3073, - 3075, 1424, 808, 490, 490, 3077, 2812, 3080, 3082, 3098, - 3090, 490, 3094, 2746, 3101, 3106, 2748, 3112, 3113, 3114, - 3139, 3118, 490, 3119, 3122, 3142, 490, 490, 3120, 3144, - 3124, 490, 810, 3140, 3156, 3141, 490, 3171, 3178, 490, - 490, 3182, 1087, 2651, 490, 1341, 1342, 611, 490, 2091, - 2655, 2408, 2823, 3089, 2945, 3133, 490, 617, 59, 487, - 2866, 2626, 3110, 3167, 2592, 2736, 2965, 3138, 3145, 1590, - 3161, 619, 1644, 808, 2999, 2390, 2415, 3135, 3143, 2620, - 2741, 2386, 2656, 59, 3134, -1594, 59, 1763, 1741, 1710, - 490, 2448, 2494, 2912, 1636, 2724, 1584, 1447, 490, 799, - 1448, 2370, 2056, 2702, 2601, 2520, 1623, 1663, 1624, 3125, - 1343, 1344, 1345, 1346, 1347, 1348, 2380, 490, 1349, 1350, - 2033, 2820, 2822, 3076, 3016, 2055, 810, 612, 1687, 2627, - 1628, 2653, 2348, 1458, 2628, 1413, 2280, 925, 517, 2514, - 941, 2513, 2971, 2533, 1401, 1754, 2709, 2710, 2711, 2712, - 2713, 2714, 2715, 2716, 2717, 2718, 3078, 2306, 1403, 1407, - 3079, 3155, 2329, 2706, 2373, 2127, 2292, 517, 517, 2704, - 2327, 2347, 801, 1854, 2819, 2454, 3071, 2629, 1408, 1999, - -1594, 610, 1771, 2286, 2593, 2001, 637, 692, 808, 0, - 0, 59, 59, 2630, 2446, 0, 0, 0, 0, 0, - 0, 0, 0, 490, 0, 1424, 1424, 1424, 1424, 1424, - 0, 0, 1424, 1424, 1424, 1424, 1424, 1424, 1424, 1424, - 1424, 1424, 670, 0, 1351, 1352, 0, 0, 0, 0, - 913, 0, -1594, 490, 810, 0, 0, 0, 0, 0, - 0, 657, 0, 0, 0, 715, -1594, 0, 716, 0, - 490, -1594, 0, 0, 0, 0, -1594, 799, 516, 0, - 0, 0, 0, 0, 0, -1594, 490, 0, 0, -1594, - 0, 1722, 0, 979, 0, 2896, 1807, 490, 490, 0, - 1808, 490, 0, 1809, 1810, 1811, 716, 516, 516, 517, - 0, 2631, 0, 0, 0, 0, 0, 0, 2632, 490, - -1594, 490, 979, 0, 0, 1807, 0, 802, 617, 1808, - 487, 0, 1809, 1810, 1811, 1115, 0, 0, 0, 490, - -1594, 1116, 619, 0, 0, 2818, 0, 626, 1128, 2803, - 801, 0, 0, 0, 0, 0, 0, 1353, 1354, 488, - 1424, 1424, 0, 657, 2847, 59, 0, 1129, 0, 2706, - 0, 0, 0, 0, 621, 945, 945, 0, 0, 0, - 945, 962, 0, 0, 0, 0, 0, 0, 0, -1594, - 0, 0, -1594, 0, 0, 0, 0, 0, -1594, 0, - 0, 490, 0, 1497, 0, 490, 1053, 1053, 634, 634, - 0, 634, 0, 0, 617, 490, 487, 490, 1130, 490, - 0, 0, 0, 490, 657, 0, 0, 490, 619, 516, - 0, 808, -1594, 0, 0, 0, 0, 0, 490, 799, - 657, 490, 0, 2982, 2983, 0, 0, 1117, 0, 0, - 1862, 1278, 657, 0, 0, -1594, 490, 0, 0, 0, - 497, 0, 0, 0, 0, 979, 799, 799, 1807, 0, - 0, 0, 1808, 0, 0, -1873, -1873, -1873, 0, 0, - 804, 0, 799, -1172, 0, 0, 657, 657, 657, 657, + 501, 497, 693, 704, 53, 58, 73, 91, 1181, 947, + 1117, 63, 1319, 1147, 501, 640, 1433, 1480, 1373, 1734, + 1323, 1326, 1440, 975, 1796, 1972, 1744, 1733, 593, 498, + 1330, 1612, 1698, 1379, 2458, 1638, 1453, 706, 2403, 2052, + 1747, 2406, 707, 498, 674, 1455, 1803, 48, 61, 83, + 2428, 1709, 1705, 2433, 1807, 68, 642, 1939, 678, 2082, + 1687, 845, 2085, 981, 828, 854, 840, 1457, 996, 941, + 1180, 1002, 1186, 68, 1190, 1085, 1456, 1609, 2798, 847, + 1738, 45, 46, 831, 1615, 1990, 1991, 1523, 1891, 47, + 50, 51, 54, 1417, 55, 1420, 2796, 56, 1828, 59, + 714, 60, 62, 1550, 71, 72, 1103, 74, 64, 691, + 75, 80, 2387, 2451, 2810, 81, 2813, 82, 87, 88, + 90, 92, 650, 722, 2421, 948, 64, 515, -476, 633, + 634, 2776, 2774, 2494, 2495, 2496, 2608, 2057, -479, 1359, + 1360, 64, -1148, 1869, 1652, 2199, 1140, 1870, 515, 692, + -1145, -1145, -767, 1797, -767, 512, 1143, -1123, 1129, -1883, + -1883, 2105, -1148, -764, -1733, -1740, -759, -764, -1749, 1619, + -1734, 1371, -1886, -1886, -1735, 1423, 705, -1736, -1887, -1887, + -1737, 2506, -1888, -1888, -1758, -1889, -1889, -1740, -1890, -1890, + 1016, -1749, -1149, 2521, -1756, -1893, -1893, 64, 2955, -1902, + -1902, -1758, -1909, -1909, 2312, -1913, -1913, 2108, -1760, -1911, + -1911, -1149, 2514, -1733, 2973, -1734, -1914, -1914, 515, -1146, + -1146, -1735, 1016, -476, 1427, 2004, 1381, -1736, -1737, 1016, + 1381, -1756, -1760, -479, -726, -739, -754, 515, 515, 1718, + 761, -996, 1721, 1722, 2004, 994, 1099, 2041, -996, 1616, + 1427, 515, 683, 2007, 2042, 1016, 3031, 3217, 2910, 21, + 1379, 2563, 2565, 3020, 2568, 1566, 2528, 2323, 1106, 1567, + 1016, 701, 2355, 2969, 1381, 1710, 1745, 21, 1447, 1015, + 1658, 2925, 1869, 2192, 1381, 3044, 1870, 1800, 1746, 1871, + 1872, 1873, 1323, 21, 1710, 701, 2970, 1575, 3, 4, + 2886, -434, -588, 2888, 3130, -1016, 2616, 3164, 3174, 1658, + 2321, 2971, -1016, 2585, 3104, 2180, 1641, 2324, 1690, 840, + 2639, 2049, 2111, 2642, 1701, 604, 1659, 2993, 3147, 1577, + 2944, 2676, 1765, 1701, -199, 1736, 831, 1136, 536, -199, + 3073, 3012, 1353, 3014, 2486, 3145, 1015, 2814, 3074, 1869, + 3252, 2705, 2675, 1870, 2921, 1659, 1871, 1872, 1873, 1136, + 2126, 3259, 2640, 1617, 3199, 1363, 2454, 3059, 515, 2126, + 2963, 1717, 2574, 696, 1500, 1475, 1566, 101, 1546, 1506, + 3100, 2975, 3101, 2649, 947, 3186, 1354, 1372, 3189, 996, + 1359, 1360, 2964, 1323, 1732, 603, -699, 986, 2286, 1723, + 2666, 2604, 2157, 981, 2959, 1371, 2293, 2160, 2943, -1882, + -1882, 1138, 982, 1739, 646, -476, 1660, 1693, 2127, 2650, + 680, 1655, 1415, 2706, 2820, -479, 2358, 2448, 2313, 833, + 2112, 987, 2451, 1138, 2451, 1107, 1661, 1108, 3225, 686, + 1577, 3175, 3247, 947, 1441, 537, 3087, 1508, 2641, -609, + 661, 2605, 1767, 694, 2325, 3149, 1952, 989, 29, 1566, + 1139, 697, 795, 1567, 2050, 1661, 605, 1869, 528, 1711, + 1642, 1870, 2181, 1686, 3165, 3245, 29, 3021, 2348, -476, + 647, 647, 1708, 1749, 1618, 3224, 3026, 1558, 1711, -479, + 1875, 1575, 29, 1100, 2972, 34, 1662, 2322, 2991, 3042, + 1869, 3253, 2837, 2455, 1870, 3036, 2707, 1943, 2815, 3213, + 1972, 840, 2922, 34, 3129, 1538, 1382, 3075, 1614, 3176, + 1382, 3260, 2575, 1577, 731, 1662, 2405, 1656, 831, 34, + 2193, 693, 1708, -699, 695, 1874, 3188, 38, 762, 947, + 947, 1724, 3051, 1750, 708, 1614, 2294, 983, 2828, 1725, + 2818, 1708, 3239, 662, 842, 38, 2295, 1875, 2179, 725, + 1876, 1355, 955, 946, 1382, 1101, 1463, 709, 3032, 2121, + 1695, 38, 2431, 2901, 1382, 3218, 1369, 1370, 1010, 992, + 943, 684, 2408, 2105, 2911, 39, 1640, 2005, 2524, 41, + 1684, -476, 1953, 693, 2776, 2774, 2572, 3187, 2423, -996, + 1685, -479, 2232, 1620, 513, 2043, 2389, 41, 1363, 40, + 501, 640, 1374, 1357, 1374, 3128, 2335, 2336, 2337, 1734, + 2950, 64, 1372, 41, 68, 501, 640, 1876, 2436, 1885, + -476, 1787, -476, 1319, 1375, 3002, 1375, 1956, -1148, 498, + -479, 3135, -479, 1148, 706, 3134, 1633, 1534, 1376, 707, + 1378, 727, 642, -1123, 498, 728, 501, 501, -1148, -764, + -1733, -1740, -759, -1016, -1749, 1737, -1734, 642, 2506, 1356, + -1735, 1383, 840, -1736, 2487, 1348, -1737, 64, 692, 501, + -1758, 2248, 833, -1740, 1696, 1546, 2280, -1749, -1149, 831, + -1756, 698, 2055, 972, 1110, 1130, 2967, -1758, 1710, 53, + 58, 73, 91, 952, -1760, 1104, 63, -1149, 3194, -1733, + 2898, -1734, 1431, 1432, 1561, 1330, 2796, -1735, 1109, 1240, + 501, 1320, 1104, -1736, -1737, 959, 1838, -1756, -1760, 1419, + 1361, 1365, -754, 1610, 2058, 2025, 1804, 1805, 1431, 1432, + 973, 974, 48, 61, 83, 2968, 3250, 2907, 515, 2948, + 68, 1598, 2179, 2934, 2935, 2900, 1119, 2502, 2503, 1877, + 1878, 1879, 3240, 1880, 1881, 1882, 1883, 1884, 1885, 727, + 2964, 1004, 2079, 728, 2919, 2663, 45, 46, 726, 3111, + 3266, 2953, 1005, 705, 47, 50, 51, 54, 735, 55, + 736, 2156, 56, 1728, 59, 93, 60, 62, 1131, 71, + 72, 2159, 74, 64, 2162, 75, 80, 842, 1900, 3029, + 81, 3261, 82, 87, 88, 90, 92, 1729, 2776, 2774, + 2908, 2320, -199, -199, -1880, -1880, 1877, 1878, 1879, 2013, + 1880, 1881, 1882, 1883, 1884, 1885, 1777, 2679, 840, 3112, + 2664, 94, 3241, 21, 501, 1795, 2459, 2920, 1323, 1972, + 1497, 1728, 2320, 1951, 1546, 831, 2014, 2462, 2001, 2080, + 739, 2026, 1976, 1513, 1566, 947, 1516, 699, 1567, 3242, + 828, 2228, 840, 840, 833, 1729, 2685, 2027, 2689, 1475, + 1475, 1710, 2028, 1988, 1475, 2718, 1814, 2414, 840, 831, + 831, 2363, 1711, 2045, 1927, 2614, 1575, 1319, 2252, 1931, + 2686, 1933, 2045, 1934, 1323, 831, 3043, 2329, 2253, 2267, + 1915, 1832, 1374, 1798, 1824, 2269, 1016, 1891, 2546, 2029, + 1906, 1830, 2680, 2482, 2550, 941, 2692, 2552, 1577, 3107, + 2255, 2257, 2258, 1825, 1375, 700, 2483, 2555, 946, 2254, + 2256, 21, 1595, 1596, 1597, 1598, 501, 501, 1880, 1881, + 1882, 1883, 1884, 1885, 751, 1708, 501, 3060, 2460, 501, + 501, 1710, 501, 501, 501, 501, 3205, 1329, 21, 2015, + 2431, 2409, 3017, 96, 2016, 1558, 501, 640, 1701, 2017, + 1701, 501, 640, 1882, 1883, 1884, 1885, 2497, 2681, 1702, + 2682, 1704, 2148, 1734, 2927, 3206, 743, 946, 1240, 842, + 1742, 2274, 2932, 68, 2155, 498, 2275, 1834, 3061, 758, + 498, 2379, 1016, 701, 2051, 501, 693, 3062, 642, 2425, + 737, 760, 738, 642, 3124, 1566, 2586, 2587, 2588, 2589, + 759, 1798, 501, 727, 517, 833, 763, 728, 2380, 2118, + 1397, 1398, 29, 501, 501, 501, 3063, 501, 501, 764, + 2236, 727, 2175, 2176, 2177, 1613, 64, 1575, 2276, 2488, + 949, 2204, 647, 2623, 765, 1475, 2154, 2030, 851, 1992, + 2415, 840, 2259, 2260, 501, 1711, 2262, 953, 1154, 34, + 2485, 3034, 1319, 954, 1155, 2165, 2696, 955, 831, 1577, + 2172, 633, 634, 946, 946, 518, 633, 634, 1550, 1154, + 956, 1645, 1646, 1003, 1653, 1155, 707, 707, 1136, 707, + 2529, 2273, 1157, 1137, 957, 2277, 2537, 3064, 2279, 2833, + 1710, 38, 2018, 2233, 1096, 958, 1531, 501, 1710, 3065, + 2697, 501, 501, 2019, 744, 39, 97, 1535, 1708, 985, + 29, 3257, 501, 1530, 98, 41, 2698, 3209, 3159, 3160, + 1104, 1401, 1402, 1972, 702, 1711, 2381, 2434, 961, 40, + 842, 2382, 1016, 1548, 1908, 744, 1374, 29, 2461, 1909, + 2462, 517, 1425, 41, -531, 1426, 2896, 34, 3226, -531, + 99, 2899, 1138, 1899, 962, 1901, 1902, 1240, 1375, 727, + 1156, -1123, 963, 728, 1154, 3248, 3249, 3201, 2463, 1240, + 1155, 833, 1376, 2130, 34, 840, 745, 1735, 966, 1094, + 1095, 1156, 1097, 1631, 967, 986, 1632, 1154, 1708, 38, + 968, 3256, 831, 1155, 1240, 999, 1942, 2318, 100, 1943, + 3265, 1139, 518, 39, 1001, 833, 833, 745, 969, 2489, + 705, 705, 970, 705, 2699, 3264, 38, 2493, -531, 987, + 1944, 833, 2700, 1945, 2832, 2189, 2596, 40, 2190, 2237, + 39, 2243, 1945, 2246, 2244, 988, 2244, 971, 521, 746, + 522, 2416, 1008, 2263, 2860, 989, 2264, 947, 1475, 1475, + 1475, 1475, 1475, 972, 40, 1475, 1475, 1475, 1475, 1475, + 1475, 1475, 1475, 1475, 1475, 525, 746, -531, 41, 1507, + 2871, 2716, 1511, 1006, 2383, 747, 1156, -1881, -1881, 990, + 2709, 1154, 1011, 1154, 1711, 2384, 2245, 1155, 840, 1155, + 1009, 3066, 1711, 2343, 3067, 2673, 842, 1765, 2306, 1156, + 1928, 2307, 747, 1010, 2377, 831, 1771, 1772, 1774, 1775, + 1098, 2517, 1320, 2559, 1157, 1593, 1594, 1595, 1596, 1597, + 1598, 1102, 2792, 2708, 501, 2717, 2281, 991, 840, 1374, + 842, 842, 2404, 1113, 2345, 1157, 2916, 2346, 748, 2218, + 1120, 2219, 2287, 1154, 840, 831, 842, 1708, 1121, 1155, + 947, 1375, 2470, 2349, 2472, 1708, 2346, 2476, 1126, 749, + 2477, 831, 2330, 1123, 2331, 1378, 1158, 992, 1124, 1766, + 1159, 2314, 1436, 840, 1127, 521, 2480, 522, 2319, 2481, + 840, 1134, 1550, 1475, 1475, 1462, 749, 1184, 1149, 946, + 831, 1159, 2332, 1156, 2333, 1156, 2540, 831, 2600, 1943, + 1160, 2346, 525, 2431, 833, 1320, 943, 2473, 1151, 2475, + 2347, 501, 840, 2347, 1152, 840, 2052, 1767, 2351, 1153, + 840, 1185, 1165, 2658, 2548, 2549, 2659, -1884, -1884, 831, + 1157, 1436, 831, 834, 501, 501, 2672, 831, 2674, 501, + 2805, 501, 640, 2190, -1885, -1885, 501, 501, 501, 501, + 68, 2826, 1166, 1157, 2827, 1156, 1929, 2834, 1183, 2513, + 2835, 501, 501, -1891, -1891, 2872, 501, 640, 1945, 1161, + 498, 501, 640, 501, 640, 501, 640, 2892, 2986, 2985, + 2893, 1945, 1188, 642, 103, 1187, 1159, 511, 2987, 1560, + 1161, 2346, 501, 501, 566, 498, 3005, 1191, 1563, 1945, + 498, 501, 498, 64, 498, 2117, 660, 1948, 642, 1159, + 673, -1892, -1892, 642, 1611, 642, 1189, 642, 1838, 2902, + -1894, -1894, 501, 2768, 501, 1621, 2716, 1436, 1436, 842, + 501, 501, 501, 501, 501, 501, 501, 1320, 833, 1160, + 1324, 501, 501, 1946, 1947, 1950, 501, 1157, 1325, 1157, + 501, 68, 517, 501, 501, 501, 501, 501, 501, 501, + 501, 501, 3082, 3050, 501, 2894, 2190, 3084, 1327, 3143, + 1945, 501, 3144, 1240, 3163, -1195, 1320, 3144, 3227, 1328, + 3228, 633, 634, -1895, -1895, 1161, 633, 634, 633, 634, + 633, 634, 1133, 2087, 1135, 2221, 2949, 501, 707, 2163, + 1331, 3082, 1333, 1159, 64, 1159, -1896, -1896, 1161, 1157, + -488, 699, 1110, 518, 3167, 21, 3246, 3168, 1345, 3144, + 501, -1897, -1897, 1335, -488, -532, 1347, 2431, 3262, -488, + -532, 501, 501, 2164, 1348, 1160, 515, -1898, -1898, -1899, + -1899, -1900, -1900, -1901, -1901, -1903, -1903, -1904, -1904, -1905, + -1905, 833, -1906, -1906, -1907, -1907, -1908, -1908, 2011, -1910, + -1910, 2170, 1349, 842, 536, 1159, 1352, 853, 1357, 1320, + 1361, 1320, -1912, -1912, 1364, 947, 1365, 1015, -488, 700, + 1869, -1915, -1915, 1367, 1870, 2045, 834, -1916, -1916, -1916, + 2130, 833, 840, 1752, 1753, 2171, 2106, 2107, -488, -532, + 1416, 1167, 1161, 1368, 1161, -583, -583, 833, 1380, 831, + 1401, 1402, 1240, 1399, 1400, 501, 501, 1418, 501, 1385, + 1168, -587, -587, 1386, 3082, 1388, 533, -586, -586, 2965, + 1422, 567, 705, 1625, 1627, 2148, 833, 2777, 520, 1421, + 652, 516, 1424, 833, 1442, 1445, 1448, -488, -532, 21, + 2930, 1167, 1240, 690, 690, 1763, -488, 701, 1016, 1491, + 1478, 1320, 501, 1493, 1161, 1503, 2222, 1475, 1475, 3048, + 1168, 1169, 3082, 2825, 2791, 833, 842, 2800, 833, 1496, + 1501, 1504, 1510, 833, 1512, 1517, 521, 1518, 522, 1526, + 1527, 3196, 3198, 3198, 1529, 2816, -730, -737, 1534, 41, + -609, 946, -610, -727, 523, -728, 1537, -731, 517, 1538, + 524, 718, -729, 525, 29, 1542, 842, 1551, 1552, 1604, + 1559, 1169, 501, 1606, 1623, 501, 1608, 501, 1634, 1643, + 1139, -1195, 842, 501, 501, 501, 501, 501, 2712, 1635, + 501, 501, 501, 501, 501, 501, 501, 501, 501, 501, + 1639, 34, 3126, 1644, 2206, 501, 501, 1391, 1392, 501, + 840, 842, 1170, 64, 1137, 1550, 501, 1680, 842, 518, + 1682, 3198, 1852, 1688, 2559, 1706, 1707, 831, 834, 1708, + 1715, 1713, 1714, 1719, 1726, 1727, 1731, 1741, 501, 1748, + 21, 501, 1755, 38, 1762, 501, 640, -488, 702, 1756, + 842, 1760, 1769, 842, 946, 1770, 1240, 39, 842, 1779, + 1782, 1783, 1170, 1171, 1785, 1798, 501, 1786, 1789, 1788, + 1799, 1172, 1806, 519, 498, 1808, 1397, 1398, 1809, 1816, + 1829, 40, 1373, 1173, 1817, 1820, 1821, 642, 1822, 2939, + 2940, 693, 501, 1854, 1823, 41, 1859, 501, 29, 1856, + 501, 1475, 1925, 1857, 1858, 2771, 1860, 840, 1876, 1861, + 1896, 1957, 727, 1171, 1174, 1123, 728, 1863, 501, 501, + 1958, 1172, 1866, 501, 831, 1888, 1907, 1959, 1734, 1897, + 1960, 1961, 1962, 1173, 1904, 34, 2768, 501, 1932, 1938, + 501, 1941, 501, 1566, 520, 1953, 1979, 1867, 1868, 1500, + 1982, 1984, 1887, 2010, 1985, 1839, 1987, 1986, 2003, 2021, + 633, 634, 1176, 501, 1174, 2022, 501, 640, 2024, 2046, + 2047, 2053, 2069, 2067, 2824, 2068, 840, 38, 2066, 700, + 2086, 2097, 501, 640, 1177, 2083, 2095, 1401, 1402, 834, + 2096, 39, 521, 831, 522, 498, 501, 2059, 2098, 1948, + 1840, 840, 2418, 2099, 1179, 833, 2100, 2116, 642, 2119, + 523, 498, 1176, 501, 501, 40, 524, 2123, 831, 525, + 1475, 2124, 2125, 701, 642, 2191, 1841, 2196, 2187, 41, + 2197, 2205, 501, 2207, 1177, 1946, 1947, 1950, 1548, 29, + 2208, 2209, 2223, 68, 1842, 2226, 2224, 840, 1843, 2229, + 1320, 1320, 1320, 2230, 1179, 2231, 2011, 2234, 2235, 2238, + 2261, 2239, 2270, 2240, 831, 2241, 2242, 2250, 2251, 2278, + 1844, 1893, 2396, 1845, 1869, 2308, 34, 1892, 2339, 2378, + 2394, 633, 634, 2399, 2412, 2419, 693, 2315, 1846, -589, + 2426, 1240, 2437, 2438, 2316, 35, 64, 633, 634, 64, + 2317, 2326, 2361, 2327, 2045, 2328, 2342, -1916, -1916, -1916, + 2352, 1880, 1881, 1882, 1883, 1884, 1885, 985, 38, 2373, + 2422, 499, 508, 2353, 2359, 3204, 534, 2360, 2362, 2371, + 842, 534, 39, 3037, 2385, 644, 2424, 648, 648, 651, + 534, 656, 501, 2938, 656, 840, 2395, 676, 679, 2440, + 679, 2397, 2441, 534, 534, 834, 40, 2398, 1475, 2444, + 2768, 2446, 831, 2442, 2447, 3214, 2450, 2469, 2471, 2484, + 41, 2490, 2491, 833, 2492, 836, 2498, 1320, 2499, 946, + 1847, 2500, 2511, 840, 2501, 2508, 947, 2512, 1848, 834, + 834, 2516, 2526, 986, 2531, 2530, 753, 2534, 2538, 517, + 831, 2430, 2527, 676, 1167, 834, 2543, 2545, 2553, 1849, + 679, 534, 679, 679, 679, 1436, 2562, 2570, 2554, 2272, + 501, 640, -1195, 1168, 2573, 2576, 2593, 987, 2579, 850, + 2580, 3110, 1850, 692, 2581, 2582, 3088, 2598, 3090, 2594, + 2603, 2606, 2612, 988, 2689, 693, 2619, 2621, 2622, 498, + 2690, 2636, 2646, 989, 2633, 2648, 840, 2625, 2655, 2671, + 518, 2667, 642, 2691, 2638, 2643, 2677, 2704, 501, 2644, + 833, 2665, 2684, 831, 1169, 2795, 693, 501, 2678, 2720, + 2799, 1474, 2788, 2808, 2789, 2790, 501, 990, 2803, 501, + 2804, 501, 2692, 2807, 2693, 2812, 2821, 693, 842, 501, + 2190, 2830, 501, 501, 2831, 2823, 2857, 501, 501, 2836, + 2891, 501, 2859, 2862, 2203, 3166, 2864, 2863, 1436, 2880, + 2887, 2895, 2897, 3170, 2903, 501, 3158, 2904, 2905, 2909, + 2913, 2914, 2915, 2923, 2926, 991, 2928, 501, 2929, 833, + -1145, 2933, -1880, -1881, -1882, -1883, 2288, 2289, 2290, 2291, + 2292, 690, -1884, 2296, 2297, 2298, 2299, 2300, 2301, 2302, + 2303, 2304, 2305, -1885, 833, 1170, 1015, -1886, 2771, 1869, + 840, -1887, 3110, 1870, -1888, 992, 1871, 1872, 1873, 2694, + -1889, -1890, -1891, -1892, -1894, -1895, -1896, 831, 834, -1897, + 1320, 2956, 1548, 2617, 1320, 2775, 1320, -1898, -1899, -1900, + 1963, 1964, 1965, 2945, 1966, 1967, 1968, 1969, 1970, 1971, + 833, 2946, 2947, 2960, 2974, 2976, 1171, -1901, -1903, -1904, + -1905, -1906, -1907, 1548, 1172, -1908, -1909, -1910, 836, -1911, + -1912, 2961, -1913, 521, -1914, 522, 1173, -1915, -1146, 1771, + 1772, 1774, 1775, 2797, 692, 2954, 2978, 2695, 2979, 2982, + 2988, 2992, 2696, 1673, 2989, 3004, 2994, 524, 2996, 3000, + 525, 3015, 3024, 3025, 842, 3027, 3039, 1174, 3040, 2817, + 3047, 3049, 2819, 3055, 3056, 3070, 3057, 3071, 3072, 3085, + 3086, 2374, 2375, 3089, 3093, 3092, 501, 3095, 3098, 842, + 3103, 3115, 3105, 2922, 3119, 3121, 2697, 3125, 3131, 3122, + 3137, 3138, 3139, 3148, 3145, 3150, 501, 501, 833, 3152, + 2883, 3155, 2698, 3157, 501, 1176, 3169, 3161, 3172, 3177, + 2479, 3184, 834, 3183, 3185, 501, 3190, 3191, 3192, 501, + 501, 3200, 3202, 3210, 501, 842, 3216, 1177, 3236, 501, + 64, 3219, 501, 501, 3221, 3217, 833, 501, 3218, 3251, + 3258, 501, 640, 3263, 1125, 2719, 837, 1179, 2467, 501, + 3019, 2150, 3102, 2660, 2723, 2505, 64, 3237, 3195, 64, + 2936, 2806, 3181, 2509, 3244, 3035, 3215, 1875, 3222, 3238, + 498, 3069, 2520, 1697, 2449, 2474, 3220, 2811, 3212, 2724, + 2445, 2688, 2771, 642, 840, 3211, 1802, 501, 2507, 2556, + 1768, 2983, 1636, 1498, 2429, 501, 2115, 2793, 1677, 2584, + 2699, 831, 3203, 1499, 2092, 2439, 2114, 3151, 2700, 833, + 836, 3091, 1681, 635, 501, 1464, 1676, 2411, 679, 1509, + 679, 976, 2344, 842, 679, 834, 960, 679, 2578, 2577, + 2597, 3041, 1815, 1436, 1452, 1454, 534, 1876, 2560, 1458, + 2561, 756, 3153, 1459, 2566, 3154, 2569, 2369, 2392, 3235, + 2432, 2356, 2186, 1916, 2390, 2410, 633, 634, 2515, 3141, + 951, 2775, 2062, 2350, 682, 834, 2661, 756, 534, 534, + 1831, 2064, 2890, 1351, 659, 715, 0, 0, 0, 0, + 0, 834, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2892, 0, 0, 0, 1813, -469, 0, 0, 490, 1131, - 0, 658, 801, 59, 59, 0, 0, 0, 0, -469, - 0, 498, 1386, 0, -469, 490, 0, 0, 0, 0, - 0, 0, 0, 1813, 617, -1596, 487, 0, -1594, 801, - 801, 0, 0, 3064, 0, 0, -1594, 490, 619, 0, - 0, 0, 0, 0, 0, 801, 0, 0, 0, 0, - 1132, 0, 3070, -1594, 0, -1594, -1594, 0, 1133, 0, - 802, 0, 0, -469, 1814, 499, 490, 0, 0, 1998, - 1134, 2000, 2942, 0, 3086, 0, 0, 1441, 0, 0, - 0, 1278, 2706, -469, 805, 0, 0, 2968, 0, 0, - 0, 1118, -1594, 1814, 1463, -1594, -1594, -1594, 0, 0, - 0, 1135, 0, 59, 490, 0, 0, 2975, 2976, 0, - 0, 490, 490, 617, 0, 487, 0, 0, 0, 2051, - -1596, 0, 59, 0, 0, 0, 2988, 619, 0, 0, - 0, 2704, -469, 490, 0, 500, 0, 0, 0, 0, - 0, -469, 1136, 0, 59, 1128, 1120, 0, 1137, 0, - 0, 0, 0, 799, 0, 0, 0, 1505, 0, 0, - 3146, 0, 0, 0, 1129, 0, 490, 0, 0, 0, - 1138, 0, -1596, 0, 0, 0, 1139, 3028, 0, 945, - 962, 0, 0, 501, 657, 502, -1596, 0, 0, 0, - 1140, -1596, 0, 945, 945, 0, -1596, 516, 2137, 2139, - 2140, 503, 0, 621, 0, -1596, 0, 504, 621, -1596, - 505, 0, 0, 804, 516, 1130, 0, 517, 517, 0, - 0, 0, 0, 0, 0, 0, 801, 0, 0, 1476, - 59, 0, 0, 1424, 1424, 3058, 1814, 0, 807, 0, - -1596, 0, 0, 0, 1122, 0, 0, 0, 802, 0, + 0, 0, 501, 0, 0, 0, 0, 950, 508, 648, + 834, 0, 0, 0, 0, 0, 0, 834, 693, 0, + 0, 499, 0, 833, 717, 679, 720, 0, 724, 2966, + 946, 0, 0, 501, 842, 0, 644, 980, 980, 0, + 0, 0, 980, 998, 0, 0, 0, 0, 0, 834, + 501, 0, 834, 0, 0, 0, 0, 834, 0, 0, + 0, 0, 0, 0, 0, 0, 501, 1091, 1091, 656, + 656, 836, 656, 0, 690, 1474, 1474, 501, 501, 0, + 1474, 501, 0, 0, 0, 679, 0, 0, 0, 0, + 0, 534, 0, 0, 0, 0, 0, 0, 0, 837, + 501, 0, 679, 0, 1451, 0, 515, 0, 0, 0, + 0, 0, 3016, 3018, 679, 0, 0, 839, 501, 0, + 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1877, 1878, 1879, 0, + 1880, 1881, 1882, 1883, 1884, 1885, 0, 679, 2775, 2773, + 0, 679, 679, 679, 679, 2627, 2628, 0, 0, 0, + 0, 0, 0, 0, 0, 1548, 0, 0, 0, 0, + 0, 0, 0, 0, 2505, 2794, 0, 3052, 3053, 0, + 0, 501, 0, 0, 0, 501, 640, 0, 0, 0, + 0, 0, 0, 0, 0, 501, 0, 501, 0, 501, + 0, 0, 0, 501, 0, 0, 0, 501, 0, 64, + 64, 0, 1389, 1390, 498, 0, 0, 0, 501, 0, + 0, 0, 0, 0, 501, 640, 0, 642, 0, 0, + 1320, 0, 0, 0, 0, 501, 0, 836, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 833, 0, 0, + 0, 0, 0, 498, 0, 0, 0, 0, 0, 0, + 0, 2094, 0, 0, 0, 0, 642, 0, 0, 0, + 0, 836, 836, 0, 64, 64, 0, 3133, 0, 0, + 0, 0, 501, 0, 0, 0, 0, 836, 1391, 1392, + 0, 837, 501, 3136, 535, 0, 0, 3140, 0, 535, + 0, 0, 0, 0, 0, 0, 0, 0, 535, 0, + 2889, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 535, 535, 0, 0, 501, 0, 0, 0, 834, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 2829, + 0, 0, 0, 0, 0, 0, 0, 501, 640, 0, + 0, 0, 0, 1393, 1394, 1395, 1396, 1397, 1398, 0, + 501, 1399, 1400, 980, 998, 0, 0, 0, 679, 0, + 839, 1320, 2775, 1826, 64, 1827, 498, 980, 980, 535, + 0, 534, 3208, 0, 0, 0, 0, 644, 0, 642, + 64, 0, 644, 0, 64, 501, 640, 0, 0, 534, + 0, 0, 0, 0, 0, 3223, 0, 0, 501, 501, + 0, 0, 0, 0, 1528, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 498, 0, 0, 0, 0, 0, + 0, 0, 501, 0, 0, 0, 0, 642, 0, 0, + 0, 0, 732, 0, 734, 0, 0, 0, 741, 0, + 0, 742, 837, 0, 0, 0, 0, 0, 2918, 0, + 0, 0, 0, 534, 0, 0, 501, 0, 1401, 1402, + 836, 2962, 0, 0, 1474, 1474, 1474, 1474, 1474, 64, + 0, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, + 1474, 0, 0, 0, 1436, 0, 0, 834, 0, 0, + 0, 0, 64, 0, 0, 0, 1628, 0, 1630, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - -1596, 1815, 1816, 1817, 0, 1818, 1819, 1820, 1821, 1822, - 1823, 0, 0, 979, 0, 0, 1807, 516, 0, 0, - 1808, -469, 2644, 1809, 1810, 1811, 799, 0, 0, 0, - 1815, 1816, 1817, 0, 1818, 1819, 1820, 1821, 1822, 1823, - 2804, 0, 0, 0, 0, 0, 1131, 0, 0, -1596, - 0, 0, -1596, 0, 0, 0, 0, 0, -1596, 1576, - 0, 1578, 0, 0, 0, 0, 0, 805, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 516, 516, 0, - 0, 0, 0, 657, 657, 703, 0, 2270, 1085, 704, - 0, 0, -1596, 0, 2704, 1513, 0, 1132, 1514, 801, - 0, 0, 1515, 0, 0, 1133, 0, 0, 1115, 657, - 1647, 0, 0, 0, 1116, -1596, 0, 1134, 0, 0, - 0, 1128, 657, 0, 0, 0, 1128, 0, 0, 0, - 1523, 799, 0, 0, 0, 0, 0, -1873, 0, 657, - 1129, 804, 0, 657, 0, 1129, 802, 0, 1135, 0, - 0, 0, 0, 0, 0, 0, 1424, 0, 0, 0, - 0, 0, 1525, 0, 0, 0, 0, 0, 0, 0, - 799, 658, 0, -1873, -1873, -1873, 0, 1818, 1819, 1820, - 1821, 1822, 1823, 0, 0, 0, 799, 0, 0, 0, - 0, 1130, 0, 0, 0, 1137, 1130, 0, -1596, 0, - 0, 0, 0, 0, 801, 0, -1596, 0, 0, 0, - 0, 0, 0, 0, 0, 799, 0, 1138, 0, 0, - 1117, 807, 799, -1596, 1813, -1596, -1596, 0, 0, 0, - 0, 0, 2562, 0, 0, 0, 0, 1140, 0, 0, - 0, 0, 0, 801, 517, 517, 0, 517, 0, 0, - 0, 0, 0, 799, 0, 805, 799, 0, 0, 801, - 0, 799, -1596, -1873, 0, -1596, -1596, -1596, 0, 0, - 0, 1424, 0, 0, 0, 0, 0, 0, 1704, -1873, - 0, 0, 1131, 0, -1873, 0, 657, 1131, 801, 0, - 0, 0, 0, 0, 1814, 801, 1736, 0, 0, 804, - 0, 0, 979, -1610, 0, 1807, 0, 0, 802, 1808, - 0, 0, 1809, 1810, 1811, 0, 0, 0, 0, 0, - 517, -1873, 0, 0, 0, 1752, 801, 0, 0, 801, - 1752, 0, 0, 1132, 801, 802, 802, 1874, 1132, 0, - 1877, 1133, 0, 0, 0, 0, 1133, 0, 0, 0, - 0, 802, 0, 1134, 0, 0, 0, 0, 1134, 0, - 0, 716, 716, 0, 516, 516, 2449, 516, 716, 0, - 0, 0, 0, 0, 1118, 0, 1534, 0, 2461, 2462, - 2464, 0, 0, 0, 1135, 0, 0, 0, 0, 1135, - 0, 0, 0, 0, 0, 2477, 0, 0, -1610, 0, - 2482, 0, 0, 0, 0, 0, 1424, 0, 0, 807, - 0, 0, 0, 805, 0, 0, 0, 0, 0, 0, - 0, 0, 488, 0, 0, 2093, 0, 0, 0, 1120, - 0, 1137, 0, 0, 0, 945, 1137, 1851, 0, 0, - 516, 0, 1053, 1053, 0, 657, 0, 621, 0, 0, - -1610, 0, 621, 1138, 0, 621, 0, 516, 1138, 2094, - 516, 804, 0, 0, -1610, 0, 0, 0, -1873, -1610, - 0, 0, 0, 1140, -1610, 0, 0, 0, 1140, 0, - 0, 1912, 0, -1610, 0, 0, 1916, -1610, 804, 804, - 0, 1815, 1816, 1817, 0, 1818, 1819, 1820, 1821, 1822, - 1823, 2526, 2527, 2528, 804, 0, 0, 0, 0, 0, - 0, 0, 0, -1873, 517, 0, 0, 0, -1610, 0, - 716, 0, 0, 0, 517, 0, 517, 1122, 0, 517, - 0, 0, 802, 0, 0, 517, 799, 517, -1610, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 517, - 0, 1053, 0, 0, 517, 0, 0, 0, 517, 517, - 517, 517, 0, 517, 517, 0, 0, 807, 0, 519, - -1873, 0, 1997, 0, 657, 805, 657, 1541, 1542, 1543, - 1544, 1545, 1546, 1814, 0, 0, 2019, -1610, 0, 0, - -1610, 0, 0, 0, 0, 0, -1610, 0, 0, 0, - 0, 0, 805, 805, 0, 0, 0, 0, 0, 801, - 0, 2600, 0, 0, 0, 0, 0, 0, 805, 0, - 0, 0, 520, 0, 657, 0, 0, 0, 0, 0, - -1610, 0, 0, 1647, 516, 0, 0, 0, 521, 0, - 0, 0, 0, 0, 516, 2073, 516, 2077, 0, 516, - 0, 0, 0, -1610, 0, 516, 0, 516, 0, 0, - 0, 0, 0, 0, 0, 802, 0, 0, 716, 516, - 0, 0, 0, 716, 516, 0, 0, 0, 516, 516, - 516, 516, 0, 516, 516, 804, 2732, 0, 0, 1339, - 1340, 0, 522, 0, 0, 0, 0, 0, 0, 0, - 0, 799, 523, 657, 657, 657, 2141, 0, 0, 658, - 0, 0, 0, 0, 524, 0, 0, 0, 0, 525, - 517, 0, 2157, 0, 0, 0, 0, 0, 0, 807, - 0, 0, 0, 0, 0, 0, -1610, 0, 0, 0, - 0, 0, 0, 0, -1610, 0, 526, 0, 0, 0, - 1877, 0, 2767, 2768, 2769, 2770, 807, 807, 0, 0, - 0, -1610, 0, -1610, -1610, 1341, 1342, 0, 0, 0, - 802, 0, 807, 0, 801, 0, 0, 0, 0, 0, - 1815, 1816, 1817, 0, 1818, 1819, 1820, 1821, 1822, 1823, - 517, 527, 0, 0, 0, 528, 0, 0, 1505, 805, - -1610, 0, 799, -1610, -1610, -1610, 0, 0, 0, 802, - 0, 0, 0, 0, 0, 0, 0, 0, 804, 0, - 0, 0, 0, 0, 0, 802, 0, 0, 0, 0, - 1343, 1344, 1345, 1346, 1347, 1348, 0, 0, 1349, 1350, - 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 657, 0, 802, 0, 0, 0, 529, 0, - 2854, 802, 0, 0, 0, 621, 0, 0, 799, 0, - 516, 0, 530, 0, 0, 801, 0, 0, 517, 0, - 0, 0, 1513, 0, 0, 1514, 0, 0, 0, 1515, - 0, 799, 802, 0, 0, 802, 0, 0, 0, 0, - 802, 0, 0, 0, 0, 531, 0, 0, 532, 0, - 516, 0, 0, 0, 2303, 0, 533, 1523, 516, 534, - 0, 0, 0, 804, -1873, 0, 0, 0, 0, 0, - 0, 0, 805, 0, 0, 0, 0, 799, 535, 0, - 0, 801, 0, 0, 1351, 1352, 0, 0, 0, 1525, - 0, 0, 536, 807, 0, 1912, 0, 0, 0, 537, - 0, 0, 804, 0, 801, 0, 0, 0, 538, 0, - 0, 0, 0, 0, 539, 0, 0, 0, 804, 0, - 1513, 0, 0, 1514, 0, 621, 0, 1515, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 516, 540, - 0, 621, 0, 0, 0, 2357, 0, 804, 2360, 2019, - 801, 0, 0, 0, 804, 1523, 0, 0, 0, 2565, - 0, 0, -1873, 0, 0, 0, 0, 0, 0, 0, - 0, 799, 0, 0, 0, 0, 517, 805, 0, 1513, - 0, 0, 1514, 0, 0, 804, 1515, 1525, 804, 0, - -1873, 0, 0, 804, 0, 0, 0, 1353, 1354, 0, - 0, 0, 0, 1704, 0, 0, -1873, 0, 799, 0, - 0, -1873, 0, 0, 1523, 0, 805, 1355, 0, 0, - 0, -1873, 0, 0, 0, 0, 807, 0, 0, 0, - 0, 0, 805, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 801, 0, 1525, 0, -1873, 0, - 0, 0, 0, 0, 0, 0, 0, 2566, 0, 2984, - 0, 805, 0, 0, 0, 0, 1704, 0, 805, 0, - 0, 657, 0, 0, 0, 0, 0, 0, 3007, 799, - 0, 801, 1704, 657, 657, 657, 0, 0, -1873, 0, - 0, 0, 0, 517, 0, 0, 516, 1874, 0, 805, - 657, 0, 805, 1534, -1873, 657, 0, 805, 0, -1873, - 0, 0, 0, 0, 0, 802, 2807, 2489, 0, 0, - 0, 0, 0, 0, 0, 3037, 0, 0, 0, 0, - 0, 807, 0, 0, 716, 0, 0, 0, 0, 0, - 0, 0, 1339, 1340, 0, 0, -1873, -1873, 1704, 1704, - 0, 0, 801, 0, 0, 3063, 0, 0, 0, 0, - 0, 0, 0, -1873, 0, 0, 0, 0, -1873, 0, - 807, 0, 0, 0, 0, 0, 0, 0, 488, 0, - 0, 0, 0, 0, 0, 0, 807, 0, 0, 0, - 0, 0, 0, 0, 799, -1873, 0, 2519, 517, 0, - 0, 1534, 0, 0, 0, -1873, 657, 657, 657, 0, - 0, 0, 0, 516, 0, 807, 0, 516, 1341, 1342, - 0, 0, 807, 0, 0, 517, 0, 0, 0, 0, - 0, 0, 1912, 0, 0, 0, 0, 0, 0, 0, - 517, 517, 517, 517, 517, 517, 517, 517, 517, 517, - 0, 0, 0, 807, 0, 0, 807, 0, 0, 0, - 1534, 807, 0, 0, 0, 0, 0, 801, 804, 0, + 0, 0, 0, 0, 534, 534, 0, 0, 0, 0, + 679, 0, 0, 0, 0, 0, 0, 0, 0, 0, + -1632, 0, 0, 0, 0, 0, 0, 0, 0, 965, + 0, 0, 0, 0, 3013, 0, 0, 679, 1700, 0, + 0, 0, 839, 0, 0, 0, 0, 0, 0, 0, + 679, 0, 0, 0, 0, 0, 0, 0, 1565, 0, + 0, 1566, 1403, 1404, 0, 1567, 0, 679, -1916, -1916, + -1916, 679, 0, 0, 834, 1743, 2984, 0, 0, 0, + 0, 0, 0, 0, 836, 0, 0, 0, 0, 1474, + 1474, 0, 2773, 1575, 0, 0, 0, 0, 837, 0, + 1576, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, -1632, 0, 0, 1150, 0, + 0, 0, 0, 0, 0, 1577, 2122, 0, 0, 0, + 0, 0, 837, 837, 0, 0, 2131, 0, 2134, 0, + 0, 2145, 0, 834, 0, 0, 0, 2149, 837, 2151, + 0, 1334, 0, 0, 0, 1337, 1339, 1342, 1344, 0, + 0, 2158, 0, 0, 0, 0, 2161, -1632, 834, 0, + 2166, 2167, 2168, 2169, 0, 2173, 2174, 0, 0, 0, + 0, -1632, 0, 0, 0, 0, -1632, 0, 0, 0, + 0, -1632, 0, 0, 0, 0, 3127, 836, 0, 0, + -1632, 0, 0, 839, -1632, 0, 0, 0, 0, 1759, + 0, 0, 0, 679, 834, 0, 0, 0, 0, 679, + 0, 0, 0, 0, 0, 0, 1578, 0, 0, 0, + 1793, 756, 756, 0, 0, -1632, 0, 836, 0, 0, + 0, 0, 1579, 0, 0, 0, 0, 1580, 0, 0, + 0, 0, 0, 836, 0, -1632, 0, 0, 0, 0, + 0, 0, 0, 0, 1813, 0, 0, 0, 0, 1813, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 802, 0, 0, 1343, 1344, 1345, 1346, 1347, 1348, 0, - 0, 1349, 1350, -1873, 0, 0, 0, -1873, 2019, 0, - 0, 0, 0, 0, 1541, 1542, 1543, 1544, 1545, 1546, - 0, 0, 0, 0, 0, 0, 657, 0, 516, 0, - 0, 0, 1704, 1647, 1704, 0, 1736, 0, 0, 0, - 1874, 0, 0, 0, 0, 0, 0, 0, 1035, 1035, - 0, 0, 0, 0, 0, 516, 0, 2654, 0, 0, - 0, 0, -1873, 0, 0, 0, 0, 0, 0, 0, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, + 0, 0, 836, 0, 1583, 0, -1634, 0, 0, 836, + 0, 0, 540, 0, 535, 0, 0, 0, 0, 0, + 756, 0, 534, 534, -1632, 534, 756, -1632, 0, 0, + 0, 0, 834, -1632, 0, 0, 2773, 0, 0, 0, + 0, 836, 0, 0, 836, 0, 535, 535, 0, 836, + 0, 837, 0, 0, 0, 0, 0, 0, 0, 1586, + 0, 0, 0, 0, 0, 541, 1015, 0, -1632, 1869, + 834, 0, 0, 1870, 0, 0, 1871, 1872, 1873, 0, + 0, 542, 499, 0, 0, 0, 0, 0, 0, 839, + 0, -1632, 1468, 2874, 0, 980, 0, 1913, 0, 543, + 534, -1634, 1091, 1091, 0, 679, 0, 644, 0, 0, + 0, 0, 644, 0, 644, 0, 644, 0, 534, 0, + 0, 534, 0, 839, 839, 0, 0, 0, 0, 1565, + 0, 0, 1566, 0, 0, 544, 1567, 0, 0, 839, + 0, 1974, 0, 834, 0, 545, 1978, 680, 0, 0, + 0, 0, 1588, -1634, 0, 0, 0, 546, 0, 0, + 0, 0, 547, 0, 1575, 0, 0, -1634, 0, 535, + 0, -1916, -1634, 0, -1632, 0, 0, -1634, 0, 0, + 0, 756, 0, -1632, 0, 837, -1634, 0, 0, 548, + -1634, 0, 0, 1474, 1474, 0, 1577, 0, 0, 0, + -1632, 0, -1632, -1632, 0, 0, 0, 0, 0, 0, + 0, 0, 1091, 0, 0, 0, 0, 0, 0, 0, + 1826, -1634, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 2060, 549, 679, 0, 679, 550, -1632, + 0, -1634, -1632, -1632, -1632, 0, 0, 679, 2078, 0, + 0, 0, 0, 0, 0, 1589, 0, 834, -1916, -1916, + -1916, 0, 1593, 1594, 1595, 1596, 1597, 1598, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1875, 0, 0, + 0, 1689, 0, 0, 0, 0, 679, 0, 0, 0, + -1634, 0, 0, -1634, 1716, 1700, 534, -1916, 837, -1634, + 0, 551, 0, 0, 0, 0, 534, 2132, 534, 2136, + 0, 534, 0, -1916, 0, 1740, 552, 534, -1916, 534, + 0, 836, 839, 0, 0, 0, 0, 0, 0, 0, + 756, 534, 0, 0, -1634, 756, 534, 0, 837, 0, + 534, 534, 534, 534, 0, 534, 534, 1876, 0, 553, + 0, 0, 554, 0, 837, -1916, 0, -1634, 0, 0, + 555, 0, 0, 556, 0, 0, 679, 0, 0, 0, + 679, 679, 679, 679, 0, 2533, 0, 1474, 0, 0, + 0, 0, 557, 837, 0, 0, 0, 2217, 0, 0, + 837, 0, 0, 0, 0, 0, 558, 0, 0, 0, + 0, 0, 0, 559, 0, 0, 0, 0, 0, 0, + 1586, 0, 560, 680, 0, 0, 2867, 0, 561, 0, + 0, 0, 837, 1154, 0, 837, 0, 0, 0, 1155, + 837, 0, 0, 0, 0, 0, 1167, 0, 0, 0, + -1634, 0, 0, 0, 562, 0, 0, 0, 0, -1634, + 0, 0, 0, 0, 0, 1168, 839, 1764, 0, 1492, + 0, 0, 0, 1778, 0, 0, -1634, 0, -1634, -1634, + 0, 0, 0, 0, 0, 0, 0, 1515, 0, 0, + 0, 834, 0, 0, 0, 0, 0, 0, 0, 836, + 0, 0, 0, 0, 0, 1565, 1474, 0, 1566, 0, + 0, 0, 1567, -1916, 0, -1634, 1169, 0, -1634, -1634, + -1634, 534, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1015, 679, 0, 1869, 0, 0, 0, 1870, + 1575, 0, 1871, 1872, 1873, 1156, 644, -1916, 0, 0, + 0, 1557, 534, 0, 0, 0, 1877, 1878, 1879, 2875, + 1880, 1881, 1882, 1883, 1884, 1885, 0, 0, 0, 0, + 0, 0, 1577, 0, 0, 0, 0, 0, 0, 839, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 802, 805, 0, 0, 2157, 0, 0, 0, 0, - 0, 657, 0, 0, 0, -1873, 0, 1351, 1352, 1193, - 1200, 1647, 1541, 1542, 1543, 1544, 1545, 1546, 0, 0, - 0, 0, 0, 0, 0, 0, 1736, 799, 0, 0, + 0, 534, 0, 0, 0, 2367, 836, 0, 0, 534, + 0, 0, 0, 0, 0, 0, 2669, 1170, 0, 0, + 0, 0, 535, 535, 0, 0, -1916, 0, 0, 839, + 0, 0, 0, 1593, 1594, 1595, 1596, 1597, 1598, 0, + 0, 0, 0, 2721, 0, 839, 1974, 0, 0, 1924, + 0, 0, 2376, 0, 1474, 0, 0, 0, 2778, 2779, + 2780, 2781, 2782, 2783, 2784, 2785, 2786, 2787, 1171, 0, + 0, 0, 0, 0, 839, 836, 1172, 644, 0, 0, + 0, 839, 0, -1916, 0, 0, 0, 0, 1173, 0, + 534, 0, 0, 644, 0, 0, 0, 2078, 0, -1916, + 836, 0, 0, 1565, -1916, 0, 1566, 0, 0, 1157, + 1567, 0, 0, 839, 0, 0, 839, 1389, 1390, 1174, + 0, 839, 837, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1389, 1390, 0, 0, 1575, 0, + 0, -1916, 0, 0, 0, -1916, 836, 0, 0, 0, + 0, 1759, 0, 1875, 0, 0, 0, 0, 0, 0, + 0, 1175, 0, 0, 0, 1159, 0, 1176, 0, 0, + 1577, 0, 0, 0, 0, 0, 0, 0, 0, 2061, + 0, 2063, 0, 0, 0, 0, 0, 1435, 0, 1177, + 0, 2072, 0, 1391, 1392, 1178, 1586, 0, 1449, 1450, + 0, 0, 0, 1465, 1466, 0, 0, 0, 0, 1179, + 1391, 1392, 0, 0, 1759, 0, 0, 0, 0, 0, + 0, 679, 0, 1876, 0, 0, 0, 0, 0, 0, + 2110, 1759, 679, 679, 679, 0, 0, 0, 0, 0, + 2386, 0, 0, 0, 836, 534, 1435, 679, 0, 0, + 679, 0, 0, 0, 0, 679, 0, 0, 1393, 1394, + 1395, 1396, 1397, 1398, 1161, 2917, 1399, 1400, 2551, 0, + 0, -1916, 0, 0, 0, 1393, 1394, 1395, 1396, 1397, + 1398, 0, 836, 1399, 1400, 756, 0, -1916, 0, -1916, + 837, 0, -1916, 0, 0, 0, 0, 0, 0, 1759, + 1759, 0, 1759, 0, 0, 0, 0, 0, 0, 0, + 2195, 0, 0, 1562, 2198, 2200, 2201, 2202, 0, 0, + 535, 535, 0, 535, 0, 0, 0, 0, 0, -1916, + 0, 499, 0, 0, 0, 0, 0, 0, 0, 0, + 1435, 0, 1435, 1435, 0, 0, 0, 0, 0, 0, + 2583, 0, 0, 0, 0, 836, 0, 0, 0, 679, + 679, 679, 0, 0, 0, 0, 534, 0, 0, 0, + 534, 0, 0, 1401, 1402, 0, 0, 0, 1072, 1072, + 0, 0, 0, 0, 1586, 1974, 0, 837, 0, 0, + 1401, 1402, -1916, 839, 0, 0, 0, 0, 535, 1593, + 1594, 1595, 1596, 1597, 1598, 0, 0, 0, 0, 0, + 1435, 0, 0, 1435, 1435, 0, 1937, 0, 0, 1940, + 0, 0, 1877, 1878, 1879, 0, 1880, 1881, 1882, 1883, + 1884, 1885, 0, 0, 0, 0, 0, 0, 0, 0, + 2654, 1235, 1242, 2657, 0, 0, 2078, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 837, 0, 0, 0, + 0, 0, 0, 0, 679, 0, 534, 2334, 0, 836, + 1759, 1700, 1759, 0, 1793, 0, 0, -1916, 0, 0, + 0, 837, 0, 0, 0, 0, 0, 1403, 1404, 0, + 0, 0, 0, 534, 0, 2722, 0, 0, 0, 0, + 3038, 0, 0, 0, 1403, 1404, 0, 1405, 534, 534, + 534, 534, 534, 534, 534, 534, 534, 534, 0, 0, + 3045, 3046, 0, 0, 0, 0, 0, 837, 0, 0, + 0, 0, 0, 0, 0, 2217, 0, 0, 0, 3058, + 0, 679, 1015, 0, 0, 1869, 0, 0, 0, 1870, + 0, 1700, 1871, 1872, 1873, 0, 0, 0, 0, 0, + 0, 839, 0, 0, 0, 0, 1565, 1793, 0, 1566, + 0, 0, 0, 1567, 0, 0, 1570, 1571, 1572, 0, + -1916, 0, 0, 0, 0, 0, 1759, 1593, 1594, 1595, + 1596, 1597, 1598, 1573, 535, 0, 0, 0, 0, 0, + 0, 1575, 0, 534, 535, 0, 535, 1801, 1576, 535, + 679, 679, 679, 679, 0, 535, 1015, 535, 1810, 1869, + 1811, 0, 756, 1870, 0, 837, 1871, 1872, 1873, 535, + 1818, 0, 0, 1577, 535, 2865, 0, 0, 535, 535, + 535, 535, 0, 535, 535, 0, 0, 1819, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 839, 0, + 2885, 0, 644, 837, 0, 0, 0, 0, 1446, 0, + 1091, 0, 0, 1833, 1835, 0, 0, 3162, 1467, 0, + 0, 1469, 0, 2078, 1479, 1482, 1487, 1490, 0, 1974, + 0, 0, 0, 836, 0, 1700, 0, 0, 0, 0, + 0, 1759, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 756, 534, 0, 0, 0, 0, + 1235, 0, 679, 0, 0, 0, 0, 839, 0, 1167, + 0, 0, 0, 0, 1578, 0, 837, 1532, 0, 2937, + 1565, 0, 0, 1566, 0, 2510, 0, 1567, 1168, 0, + 1579, 0, 839, 1875, 1536, 1580, 2522, 2523, 2525, 0, + 0, 0, 0, 0, 0, 1539, 1540, 1541, 0, 1545, + 1549, 2536, 0, 0, 2539, 1575, 0, 1581, 1582, 2544, + 0, 0, -1916, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1583, 0, 0, 0, 1607, 0, 839, 1169, + 2710, 0, 0, 0, 0, 0, 0, 1577, 2711, 535, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1759, + 0, 0, 0, 1876, 0, 0, 0, -1916, 0, 0, + 1584, 2217, 0, 1585, 0, 0, 0, 0, 0, 0, + 1940, 0, 0, 0, 0, 2980, 0, 1586, 0, 1651, + 837, 0, 0, 1667, 1672, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 2712, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2626, 0, 535, + 0, 2999, 0, 2590, 2591, 2592, 0, 1557, 0, 0, + 1170, 0, 0, 0, 0, 0, 839, 1876, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3011, -1916, 1235, + 2104, 2104, 0, 0, 0, 0, 0, 2654, 0, 0, + 0, 1235, 0, 1565, -1916, 0, 1566, 0, 0, -1916, + 1567, 0, 0, 0, 839, 0, 0, 0, 0, 0, + 1588, 1171, 0, 0, 0, 0, 1235, 0, 0, 1172, + 534, 0, 0, 0, 0, 0, 0, 0, 1575, 0, + 0, 1173, 1435, 2713, 0, -1916, -1916, 0, 535, 0, + 534, 534, 1435, 0, 0, 1435, 0, 0, 0, 0, + 0, 0, 0, 679, 0, 1700, 0, 0, 2668, 534, + 1577, 0, 1174, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 679, 0, 0, 3083, 839, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 804, 0, 1704, 0, 0, 517, 0, - 0, 0, 0, 0, 0, 0, 0, 802, 0, 0, - 516, 0, 0, 0, -1873, 0, 0, 657, 657, 657, - 657, 1541, 1542, 1543, 1544, 1545, 1546, 0, 0, 716, - 802, 0, 0, 0, 0, 0, 0, 0, 1513, 0, - 0, 1514, 2794, 0, 0, 1515, 0, 0, 0, 0, - 801, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2814, 0, 621, - 1353, 1354, 0, 1523, 0, 0, 802, 1053, 0, 0, - -1873, 2357, 0, 0, 0, 0, 2019, 0, 0, 0, - 0, 0, 1912, 0, 804, 0, 807, 0, 1647, 0, - 0, 0, 0, 0, 1704, 1525, 0, 805, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 716, 516, 0, - 0, 0, 0, 0, 0, 657, 0, 0, 0, 0, + 0, 1586, 1877, 1878, 1879, 0, 1880, 1881, 1882, 1883, + 1884, 1885, 0, 0, 0, 0, 0, 0, 0, 1091, + 1176, 0, 0, 1589, 0, 3083, 1590, 1591, 1592, 679, + 1593, 1594, 1595, 1596, 1597, 1598, 0, 0, 2247, 2249, + 2629, 0, 1177, 0, 0, 2802, 0, 0, 0, 0, + 0, 0, 0, 0, 837, 0, 0, 0, 0, 679, + 1435, 0, 1179, 0, 2714, 0, 0, 2715, 0, 0, + 0, -1916, 0, 0, 0, 0, 1877, 1878, 1879, 0, + 1880, 1881, 1882, 1883, 1884, 1885, 0, -1916, 0, 0, + 0, 0, -1916, 0, -1916, 0, 2999, 0, 0, 0, + 0, 839, 0, 535, 0, 0, 0, 534, 0, 0, + 0, 0, 0, 0, 2838, 2839, 2840, 2841, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, -1916, + 0, 0, 0, 0, 0, 1700, 0, 0, 0, 0, + 0, 0, 0, 1855, 0, 0, 0, 0, 3083, 756, + 756, 756, 0, 0, 0, 0, 0, 0, 0, 1913, + 0, 0, -1648, 1435, 0, 0, 0, 0, 0, 0, + 0, 0, 1708, 0, 0, 0, 0, 0, 1487, 0, + 1487, 1487, 0, 0, 1586, 0, 0, 0, 0, 1700, + 0, 0, 0, 1072, 1072, 0, 3083, -1916, 0, 0, + 0, 0, 0, 0, 1593, 1594, 1595, 1596, 1597, 1598, + 0, 0, 0, 0, 2078, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 535, 0, 2924, 0, 1937, 756, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2867, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 804, 1513, 0, 0, 1514, 0, 0, 0, 1515, 0, - 802, -1873, -1873, -1873, 0, 1395, 0, 0, 0, 0, - 0, 0, 0, 804, 0, 1416, 0, 0, 1418, 0, - 0, 1428, 1431, 1436, 1439, 0, 1523, 0, 0, 0, - 0, 0, 0, 1524, 0, 0, -1873, 802, 805, 0, + 0, 0, 0, 0, 0, 0, 1989, -1648, 0, 0, + 0, 0, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 0, + 0, 0, 0, 2008, 2009, 0, 0, -1916, 2020, 0, + 2407, 0, 2023, 0, 0, 2031, 2032, 2033, 2034, 2035, + 2036, 2037, 2038, 2039, 0, 0, 2040, 0, 0, 0, + 0, 0, 0, 1072, 0, 1235, 0, 0, 0, -1648, + 0, 0, 2435, 2435, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -1648, 535, 839, 0, 0, -1648, 2065, + 0, 1476, 0, -1648, 0, 0, 0, 0, 0, 0, + 0, 0, -1648, 0, 0, 0, -1648, 0, 0, 0, + 0, 535, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1540, 1541, 0, 535, 535, 535, 535, + 535, 535, 535, 535, 535, 535, 0, -1648, 0, 0, + -1916, -43, 0, 0, 0, 0, 0, 1593, 1594, 1595, + 1596, 1597, 1598, 0, 0, 0, 0, -1648, 0, 0, + 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 3, 4, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, + 6, 0, 0, 0, 0, 0, 1601, 0, 0, 7, + 0, 0, 0, 0, 1235, 0, -1648, 2183, 2184, -1648, + 2185, 8, 0, 0, 0, -1648, 0, 0, 0, 0, + 2547, 1937, 9, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 10, 0, 11, 0, 0, 1601, + 0, 0, 0, 0, 1235, 0, 0, 3054, 0, 0, + -1648, 0, 0, 0, 12, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 3078, 13, 14, + 0, 0, 0, -1648, 0, 0, 0, 0, 15, 0, + 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, + 0, 0, 17, 0, 18, 19, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 20, 0, + 0, 0, 21, 3106, 2283, 0, 0, 2284, 0, 2285, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 680, + 0, 0, 0, 535, 0, 0, 0, 22, 0, 0, + 0, 0, 0, 3132, 0, 0, 0, 2310, 2311, 0, + 0, 2065, 23, 0, 0, 0, -1648, 0, 0, 1601, + 0, 0, 0, 0, 0, -1648, 1601, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, + 2338, 0, -1648, 2341, -1648, -1648, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1235, 0, + 0, 0, 0, 0, 1154, 0, 0, 0, 2354, 0, + 1155, 0, 0, 0, 0, 0, 0, 1167, 0, 0, + 0, -1648, 0, 0, -1648, -1648, -1648, 0, 0, 0, + 0, 0, 0, 0, 2365, 0, 1168, 0, 0, 2368, + 0, 0, 2370, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 25, 0, 0, 26, + 0, 0, 0, 1565, 1435, 0, 1566, 0, 0, 0, + 1567, 1568, 1569, 1570, 1571, 1572, 0, 0, 0, 2388, + 0, 0, 2391, 0, 2393, 0, 0, 1169, 27, 0, + 1573, 0, 0, 0, 0, 0, 0, 28, 1575, 0, + 0, 0, 0, 0, 0, 1576, 0, 0, 0, 0, + 0, 29, 0, 0, 0, 0, 1156, 0, 30, 0, + 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, + 1577, 0, 32, 0, 0, 0, 0, 0, 1651, 0, + 0, 0, 0, 0, 33, 0, 0, 0, 34, 0, + 0, 0, 0, 0, 0, 1672, 2038, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 35, 535, 0, + 1601, 0, 0, 0, 2443, 0, 0, 0, 1170, 0, + 0, 0, 36, 0, 0, 37, 0, 0, 535, 535, + 38, 1601, 0, 1601, 0, 1476, 1476, 1886, 0, 0, + 1476, 0, 0, 1601, 39, 0, 1601, 535, 0, 0, + 0, 1601, 0, 0, 1601, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 40, 1171, + 0, 1578, 0, 1235, 0, 0, 0, 1172, 0, 0, + 0, 0, 41, 0, 0, -43, 0, 1579, 0, 1173, + 0, 0, 1580, 0, 0, 0, 1601, 0, 0, 0, + 1601, 0, 0, 1601, 1601, 1601, 0, 0, 0, 1601, + 1157, 0, 0, 1601, 1581, 1582, 0, 0, 0, 0, + 1174, 0, 0, 0, 2542, 0, 0, 0, 0, 1583, + 0, 1435, 0, 0, 1565, 0, 1435, 1566, 0, 0, + 0, 1567, 1568, 1569, 1570, 1571, 1572, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1704, 0, -1873, 0, 0, 0, 1193, -1873, 1525, 804, - 0, 517, 2157, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1481, 0, 2909, 0, 0, 0, 0, - 0, 517, 517, 0, 0, 0, 0, 0, 0, 0, - 1485, 807, 0, 0, -1873, 0, 0, 0, 0, 0, - 517, 1488, 1489, 1490, 805, 1494, 1498, 0, 802, 0, - 0, 2928, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 805, 0, 0, - 1555, 0, 0, 0, 0, 0, 0, 2940, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1534, - 2951, 517, 0, 804, 0, 0, 0, 0, 0, 1526, + 0, 1573, 2152, 0, 2611, 0, 1159, 1584, 1176, 1575, + 1585, 1601, 0, 0, 0, 0, 1576, 0, 0, 0, + 0, 0, 0, 0, 1586, 535, 0, 1587, 1833, 1835, + 1177, 0, 1564, 0, 0, 0, 2153, 1565, 0, 0, + 1566, 1577, 0, 0, 1567, 1568, 1569, 1570, 1571, 1572, + 1179, 0, 0, 0, 0, 1601, 0, 0, 0, 0, + 0, 0, 0, 0, 1573, 0, 0, 1574, 0, 0, + 0, 1601, 1575, 0, 0, 0, 1601, 0, 0, 1576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 805, 0, 1527, 0, 0, 0, 0, - 1528, 516, 1598, 0, 0, 0, 1614, 1619, 0, 0, - 804, 0, 807, 0, 0, 0, 0, 0, 0, 0, - 0, 516, 516, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 657, 0, 1647, 1531, 0, 0, - 516, 0, 0, 802, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 657, 0, 0, 2951, 0, 0, 0, - 1193, -1873, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1193, 0, 0, 0, 0, 0, 807, 0, - 0, 804, 0, 0, 0, 0, 0, 805, 0, 1053, - 0, 516, 1534, 0, 0, 0, 1193, 0, 0, 1385, - 657, 807, 0, 0, 0, 0, 0, 0, 1398, 1399, - 0, 0, 0, 1414, 1415, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 805, 0, 1425, 0, 0, 0, - 657, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 807, 0, 0, - 0, 0, 0, 0, 0, 1385, 0, 0, 0, 0, - 0, 0, 2928, -1873, 0, 0, 0, 0, 0, 0, - 1541, 1542, 1543, 1544, 1545, 1546, 2951, 716, 716, 716, - 0, 0, 0, 0, 1536, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 805, 804, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1647, 0, 0, + 2602, 0, 0, 0, 0, 0, 0, 0, 0, 2607, + 0, 0, 0, 0, 1577, 1161, 0, 0, 2615, 0, + 0, 2618, 0, 2620, 0, 0, 0, 1588, 0, 0, + 0, 2624, 0, 0, 0, 0, 0, 0, 0, 2631, + 2632, 0, 0, 2635, 0, 0, 0, 0, 0, 0, + 0, 0, 1578, 0, 0, 0, 0, 2645, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1579, 2662, + 0, 0, 0, 1580, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1510, 0, 0, 0, 1851, 0, 0, 0, 1549, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2019, - 0, 807, 0, 0, 0, 0, 0, 1385, 0, 1385, - 1385, 0, 0, 0, 0, 0, 0, 0, 0, 1647, - 0, 0, 0, 0, 0, 2951, 802, 0, 0, 0, - 0, 1549, 0, 1513, 0, 716, 1514, 0, 807, 0, - 1515, 1516, 1517, 1518, 1519, 1520, 1537, 0, 0, -1873, - -1873, -1873, 0, 1541, 1542, 1543, 1544, 1545, 1546, 0, - 1521, 0, 0, 0, 1793, 0, 0, 0, 1523, 0, - 805, 0, 0, 0, 0, 1524, 1385, 0, 0, 1385, - 1385, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1436, - 1525, 1436, 1436, 0, 0, 0, 0, 0, 0, 807, - 0, 0, 0, 0, 1035, 1035, 0, 0, 0, 0, - 0, 0, 1513, 0, 0, 1514, 0, 0, 0, 1515, - 0, 0, 1518, 1519, 1520, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1549, 0, 1521, - 0, 0, 0, 0, 1549, 0, 0, 1523, 0, 0, - 0, 0, 0, 0, 1524, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1927, 0, 0, 804, - 0, 0, 1931, 1932, 1933, 1934, 1935, 1936, 1937, 1525, - 0, 0, 0, 1946, 1947, 0, 0, 0, 1958, 0, - 0, 1526, 1961, 0, 0, 1969, 1970, 1971, 1972, 1973, - 1974, 1975, 1976, 1977, 0, 0, 1978, 1527, 0, 0, - 0, 0, 1528, 1035, 807, 1193, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1581, 1582, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1833, 1835, 0, 0, + 1583, 0, 0, 0, 0, 1578, 0, 1435, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1529, 1530, 0, 0, 0, 2002, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1531, - 0, 0, 1740, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1749, 0, 1750, 0, 0, 0, 0, - 0, 0, 1489, 1490, 0, 1757, 0, 0, 0, 0, - 1526, 0, 0, 805, 0, 0, 0, 1532, 0, 0, - 1533, 0, 1758, 0, 0, 0, 1527, 0, 0, 0, - 0, 1528, 0, 0, 1534, 0, 0, 1535, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1773, 1775, - 0, 0, 0, 1529, 1530, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1531, 1549, + 1589, 1579, 0, 1590, 1591, 1592, 1580, 1593, 1594, 1595, + 1596, 1597, 1598, 0, 0, 0, 0, 0, 1584, 0, + 1862, 1585, 0, 0, 0, 0, 0, 0, 1581, 1582, + 0, 0, 0, 0, 0, 1586, 0, 0, 1587, 1601, + 0, 0, 0, 1583, 0, 0, 0, 0, 0, 0, + 0, 1886, 1886, 0, 1476, 1476, 1476, 1476, 1476, 0, + 0, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, 1476, + 1476, 1886, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1584, 0, 0, 1585, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1586, 0, + 0, 1587, 0, 0, 0, 0, 0, 0, 2855, 2856, + 0, 0, 0, 0, 0, 0, 2861, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 2866, 1588, 0, + 0, 2868, 2869, 0, 0, 0, 2870, 0, 0, 0, + 0, 2873, 0, 0, 2876, 2877, 0, 0, 0, 2881, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1193, 0, 0, 2124, 2125, 0, 2126, 0, 0, - 1549, 0, 1549, 0, 1425, 1425, 1824, 0, 0, 1425, - 0, 0, 1549, 0, 0, 1549, 1532, 0, 0, 1533, - 1549, 0, 0, 1549, 0, 0, 0, 0, 0, 1193, - 0, 0, 0, 1534, 0, 0, 1536, 0, 0, 0, + 0, 1072, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1601, 0, 0, 0, 1601, 1601, 1601, + 1601, 1601, 1601, 1601, 0, 0, 0, 0, 0, 1476, + 1476, 1588, 1601, 1601, 0, 0, 0, 0, 0, 2912, + 0, 0, 0, 0, 1601, 0, 0, 1601, 0, 0, + 0, 1435, 0, 0, 0, 1601, 1601, 1601, 1601, 1601, + 1601, 1601, 1601, 1601, 1601, 0, 2931, 0, 0, 0, + 0, 1589, 0, 0, 1590, 1591, 1592, 0, 1593, 1594, + 1595, 1596, 1597, 1598, 0, 0, 0, 0, 1983, 1601, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1549, 0, 0, 0, 1549, - 0, 0, 1549, 1549, 1549, 0, 0, 807, 1549, 0, - 0, 0, 1549, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2219, 0, 0, 2220, 0, 2221, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1536, 0, 2246, 2247, 0, - 0, 2002, 0, 0, 0, 0, 0, 0, 1537, 1549, - 0, 1538, 1539, 1540, 0, 1541, 1542, 1543, 1544, 1545, - 1546, 0, 0, 0, 0, 0, 0, 0, 1800, 0, - 2274, 0, 0, 2277, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1193, 0, 0, - 0, 0, 1549, 0, 0, 0, 0, 0, 2290, 0, - 0, 0, 2045, 2045, 0, 0, 0, 0, 1549, 0, - 0, 0, 0, 1549, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2301, 0, 0, 0, 0, 2305, - 0, 0, 2307, 0, 0, 0, 0, 1537, 0, 0, - 1538, 1539, 1540, 0, 1541, 1542, 1543, 1544, 1545, 1546, - 0, 0, 0, 0, 1385, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1385, 0, 0, 1385, 0, 2325, - 0, 0, 2328, 0, 2330, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1589, 0, 0, 1590, 1591, 1592, + 0, 1593, 1594, 1595, 1596, 1597, 1598, 0, 0, 0, + 0, 0, 0, 0, 2958, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1565, 0, 0, 1566, 0, 0, 0, + 1567, 0, 1549, 1570, 1571, 1572, 0, 1601, 1601, 1601, + 0, 0, 1565, 0, 0, 1566, 0, 0, 2365, 1567, + 1568, 1569, 1570, 1571, 1572, 0, 0, 0, 1575, 3006, + 3007, 0, 0, 3008, 0, 1576, 0, 0, 0, 1573, + 0, 0, 0, 0, 0, 0, 0, 1575, 0, 0, + 0, 0, 3023, 0, 1576, 0, 0, 0, 0, 0, + 1577, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3033, 0, 0, 0, 0, 1565, 0, 0, 1566, 1577, + 0, 0, 1567, 1568, 1569, 1570, 1571, 1572, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1573, 0, 0, 0, 0, 1601, 1601, 1601, + 1575, 0, 1886, 1886, 1886, 1886, 1886, 1576, 0, 0, + 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, 1886, + 0, 0, 0, 3077, 1601, 1601, 0, 0, 0, 0, + 0, 0, 1577, 0, 0, 0, 0, 0, 0, 0, + 0, 2855, 0, 0, 0, 3094, 0, 0, 0, 3097, + 0, 1578, 1601, 0, 0, 1601, 0, 0, 0, 0, + 1072, 0, 0, 0, 0, 0, 0, 1579, 1601, 0, + 1578, 0, 1580, 0, 0, 0, 0, 3117, 0, 1601, + 0, 0, 1601, 0, 1601, 0, 1579, 0, 1886, 1886, + 0, 1580, 0, 0, -1916, -1916, 0, 0, 0, 0, + 0, 0, 1601, 1476, 1476, 1601, 0, 1601, 0, 1583, + 0, 0, 0, 1581, 1582, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3142, 0, 0, 0, 1583, 0, + 0, 0, 0, 1578, 2855, 0, 1565, 0, 0, 1566, + 0, 0, 0, 1567, 1568, 1569, 1570, 1571, 1572, 1579, + -1916, 0, 0, 0, 1580, 0, 0, 1601, 0, 0, + 0, 0, 0, 1573, 1586, 0, 1584, 3182, 0, 1585, + 0, 1575, 0, 0, 0, 0, 1581, 1582, 1576, 0, + 0, 0, 0, 1586, 0, 0, 1587, 0, 0, 0, + 0, 1583, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1577, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1598, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2185, 2187, 0, 0, 0, 0, 1619, 1976, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1584, + 0, 0, 1585, 0, 0, 0, 0, 0, 0, 0, + 1565, 0, 0, 1566, 0, 0, 1586, 1567, 0, 1587, + 3232, 3232, 0, 0, 0, 1565, 1601, 1588, 1566, 0, + 0, 0, 1567, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 3232, 1575, 1588, 0, 0, 0, + 0, 0, -1916, 0, 0, 0, 0, 1476, 0, 0, + 1575, 0, 0, 0, 0, 0, 0, -1916, 0, 0, + 0, 0, 0, 0, 1578, 0, 0, 1577, 3232, 0, + 0, 0, 0, 0, 0, 0, 1601, 0, 0, 0, + 1579, 1601, 1577, 0, 0, 1580, 0, 0, 0, 1601, + 0, 0, 1601, 0, 1601, 0, 0, 0, 1601, 1588, + 0, 1886, 1886, 0, 0, 1601, 1601, 1581, 1582, 1601, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1601, + 1589, 0, 1583, 1590, 1591, 1592, 0, 1593, 1594, 1595, + 1596, 1597, 1598, 0, 0, 0, 1601, 2630, 0, 1589, + 0, 0, 1590, 1591, 1592, 0, 1593, 1594, 1595, 1596, + 1597, 1598, 2878, 0, 0, 0, 1983, 0, 0, 0, + 1584, 0, 0, 1585, 0, 0, 1476, 0, -1916, 0, + 0, 0, 0, 0, 0, 0, 0, 1586, 0, 0, + 1587, 0, 0, -1916, -1916, 0, 0, 0, 0, -1916, + 0, 0, 0, 0, 0, 0, 0, 0, 0, -1916, + 0, 0, 1589, 0, -1916, 1590, 1591, 1592, 0, 1593, + 1594, 1595, 1596, 1597, 1598, 0, 0, 0, 0, 2282, + 0, 0, 0, 0, 0, 0, -1916, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1385, 0, 2384, 0, 0, + 0, -1916, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1549, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1824, - 1824, 0, 1425, 1425, 1425, 1425, 1425, 0, 0, 1425, - 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1425, 1824, - 0, 0, 0, 0, 0, 0, 1193, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1588, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1586, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1586, 0, 0, 0, + 0, 0, 0, 1886, 1476, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1601, + 1601, 0, 0, 0, 0, 1601, 0, 0, 0, 0, + 1601, 0, 1601, 1601, 1601, 0, 0, 1601, 0, 0, + 1601, 1601, 0, 0, 0, 1601, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1512, 1385, 0, 0, 0, 1513, - 0, 0, 1514, 0, 0, 2480, 1515, 1516, 1517, 1518, - 1519, 1520, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1521, 0, 0, 1522, - 0, 0, 0, 0, 1523, 0, 0, 0, 0, 0, - 0, 1524, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1549, 0, 0, 0, 1549, 1549, 1549, 1549, 1549, - 1549, 1549, 0, 0, 0, 0, 1525, 1425, 1425, 0, - 1549, 1549, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1549, 0, 0, 1549, 0, 0, 0, 0, - 0, 0, 0, 1549, 1549, 1549, 1549, 1549, 1549, 1549, - 1549, 1549, 1549, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2344, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1549, 0, 2538, 0, - 0, 0, 0, 0, 0, 0, 0, 2543, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 2551, 2376, 2376, - 2554, 0, 2556, 0, 0, 0, 0, 0, -39, 0, - 2560, 0, 0, 0, 0, 0, 0, 1526, 2567, 2568, - 0, 0, 2571, 0, 0, 0, 0, 0, 0, 1, - 0, 0, 0, 1527, 0, 0, 2581, 0, 1528, 2, - 0, 3, 4, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 2594, 0, 0, 0, 0, 5, 0, 0, - 1529, 1530, 0, 0, 0, 0, 6, 0, 0, 0, - 0, 0, 0, 0, 0, 1531, 0, 0, 7, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, - 0, 0, 0, 0, 0, 0, 0, 0, 1549, 1549, - 1549, 9, 0, 10, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1532, 0, 0, 1533, 0, 0, 0, - 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, - 1534, 0, 0, 1535, 0, 12, 0, 0, 0, 0, - 0, 0, 0, 2485, 0, 13, 0, 0, 0, 0, - 0, 14, 0, 0, 0, 0, 0, 0, 0, 15, - 0, 16, 17, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 18, 0, 0, 0, 19, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1549, 1549, 1549, 0, 0, 1824, 1824, - 1824, 1824, 1824, 0, 20, 0, 1824, 1824, 1824, 1824, - 1824, 1824, 1824, 1824, 1824, 1824, 2784, 2785, 0, 21, - 1549, 1549, 1536, 0, 2790, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 2795, 0, 0, 0, 2797, - 2798, 0, 0, 0, 2799, 22, 0, 0, 1549, 2802, - 0, 1549, 2805, 2806, 0, 0, 0, 2810, 0, 0, - 0, 0, 0, 0, 1549, 0, 0, 0, 0, 1035, - 0, 0, 0, 0, 0, 1549, 0, 0, 0, 1549, - 0, 1549, 0, 0, 0, 1824, 1824, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1549, - 1425, 1425, 1549, 2842, 1549, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 23, 0, 1537, 24, 0, 1538, 1539, 1540, - 2861, 1541, 1542, 1543, 1544, 1545, 1546, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 25, 0, 0, 0, 1549, 0, - 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, - 0, 0, 0, 0, 28, 0, 0, 0, 29, 0, - 1385, 0, 1513, 0, 0, 1514, 0, 0, 30, 1515, - 1516, 1517, 1518, 1519, 1520, 0, 0, 0, 0, 0, - 31, 0, 0, 0, 32, 0, 2888, 0, 1513, 1521, - 0, 1514, 2547, 0, 0, 1515, 0, 1523, 1518, 1519, - 1520, 0, 0, 33, 1524, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1521, 0, 0, 0, 0, - 34, 0, 0, 1523, 1549, 35, 0, 0, 0, 1525, - 1524, 0, 0, 1498, 0, 0, 0, 0, 0, 36, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 2301, - 0, 0, 0, 1425, 0, 1525, 0, 0, 0, 0, - 2935, 2936, 0, 37, 2937, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 38, 0, 0, - -39, 0, 1549, 0, 2953, 0, 0, 1549, 0, 0, - 0, 0, 0, 0, 0, 1549, 0, 0, 1549, 0, - 1549, 0, 2963, 0, 1549, 0, 0, 1824, 1824, 0, - 0, 1549, 1549, 0, 0, 1549, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1549, 0, 0, 0, 0, - 1526, 0, 0, 0, 0, 0, 0, 0, 1549, 0, - 0, 0, 0, 0, 0, 0, 1527, 0, 0, 0, - 0, 1528, 0, 0, 0, 0, 1526, 0, 0, 0, - 0, 0, 0, 0, 3006, 0, 0, 0, 1425, 0, - 0, 0, 1527, 1529, 1530, 0, 0, 1528, 1385, 0, - 0, 0, 2784, 1385, 0, 0, 3019, 0, 1531, 0, - 3022, 0, 0, 0, 0, 0, 0, 0, 0, 1529, - 1530, 1035, 0, 0, 3029, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1531, 0, 0, 0, 0, 3048, - 0, 0, 0, 0, 0, 0, 1532, 0, 0, 1533, - 0, 0, 0, 0, 1773, 1775, 0, 0, 0, 0, - 0, 0, 0, 1534, 0, 0, 1535, 0, 0, 0, - 0, 0, 1532, 0, 0, 1533, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1534, - 0, 2784, 1535, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1589, -1916, 0, 1590, 1591, 1592, 0, + 1593, 1594, 1595, 1596, 1597, 1598, 1601, 0, 0, -1916, + 2372, 0, 1886, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1601, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1824, 1425, 0, 0, 0, 0, 0, 0, - 3111, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1549, 1549, - 0, 0, 0, 0, 1549, 1536, 0, 0, 0, 1549, - 0, 1549, 1549, 1549, 0, 0, 1549, 0, 0, 1549, - 1549, 0, 0, 0, 1549, 0, 0, 0, 0, 0, - 0, 1536, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1601, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 3152, 3152, 1549, 0, 0, 0, - 0, 0, 1824, 0, 0, 0, 0, 0, 0, 0, - 0, 1773, 1775, 0, 0, 1549, 3152, 0, 0, 0, - 0, 0, 1385, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1886, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1549, 0, 0, 0, 0, 1537, 0, 3152, - 1538, 1539, 1540, 0, 1541, 1542, 1543, 1544, 1545, 1546, - 0, 0, 0, 0, 1921, 0, 0, 1824, 0, 0, - 0, 0, 0, 1537, 0, 0, 1538, 1539, 1540, 0, - 1541, 1542, 1543, 1544, 1545, 1546, 0, 0, 0, 1549, - 1549, 1549, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1549, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1549, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -1916, 0, 0, + 1601, 1601, 1601, 0, 1593, 1594, 1595, 1596, 1597, 1598, + 0, 0, -1916, 0, 0, 0, 0, 1601, 0, 1593, + 1594, 1595, 1596, 1597, 1598, 0, 0, 1601, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1549, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1549, 0, 0, 1549, 0, 0, 0, - 0, 0, 0, 1549, 0, 0, 0, 0, 0, 0, + 0, 1601, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1601, 0, + 0, 1601, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1549, 0, 0, 0, 0, 0, 0, 0, + 0, 1601, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 95, 976, 624, 977, 978, 979, 980, 981, - 0, 0, 0, 0, 0, 1385, 0, 0, 0, 0, - 96, 97, 98, 99, 100, 101, 102, 103, 0, 104, - 105, 106, 0, 0, 0, 1549, 982, 0, 0, 107, - 108, 0, 109, 110, 111, 112, 113, 114, 115, 116, - 983, 118, 984, 985, 0, 121, 122, 123, 124, 125, - 126, 986, 583, 127, 128, 987, 988, 131, 0, 132, - 133, 134, 135, 584, 0, 585, 1549, 989, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 0, 148, 149, - 150, 151, 152, 153, 0, 154, 155, 156, 157, 586, - 587, 588, 589, 590, 591, 592, 163, 164, 165, 166, - 167, 168, 169, 990, 991, 172, 992, 173, 0, 174, - 175, 176, 177, 178, 179, 0, 180, 181, 182, 183, - 184, 0, 0, 185, 186, 754, 188, 189, 0, 190, - 191, 192, 0, 193, 194, 195, 0, 196, 197, 198, - 199, 993, 201, 202, 203, 204, 205, 593, 994, 207, - 0, 208, 209, 995, 211, 0, 212, 0, 213, 214, - 19, 215, 216, 217, 218, 219, 220, 0, 221, 0, - 996, 997, 224, 0, 225, 226, 227, 228, 229, 230, - 231, 232, 233, 234, 235, 236, 0, 237, 238, 239, - 240, 241, 242, 0, 243, 244, 245, 246, 247, 248, - 249, 250, 998, 999, 0, 1000, 0, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 0, 0, - 265, 266, 267, 268, 0, 269, 270, 271, 595, 596, - 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 0, 0, 0, 0, 0, 0, 1601, 0, 0, 0, + 0, 104, 1012, 515, 1013, 1014, 1015, 1016, 1017, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, + 106, 107, 108, 109, 110, 111, 112, 0, 113, 114, + 115, 0, 0, 0, 0, 1018, 1601, 0, 116, 117, + 0, 118, 119, 120, 121, 122, 123, 124, 125, 1019, + 127, 1020, 1021, 0, 130, 131, 132, 133, 134, 135, + 1022, 606, 136, 137, 1023, 1024, 140, 0, 141, 142, + 143, 144, 607, 0, 608, 0, 1025, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 1601, 157, 158, 159, + 160, 161, 162, 0, 163, 164, 165, 166, 609, 610, + 611, 612, 613, 614, 615, 172, 173, 174, 175, 176, + 177, 178, 1026, 1027, 181, 1028, 182, 0, 183, 184, + 185, 186, 187, 188, 0, 189, 190, 191, 192, 193, + 0, 0, 194, 195, 785, 197, 198, 0, 199, 200, + 201, 0, 202, 203, 204, 0, 205, 206, 207, 208, + 1029, 210, 211, 212, 213, 214, 616, 1030, 216, 0, + 217, 218, 1031, 220, 0, 221, 0, 222, 223, 21, + 224, 225, 226, 227, 228, 229, 0, 230, 0, 1032, + 1033, 233, 0, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 0, 246, 247, 248, 249, + 250, 251, 0, 252, 253, 254, 255, 256, 257, 258, + 259, 1034, 1035, 0, 1036, 0, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 0, 0, 274, + 275, 276, 277, 0, 278, 279, 280, 618, 619, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, 293, 294, 295, 1001, 297, 1002, 299, 300, 301, - 302, 1003, 303, 304, 305, 306, 1004, 597, 308, 1005, - 310, 311, 312, 0, 313, 314, 0, 0, 1006, 316, - 317, 0, 0, 318, 319, 320, 321, 322, 599, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 0, - 334, 335, 600, 337, 338, 339, 340, 341, 342, 0, - 343, 344, 345, 346, 347, 348, 0, 349, 350, 351, - 1007, 353, 354, 355, 356, 0, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, 369, 0, - 370, 371, 372, 373, 374, 375, 1008, 377, 378, 379, - 380, 381, 382, 383, 384, 385, 386, 387, 27, 388, - 389, 390, 391, 392, 602, 394, 395, 396, 397, 398, - 399, 400, 401, 1009, 403, 0, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, - 603, 419, 0, 420, 421, 32, 422, 423, 424, 425, - 426, 427, 428, 0, 1010, 1011, 0, 0, 431, 432, - 604, 434, 605, 1012, 436, 437, 606, 439, 440, 441, - 442, 443, 0, 0, 444, 445, 446, 447, 448, 607, - 0, 450, 451, 452, 453, 454, 608, 1013, 0, 457, - 458, 459, 460, 461, 462, 463, 0, 0, 464, 0, - 36, 465, 466, 467, 468, 469, 470, 471, 472, 473, - 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, - 484, 485, 1014, 0, 37, 0, 0, 0, 0, 1015, - 1016, 0, 0, 0, 0, 0, 1018, 0, 1019, 2924, - 0, 0, 0, 1020, 1021, 1022, 1152, 976, 624, 977, - 978, 979, 980, 981, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 96, 97, 98, 99, 100, 101, - 102, 103, 1153, 104, 105, 106, 0, 0, 0, 0, - 982, 0, 0, 107, 108, 0, 109, 110, 111, 1154, - 113, 114, 115, 116, 983, 1155, 984, 985, 0, 121, - 122, 123, 124, 125, 126, 986, 583, 127, 128, 987, - 988, 131, 0, 132, 133, 134, 135, 584, 0, 1156, - 0, 1157, 139, 140, 141, 142, 143, 1158, 145, 146, - 147, 0, 148, 149, 150, 151, 152, 153, 0, 1159, - 155, 156, 157, 1160, 1161, 1162, 1163, 590, 591, 1164, - 163, 164, 165, 166, 167, 168, 169, 990, 991, 172, - 992, 173, 0, 174, 175, 176, 177, 178, 179, 0, - 180, 181, 182, 183, 184, 1165, 0, 185, 186, 754, - 188, 189, 0, 190, 191, 192, 0, 193, 194, 195, - 0, 196, 197, 198, 199, 993, 201, 202, 203, 204, - 205, 593, 994, 207, 0, 208, 209, 995, 211, 0, - 212, 0, 213, 1166, 0, 1167, 216, 217, 1168, 1169, - 220, 0, 221, 0, 996, 997, 224, 0, 225, 226, - 227, 228, 229, 230, 231, 1170, 233, 234, 235, 236, - 0, 237, 238, 239, 240, 241, 242, 0, 243, 1171, - 245, 246, 247, 248, 249, 250, 998, 999, 0, 1000, - 0, 254, 1172, 1173, 257, 1174, 259, 260, 261, 262, - 263, 264, 0, 0, 265, 1175, 267, 1176, 0, 269, - 270, 271, 595, 596, 272, 273, 274, 275, 276, 1177, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 291, 292, 293, 294, 295, 1001, 1178, - 1002, 299, 300, 301, 302, 1003, 303, 304, 1179, 306, - 1004, 597, 308, 1005, 310, 311, 312, 0, 313, 314, - 0, 0, 1006, 316, 317, 0, 0, 318, 319, 1180, - 321, 1181, 599, 324, 325, 326, 327, 328, 329, 330, - 331, 332, 333, 0, 334, 335, 600, 337, 338, 339, - 340, 341, 342, 0, 343, 344, 345, 346, 347, 348, - 0, 349, 350, 351, 1007, 353, 354, 355, 356, 0, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - 367, 368, 369, 0, 370, 371, 1182, 373, 374, 375, - 1008, 377, 378, 379, 380, 381, 382, 383, 384, 385, - 386, 387, 0, 388, 389, 390, 391, 392, 1183, 394, - 395, 396, 397, 398, 1184, 400, 401, 1009, 403, 0, - 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 1185, 417, 603, 419, 0, 420, 421, 0, - 422, 1186, 424, 425, 426, 427, 428, 0, 1010, 1011, - 0, 0, 431, 432, 604, 434, 605, 1012, 436, 437, - 1187, 439, 440, 441, 442, 443, 0, 0, 444, 445, - 446, 447, 448, 1188, 0, 450, 451, 452, 453, 454, - 455, 1013, 1189, 457, 1190, 459, 460, 461, 462, 463, - 0, 0, 464, 0, 0, 465, 466, 467, 468, 469, - 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, 483, 484, 485, 1014, 0, 0, 0, - 0, 0, 0, 1015, 1016, 1191, 0, 0, 0, 0, - 1018, 0, 1019, 1192, 0, 0, 0, 1020, 1021, 1022, - 95, 976, 624, 977, 978, 979, 980, 981, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 96, 97, - 98, 99, 100, 101, 102, 103, 0, 104, 105, 106, - 0, 0, 0, 0, 982, 0, 0, 107, 108, 0, - 109, 110, 111, 112, 113, 114, 115, 116, 983, 118, - 984, 985, 0, 121, 122, 123, 124, 125, 126, 986, - 583, 127, 128, 987, 988, 131, 0, 132, 133, 134, - 135, 584, 0, 585, 0, 989, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 0, 148, 149, 150, 151, - 152, 153, 0, 154, 155, 156, 157, 586, 587, 588, - 589, 590, 591, 592, 163, 164, 165, 166, 167, 168, - 169, 990, 991, 172, 992, 173, 0, 174, 175, 176, - 177, 178, 179, 0, 180, 181, 182, 183, 184, 0, - 0, 185, 186, 754, 188, 189, 0, 190, 191, 192, - 0, 193, 194, 195, 0, 196, 197, 198, 199, 993, - 201, 202, 203, 204, 205, 593, 994, 207, 0, 208, - 209, 995, 211, 0, 212, 0, 213, 214, 19, 215, - 216, 217, 218, 219, 220, 0, 221, 0, 996, 997, - 224, 0, 225, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 0, 237, 238, 239, 240, 241, - 242, 0, 243, 244, 245, 246, 247, 248, 249, 250, - 998, 999, 0, 1000, 0, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 0, 0, 265, 266, - 267, 268, 0, 269, 270, 271, 595, 596, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, - 294, 295, 1001, 297, 1002, 299, 300, 301, 302, 1003, - 303, 304, 305, 306, 1004, 597, 308, 1005, 310, 311, - 312, 0, 313, 314, 0, 0, 1006, 316, 317, 0, - 0, 318, 319, 320, 321, 322, 599, 324, 325, 326, - 327, 328, 329, 330, 331, 332, 333, 0, 334, 335, - 600, 337, 338, 339, 340, 341, 342, 0, 343, 344, - 345, 346, 347, 348, 0, 349, 350, 351, 1007, 353, - 354, 355, 356, 0, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, 369, 0, 370, 371, - 372, 373, 374, 375, 1008, 377, 378, 379, 380, 381, - 382, 383, 384, 385, 386, 387, 27, 388, 389, 390, - 391, 392, 602, 394, 395, 396, 397, 398, 399, 400, - 401, 1009, 403, 0, 404, 405, 406, 407, 408, 409, - 410, 411, 412, 413, 414, 415, 416, 417, 603, 419, - 0, 420, 421, 32, 422, 423, 424, 425, 426, 427, - 428, 0, 1010, 1011, 0, 0, 431, 432, 604, 434, - 605, 1012, 436, 437, 606, 439, 440, 441, 442, 443, - 0, 0, 444, 445, 446, 447, 448, 607, 0, 450, - 451, 452, 453, 454, 608, 1013, 0, 457, 458, 459, - 460, 461, 462, 463, 0, 0, 464, 0, 36, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, - 1014, 0, 37, 0, 0, 0, 0, 1015, 1016, 0, - 0, 0, 0, 0, 1018, 0, 1019, 0, 0, 0, - 0, 1020, 1021, 1022, 95, 976, 624, 977, 978, 979, - 980, 981, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 96, 97, 98, 99, 100, 101, 102, 103, - 0, 104, 105, 106, 0, 0, 0, 0, 982, 0, - 0, 107, 108, 0, 109, 110, 111, 112, 113, 114, - 115, 116, 983, 118, 984, 985, 1432, 121, 122, 123, - 124, 125, 126, 986, 583, 127, 128, 987, 988, 131, - 0, 132, 133, 134, 135, 584, 0, 585, 0, 989, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 0, - 148, 149, 150, 151, 152, 153, 0, 154, 155, 156, - 157, 586, 587, 588, 589, 590, 591, 592, 163, 164, - 165, 166, 167, 168, 169, 990, 991, 172, 992, 173, - 0, 174, 175, 176, 177, 178, 179, 0, 180, 181, - 182, 183, 184, 0, 0, 185, 186, 754, 188, 189, - 0, 190, 191, 192, 0, 193, 194, 195, 0, 196, - 197, 198, 199, 993, 201, 202, 203, 204, 205, 593, - 994, 207, 0, 208, 209, 995, 211, 0, 212, 0, - 213, 214, 1433, 215, 216, 217, 218, 219, 220, 0, - 221, 0, 996, 997, 224, 0, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 0, 237, - 238, 239, 240, 241, 242, 0, 243, 244, 245, 246, - 247, 248, 249, 250, 998, 999, 0, 1000, 0, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 0, 1434, 265, 266, 267, 268, 0, 269, 270, 271, - 595, 596, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 1001, 297, 1002, 299, - 300, 301, 302, 1003, 303, 304, 305, 306, 1004, 597, - 308, 1005, 310, 311, 312, 0, 313, 314, 0, 0, - 1006, 316, 317, 0, 0, 318, 319, 320, 321, 322, - 599, 324, 325, 326, 327, 328, 329, 330, 331, 332, - 333, 0, 334, 335, 600, 337, 338, 339, 340, 341, - 342, 0, 343, 344, 345, 346, 347, 348, 0, 349, - 350, 351, 1007, 353, 354, 355, 356, 0, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, - 369, 0, 370, 371, 372, 373, 374, 375, 1008, 377, - 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 0, 388, 389, 390, 391, 392, 602, 394, 395, 396, - 397, 398, 399, 400, 401, 1009, 403, 0, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, - 416, 417, 603, 419, 0, 420, 421, 0, 422, 423, - 424, 425, 426, 427, 428, 0, 1010, 1011, 0, 1435, - 431, 432, 604, 434, 605, 1012, 436, 437, 606, 439, - 440, 441, 442, 443, 0, 0, 444, 445, 446, 447, - 448, 607, 0, 450, 451, 452, 453, 454, 455, 1013, - 0, 457, 458, 459, 460, 461, 462, 463, 0, 0, - 464, 0, 0, 465, 466, 467, 468, 469, 470, 471, - 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, - 482, 483, 484, 485, 1014, 0, 0, 0, 0, 0, - 0, 1015, 1016, 0, 0, 0, 0, 0, 1018, 0, - 1019, 0, 0, 0, 0, 1020, 1021, 1022, 95, 976, - 624, 977, 978, 979, 980, 981, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 96, 97, 98, 99, - 100, 101, 102, 103, -980, 104, 105, 106, 0, 0, - 0, -980, 982, 0, 0, 107, 108, 0, 109, 110, - 111, 112, 113, 114, 115, 116, 983, 118, 984, 985, - 0, 121, 122, 123, 124, 125, 126, 986, 583, 127, - 128, 987, 988, 131, 0, 132, 133, 134, 135, 584, - 0, 585, 0, 989, 139, 140, 141, 142, 143, 144, - 145, 146, 147, 0, 148, 149, 150, 151, 152, 153, - 0, 154, 155, 156, 157, 586, 587, 588, 589, 590, - 591, 592, 163, 164, 165, 166, 167, 168, 169, 990, - 991, 172, 992, 173, 0, 174, 175, 176, 177, 178, - 179, 0, 180, 181, 182, 183, 184, 0, 0, 185, - 186, 754, 188, 189, 0, 190, 191, 192, 0, 193, - 194, 195, 0, 196, 197, 198, 199, 993, 201, 202, - 203, 204, 205, 593, 994, 207, 0, 208, 209, 995, - 211, 0, 212, 0, 213, 214, 0, 215, 216, 217, - 218, 219, 220, 0, 221, 0, 996, 997, 224, 0, - 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, - 235, 236, 0, 237, 238, 239, 240, 241, 242, 0, - 243, 244, 245, 246, 247, 248, 249, 250, 998, 999, - 0, 1000, 0, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 0, 0, 265, 266, 267, 268, - 0, 269, 270, 271, 595, 596, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 1001, 297, 1002, 299, 300, 301, 302, 1003, 303, 304, - 305, 306, 1004, 597, 308, 1005, 310, 311, 312, 0, - 313, 314, 0, 0, 1006, 316, 317, 0, 0, 318, - 319, 320, 321, 322, 599, 324, 325, 326, 327, 328, - 329, 330, 331, 332, 333, 0, 334, 335, 600, 337, - 338, 339, 340, 341, 342, 0, 343, 344, 345, 346, - 347, 348, 0, 349, 350, 351, 1007, 353, 354, 355, - 356, 0, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 0, 370, 371, 372, 373, - 374, 375, 1008, 377, 378, 379, 380, 381, 382, 383, - 384, 385, 386, 387, 0, 388, 389, 390, 391, 392, - 602, 394, 395, 396, 397, 398, 399, 400, 401, 1009, - 403, -980, 404, 405, 406, 407, 408, 409, 410, 411, - 412, 413, 414, 415, 416, 417, 603, 419, 0, 420, - 421, 0, 422, 423, 424, 425, 426, 427, 428, 0, - 1010, 1011, 0, 0, 431, 432, 604, 434, 605, 1012, - 436, 437, 606, 439, 440, 441, 442, 443, 0, 0, - 444, 445, 446, 447, 448, 607, 0, 450, 451, 452, - 453, 454, 455, 1013, 0, 457, 458, 459, 460, 461, - 462, 463, 0, 0, 464, 0, 0, 465, 466, 467, - 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, - 478, 479, 480, 481, 482, 483, 484, 485, 1014, 0, - 0, 0, 0, 0, 0, 1015, 1016, 0, 0, 0, - 0, 0, 1018, 0, 1019, 0, 0, 0, 0, 1020, - 1021, 1022, 95, 976, 624, 977, 978, 979, 980, 981, + 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 1037, 306, 1038, 308, 309, 310, 311, + 1039, 312, 313, 314, 315, 1040, 620, 317, 1041, 319, + 320, 321, 0, 322, 323, 0, 0, 1042, 325, 326, + 0, 0, 327, 328, 329, 330, 331, 622, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 0, 343, + 344, 623, 346, 347, 348, 349, 350, 351, 352, 0, + 353, 354, 355, 356, 357, 358, 0, 359, 360, 361, + 1043, 363, 364, 365, 366, 0, 367, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378, 379, 0, + 380, 381, 382, 383, 384, 385, 1044, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, 29, 398, + 399, 400, 401, 402, 625, 404, 405, 406, 407, 408, + 409, 410, 411, 1045, 413, 0, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, + 626, 429, 0, 430, 431, 34, 432, 433, 434, 435, + 436, 437, 438, 0, 1046, 1047, 0, 0, 441, 442, + 627, 444, 628, 1048, 446, 447, 629, 449, 450, 451, + 452, 453, 0, 0, 454, 455, 456, 457, 458, 459, + 630, 0, 461, 462, 463, 464, 465, 631, 1049, 0, + 468, 469, 470, 471, 472, 473, 474, 0, 0, 475, + 0, 39, 476, 477, 478, 479, 480, 481, 482, 483, + 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, + 494, 495, 496, 1050, 0, 40, 0, 0, 0, 0, + 1051, 1052, 0, 0, 0, 0, 0, 1054, 0, 1055, + 2995, 0, 0, 0, 1056, 1057, 1058, 1059, 1193, 1012, + 515, 1013, 1014, 1015, 1016, 1017, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 105, 106, 107, 108, + 109, 110, 111, 112, 1194, 113, 114, 115, 0, 0, + 0, 0, 1018, 0, 0, 116, 117, 0, 118, 119, + 120, 1195, 122, 123, 124, 125, 1019, 1196, 1020, 1021, + 0, 130, 131, 132, 133, 134, 135, 1022, 606, 136, + 137, 1023, 1024, 140, 0, 141, 142, 143, 144, 607, + 0, 1197, 0, 1198, 148, 149, 150, 151, 152, 1199, + 154, 155, 156, 0, 157, 158, 159, 160, 161, 162, + 0, 1200, 164, 165, 166, 1201, 1202, 1203, 1204, 613, + 614, 1205, 172, 173, 174, 175, 176, 177, 178, 1026, + 1027, 181, 1028, 182, 0, 183, 184, 185, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 1206, 0, 194, + 195, 785, 197, 198, 0, 199, 200, 201, 0, 202, + 203, 204, 0, 205, 206, 207, 208, 1029, 210, 211, + 212, 213, 214, 616, 1030, 216, 0, 217, 218, 1031, + 220, 0, 221, 0, 222, 1207, 0, 1208, 225, 226, + 1209, 1210, 229, 0, 230, 0, 1032, 1033, 233, 0, + 234, 235, 236, 237, 238, 239, 240, 1211, 242, 243, + 244, 245, 0, 246, 247, 248, 249, 250, 251, 0, + 252, 1212, 254, 255, 256, 257, 258, 259, 1034, 1035, + 0, 1036, 0, 263, 1213, 1214, 266, 1215, 268, 269, + 270, 271, 272, 273, 0, 0, 274, 1216, 276, 1217, + 0, 278, 279, 280, 618, 619, 281, 282, 283, 284, + 285, 1218, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 1037, 1219, 1038, 308, 309, 310, 311, 1039, 312, 313, + 1220, 315, 1040, 620, 317, 1041, 319, 320, 321, 0, + 322, 323, 0, 0, 1042, 325, 326, 0, 0, 327, + 328, 1221, 330, 1222, 622, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 0, 343, 344, 623, 1223, + 347, 348, 349, 350, 351, 352, 0, 353, 354, 355, + 356, 357, 358, 0, 359, 360, 361, 1043, 363, 364, + 365, 366, 0, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 0, 380, 381, 1224, + 383, 384, 385, 1044, 387, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 0, 398, 399, 400, 401, + 402, 1225, 404, 405, 406, 407, 408, 1226, 410, 411, + 1045, 413, 0, 414, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 425, 1227, 427, 626, 429, 0, + 430, 431, 0, 432, 1228, 434, 435, 436, 437, 438, + 0, 1046, 1047, 0, 0, 441, 442, 627, 444, 628, + 1048, 446, 447, 1229, 449, 450, 451, 452, 453, 0, + 0, 454, 455, 456, 457, 458, 459, 1230, 0, 461, + 462, 463, 464, 465, 466, 1049, 1231, 468, 1232, 470, + 471, 472, 473, 474, 0, 0, 475, 0, 0, 476, + 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, + 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, + 1050, 0, 0, 0, 0, 0, 0, 1051, 1052, 1233, + 0, 0, 0, 0, 1054, 0, 1055, 1234, 0, 0, + 0, 1056, 1057, 1058, 1059, 104, 1012, 515, 1013, 1014, + 1015, 1016, 1017, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 105, 106, 107, 108, 109, 110, 111, + 112, 0, 113, 114, 115, 0, 0, 0, 0, 1018, + 0, 0, 116, 117, 0, 118, 119, 120, 121, 122, + 123, 124, 125, 1019, 127, 1020, 1021, 0, 130, 131, + 132, 133, 134, 135, 1022, 606, 136, 137, 1023, 1024, + 140, 0, 141, 142, 143, 144, 607, 0, 608, 0, + 1025, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 0, 157, 158, 159, 160, 161, 162, 0, 163, 164, + 165, 166, 609, 610, 611, 612, 613, 614, 615, 172, + 173, 174, 175, 176, 177, 178, 1026, 1027, 181, 1028, + 182, 0, 183, 184, 185, 186, 187, 188, 0, 189, + 190, 191, 192, 193, 0, 0, 194, 195, 785, 197, + 198, 0, 199, 200, 201, 0, 202, 203, 204, 0, + 205, 206, 207, 208, 1029, 210, 211, 212, 213, 214, + 616, 1030, 216, 0, 217, 218, 1031, 220, 0, 221, + 0, 222, 223, 21, 224, 225, 226, 227, 228, 229, + 0, 230, 0, 1032, 1033, 233, 0, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 0, + 246, 247, 248, 249, 250, 251, 0, 252, 253, 254, + 255, 256, 257, 258, 259, 1034, 1035, 0, 1036, 0, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 0, 0, 274, 275, 276, 277, 0, 278, 279, + 280, 618, 619, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 1037, 306, 1038, + 308, 309, 310, 311, 1039, 312, 313, 314, 315, 1040, + 620, 317, 1041, 319, 320, 321, 0, 322, 323, 0, + 0, 1042, 325, 326, 0, 0, 327, 328, 329, 330, + 331, 622, 333, 334, 335, 336, 337, 338, 339, 340, + 341, 342, 0, 343, 344, 623, 346, 347, 348, 349, + 350, 351, 352, 0, 353, 354, 355, 356, 357, 358, + 0, 359, 360, 361, 1043, 363, 364, 365, 366, 0, + 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, + 377, 378, 379, 0, 380, 381, 382, 383, 384, 385, + 1044, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 29, 398, 399, 400, 401, 402, 625, 404, + 405, 406, 407, 408, 409, 410, 411, 1045, 413, 0, + 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, + 424, 425, 426, 427, 626, 429, 0, 430, 431, 34, + 432, 433, 434, 435, 436, 437, 438, 0, 1046, 1047, + 0, 0, 441, 442, 627, 444, 628, 1048, 446, 447, + 629, 449, 450, 451, 452, 453, 0, 0, 454, 455, + 456, 457, 458, 459, 630, 0, 461, 462, 463, 464, + 465, 631, 1049, 0, 468, 469, 470, 471, 472, 473, + 474, 0, 0, 475, 0, 39, 476, 477, 478, 479, + 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, + 490, 491, 492, 493, 494, 495, 496, 1050, 0, 40, + 0, 0, 0, 0, 1051, 1052, 0, 0, 0, 0, + 0, 1054, 0, 1055, 0, 0, 0, 0, 1056, 1057, + 1058, 1059, 104, 1012, 515, 1013, 1014, 1015, 1016, 1017, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 96, 97, 98, 99, 100, 101, 102, 103, 1594, 104, - 105, 106, 0, 0, 0, 0, 982, 0, 0, 107, - 108, 0, 109, 110, 111, 112, 113, 114, 115, 116, - 983, 118, 984, 985, 0, 121, 122, 123, 124, 125, - 126, 986, 583, 127, 128, 987, 988, 131, 0, 132, - 133, 134, 135, 584, 0, 585, 0, 989, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 0, 148, 149, - 150, 151, 152, 153, 0, 154, 155, 156, 157, 586, - 587, 588, 589, 590, 591, 592, 163, 164, 165, 166, - 167, 168, 169, 990, 991, 172, 992, 173, 0, 174, - 175, 176, 177, 178, 179, 0, 180, 181, 182, 183, - 184, 0, 0, 185, 186, 754, 188, 189, 0, 190, - 191, 192, 0, 193, 194, 195, 0, 196, 197, 198, - 199, 993, 201, 202, 203, 204, 205, 593, 994, 207, - 0, 208, 209, 995, 211, 0, 212, 0, 213, 214, - 0, 215, 216, 217, 218, 219, 220, 0, 221, 0, - 996, 997, 224, 0, 225, 226, 227, 228, 229, 230, - 231, 232, 233, 234, 235, 236, 0, 237, 238, 239, - 240, 241, 242, 0, 243, 244, 245, 246, 247, 248, - 249, 250, 998, 999, 0, 1000, 0, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 0, 0, - 265, 266, 267, 268, 0, 269, 270, 271, 595, 596, - 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, 293, 294, 295, 1001, 297, 1002, 299, 300, 301, - 302, 1003, 303, 304, 305, 306, 1004, 597, 308, 1005, - 310, 311, 312, 0, 313, 314, 0, 0, 1006, 316, - 317, 0, 0, 318, 319, 320, 321, 322, 599, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 0, - 334, 335, 600, 337, 338, 339, 340, 341, 342, 0, - 343, 344, 345, 346, 347, 348, 0, 349, 350, 351, - 1007, 353, 354, 355, 356, 0, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, 369, 0, - 370, 371, 372, 373, 374, 375, 1008, 377, 378, 379, - 380, 381, 382, 383, 384, 385, 386, 387, 0, 388, - 389, 390, 391, 392, 602, 394, 395, 396, 397, 398, - 399, 400, 401, 1009, 403, 0, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, - 603, 419, 0, 420, 421, 0, 422, 423, 424, 425, - 426, 427, 428, 0, 1010, 1011, 0, 0, 431, 432, - 604, 434, 605, 1012, 436, 437, 606, 439, 440, 441, - 442, 443, 0, 0, 444, 445, 446, 447, 448, 607, - 0, 450, 451, 452, 453, 454, 455, 1013, 0, 457, - 458, 459, 460, 461, 462, 463, 0, 0, 464, 0, - 0, 465, 466, 467, 468, 469, 470, 471, 472, 473, - 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, - 484, 485, 1014, 0, 0, 0, 0, 0, 0, 1015, - 1016, 1595, 0, 0, 0, 0, 1018, 0, 1019, 0, - 0, 0, 0, 1020, 1021, 1022, 95, 976, 624, 977, - 978, 979, 980, 981, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 96, 97, 98, 99, 100, 101, - 102, 103, 2771, 104, 105, 106, 0, 0, 0, 0, - 982, 0, 0, 107, 108, 0, 109, 110, 111, 112, - 113, 114, 115, 116, 983, 118, 984, 985, 0, 121, - 122, 123, 124, 125, 126, 986, 583, 127, 128, 987, - 988, 131, 0, 132, 133, 134, 135, 584, 0, 585, - 0, 989, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 0, 148, 149, 150, 151, 152, 153, 0, 154, - 155, 2772, 157, 586, 587, 588, 589, 590, 591, 592, - 163, 164, 165, 166, 167, 168, 169, 990, 991, 172, - 992, 173, 0, 174, 175, 176, 177, 178, 179, 0, - 180, 181, 182, 183, 184, 0, 0, 185, 186, 754, - 188, 189, 0, 190, 191, 192, 0, 193, 194, 195, - 0, 196, 197, 198, 199, 993, 201, 202, 203, 204, - 205, 593, 994, 207, 0, 208, 209, 995, 211, 0, - 212, 0, 213, 214, 0, 215, 216, 217, 218, 219, - 220, 0, 221, 0, 2773, 997, 224, 0, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 0, 237, 238, 239, 240, 241, 242, 0, 243, 244, - 245, 246, 247, 248, 249, 250, 998, 999, 0, 1000, - 0, 254, 255, 256, 257, 258, 259, 260, 261, 262, - 263, 264, 0, 0, 265, 266, 267, 268, 0, 269, - 270, 271, 595, 596, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 291, 292, 293, 294, 295, 1001, 297, - 1002, 299, 300, 301, 302, 1003, 303, 304, 305, 306, - 1004, 597, 308, 1005, 310, 311, 312, 0, 313, 314, - 0, 0, 1006, 316, 317, 0, 0, 318, 319, 320, - 321, 322, 599, 324, 325, 326, 327, 328, 329, 330, - 331, 332, 333, 0, 334, 335, 600, 337, 338, 339, - 340, 341, 342, 0, 343, 344, 345, 346, 347, 348, - 0, 349, 350, 351, 1007, 353, 354, 355, 356, 0, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - 367, 368, 369, 0, 370, 371, 372, 373, 374, 2774, - 1008, 377, 378, 379, 380, 381, 382, 383, 384, 385, - 386, 387, 0, 388, 389, 390, 391, 392, 602, 394, - 395, 396, 397, 398, 399, 400, 401, 1009, 403, 0, - 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 416, 417, 603, 419, 0, 420, 421, 0, - 422, 423, 424, 425, 426, 427, 428, 0, 1010, 1011, - 0, 0, 431, 432, 604, 434, 605, 1012, 436, 437, - 606, 439, 440, 441, 442, 443, 0, 0, 444, 445, - 446, 447, 448, 607, 0, 450, 451, 452, 453, 454, - 455, 1013, 0, 457, 458, 459, 460, 461, 462, 463, - 0, 0, 464, 0, 0, 465, 466, 467, 468, 469, - 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, 483, 484, 485, 1014, 0, 0, 0, - 0, 0, 0, 1015, 1016, 2775, 0, 0, 0, 0, - 1018, 0, 2776, 0, 0, 0, 0, 1020, 1021, 1022, - 95, 976, 624, 977, 978, 979, 980, 981, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 96, 97, - 98, 99, 100, 101, 102, 103, 0, 104, 105, 106, - 0, 0, 0, 0, 982, 0, 0, 107, 108, 0, - 109, 110, 111, 112, 113, 114, 115, 116, 983, 118, - 984, 985, 0, 121, 122, 123, 124, 125, 126, 986, - 583, 127, 128, 987, 988, 131, 0, 132, 133, 134, - 135, 584, 0, 585, 0, 989, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 0, 148, 149, 150, 151, - 152, 153, 0, 154, 155, 156, 157, 586, 587, 588, - 589, 590, 591, 592, 163, 164, 165, 166, 167, 168, - 169, 990, 991, 172, 992, 173, 0, 174, 175, 176, - 177, 178, 179, 0, 180, 181, 182, 183, 184, 0, - 0, 185, 186, 754, 188, 189, 0, 190, 191, 192, - 0, 193, 194, 195, 0, 196, 197, 198, 199, 993, - 201, 202, 203, 204, 205, 593, 994, 207, 0, 208, - 209, 995, 211, 0, 212, 0, 213, 214, 0, 215, - 216, 217, 218, 219, 220, 0, 221, 0, 996, 997, - 224, 0, 225, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 0, 237, 238, 239, 240, 241, - 242, 0, 243, 244, 245, 246, 247, 248, 249, 250, - 998, 999, 0, 1000, 0, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 0, 0, 265, 266, - 267, 268, 0, 269, 270, 271, 595, 596, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 105, 106, 107, 108, 109, 110, 111, 112, 0, 113, + 114, 115, 0, 0, 0, 0, 1018, 0, 0, 116, + 117, 0, 118, 119, 120, 121, 122, 123, 124, 125, + 1019, 127, 1020, 1021, 1483, 130, 131, 132, 133, 134, + 135, 1022, 606, 136, 137, 1023, 1024, 140, 0, 141, + 142, 143, 144, 607, 0, 608, 0, 1025, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 0, 157, 158, + 159, 160, 161, 162, 0, 163, 164, 165, 166, 609, + 610, 611, 612, 613, 614, 615, 172, 173, 174, 175, + 176, 177, 178, 1026, 1027, 181, 1028, 182, 0, 183, + 184, 185, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 0, 0, 194, 195, 785, 197, 198, 0, 199, + 200, 201, 0, 202, 203, 204, 0, 205, 206, 207, + 208, 1029, 210, 211, 212, 213, 214, 616, 1030, 216, + 0, 217, 218, 1031, 220, 0, 221, 0, 222, 223, + 1484, 224, 225, 226, 227, 228, 229, 0, 230, 0, + 1032, 1033, 233, 0, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 0, 246, 247, 248, + 249, 250, 251, 0, 252, 253, 254, 255, 256, 257, + 258, 259, 1034, 1035, 0, 1036, 0, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 273, 0, 1485, + 274, 275, 276, 277, 0, 278, 279, 280, 618, 619, + 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 1037, 306, 1038, 308, 309, 310, + 311, 1039, 312, 313, 314, 315, 1040, 620, 317, 1041, + 319, 320, 321, 0, 322, 323, 0, 0, 1042, 325, + 326, 0, 0, 327, 328, 329, 330, 331, 622, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 0, + 343, 344, 623, 346, 347, 348, 349, 350, 351, 352, + 0, 353, 354, 355, 356, 357, 358, 0, 359, 360, + 361, 1043, 363, 364, 365, 366, 0, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 0, 380, 381, 382, 383, 384, 385, 1044, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 0, + 398, 399, 400, 401, 402, 625, 404, 405, 406, 407, + 408, 409, 410, 411, 1045, 413, 0, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, + 427, 626, 429, 0, 430, 431, 0, 432, 433, 434, + 435, 436, 437, 438, 0, 1046, 1047, 0, 1486, 441, + 442, 627, 444, 628, 1048, 446, 447, 629, 449, 450, + 451, 452, 453, 0, 0, 454, 455, 456, 457, 458, + 459, 630, 0, 461, 462, 463, 464, 465, 466, 1049, + 0, 468, 469, 470, 471, 472, 473, 474, 0, 0, + 475, 0, 0, 476, 477, 478, 479, 480, 481, 482, + 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, + 493, 494, 495, 496, 1050, 0, 0, 0, 0, 0, + 0, 1051, 1052, 0, 0, 0, 0, 0, 1054, 0, + 1055, 0, 0, 0, 0, 1056, 1057, 1058, 1059, 104, + 1012, 515, 1013, 1014, 1015, 1016, 1017, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 105, 106, 107, + 108, 109, 110, 111, 112, -1002, 113, 114, 115, 0, + 0, 0, -1002, 1018, 0, 0, 116, 117, 0, 118, + 119, 120, 121, 122, 123, 124, 125, 1019, 127, 1020, + 1021, 0, 130, 131, 132, 133, 134, 135, 1022, 606, + 136, 137, 1023, 1024, 140, 0, 141, 142, 143, 144, + 607, 0, 608, 0, 1025, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 0, 157, 158, 159, 160, 161, + 162, 0, 163, 164, 165, 166, 609, 610, 611, 612, + 613, 614, 615, 172, 173, 174, 175, 176, 177, 178, + 1026, 1027, 181, 1028, 182, 0, 183, 184, 185, 186, + 187, 188, 0, 189, 190, 191, 192, 193, 0, 0, + 194, 195, 785, 197, 198, 0, 199, 200, 201, 0, + 202, 203, 204, 0, 205, 206, 207, 208, 1029, 210, + 211, 212, 213, 214, 616, 1030, 216, 0, 217, 218, + 1031, 220, 0, 221, 0, 222, 223, 0, 224, 225, + 226, 227, 228, 229, 0, 230, 0, 1032, 1033, 233, + 0, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 0, 246, 247, 248, 249, 250, 251, + 0, 252, 253, 254, 255, 256, 257, 258, 259, 1034, + 1035, 0, 1036, 0, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 0, 0, 274, 275, 276, + 277, 0, 278, 279, 280, 618, 619, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, - 294, 295, 1001, 297, 1002, 299, 300, 301, 302, 1003, - 303, 304, 305, 306, 1004, 597, 308, 1005, 310, 311, - 312, 0, 313, 314, 0, 0, 1006, 316, 317, 0, - 0, 318, 319, 320, 321, 322, 599, 324, 325, 326, - 327, 328, 329, 330, 331, 332, 333, 0, 334, 335, - 600, 337, 338, 339, 340, 341, 342, 0, 343, 344, - 345, 346, 347, 348, 0, 349, 350, 351, 1007, 353, - 354, 355, 356, 0, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, 369, 0, 370, 371, - 372, 373, 374, 375, 1008, 377, 378, 379, 380, 381, - 382, 383, 384, 385, 386, 387, 0, 388, 389, 390, - 391, 392, 602, 394, 395, 396, 397, 398, 399, 400, - 401, 1009, 403, 0, 404, 405, 406, 407, 408, 409, - 410, 411, 412, 413, 414, 415, 416, 417, 603, 419, - 0, 420, 421, 0, 422, 423, 424, 425, 426, 427, - 428, 0, 1010, 1011, 0, 0, 431, 432, 604, 434, - 605, 1012, 436, 437, 606, 439, 440, 441, 442, 443, - 0, 0, 444, 445, 446, 447, 448, 607, 0, 450, - 451, 452, 453, 454, 455, 1013, 0, 457, 458, 459, - 460, 461, 462, 463, 0, 0, 464, 0, 0, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 1037, 306, 1038, 308, 309, 310, 311, 1039, 312, + 313, 314, 315, 1040, 620, 317, 1041, 319, 320, 321, + 0, 322, 323, 0, 0, 1042, 325, 326, 0, 0, + 327, 328, 329, 330, 331, 622, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 0, 343, 344, 623, + 346, 347, 348, 349, 350, 351, 352, 0, 353, 354, + 355, 356, 357, 358, 0, 359, 360, 361, 1043, 363, + 364, 365, 366, 0, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378, 379, 0, 380, 381, + 382, 383, 384, 385, 1044, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, 0, 398, 399, 400, + 401, 402, 625, 404, 405, 406, 407, 408, 409, 410, + 411, 1045, 413, -1002, 414, 415, 416, 417, 418, 419, + 420, 421, 422, 423, 424, 425, 426, 427, 626, 429, + 0, 430, 431, 0, 432, 433, 434, 435, 436, 437, + 438, 0, 1046, 1047, 0, 0, 441, 442, 627, 444, + 628, 1048, 446, 447, 629, 449, 450, 451, 452, 453, + 0, 0, 454, 455, 456, 457, 458, 459, 630, 0, + 461, 462, 463, 464, 465, 466, 1049, 0, 468, 469, + 470, 471, 472, 473, 474, 0, 0, 475, 0, 0, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, - 1014, 0, 0, 0, 0, 0, 0, 1015, 1016, 1017, - 0, 0, 0, 0, 1018, 0, 1019, 0, 0, 0, - 0, 1020, 1021, 1022, 95, 1610, 624, 977, 978, 979, - 1611, 981, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 96, 97, 98, 99, 100, 101, 102, 103, - 1612, 104, 105, 106, 0, 0, 0, 0, 982, 0, - 0, 107, 108, 0, 109, 110, 111, 112, 113, 114, - 115, 116, 983, 118, 984, 985, 0, 121, 122, 123, - 124, 125, 126, 986, 583, 127, 128, 987, 988, 131, - 0, 132, 133, 134, 135, 584, 0, 585, 0, 989, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 0, - 148, 149, 150, 151, 152, 153, 0, 154, 155, 156, - 157, 586, 587, 588, 589, 590, 591, 592, 163, 164, - 165, 166, 167, 168, 169, 990, 991, 172, 992, 173, - 0, 174, 175, 176, 177, 178, 179, 0, 180, 181, - 182, 183, 184, 0, 0, 185, 186, 754, 188, 189, - 0, 190, 191, 192, 0, 193, 194, 195, 0, 196, - 197, 198, 199, 993, 201, 202, 203, 204, 205, 593, - 994, 207, 0, 208, 209, 995, 211, 0, 212, 0, - 213, 214, 0, 215, 216, 217, 218, 219, 220, 0, - 221, 0, 996, 997, 224, 0, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 0, 237, - 238, 239, 240, 241, 242, 0, 243, 244, 245, 246, - 247, 248, 249, 250, 998, 999, 0, 1000, 0, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 0, 0, 265, 266, 267, 268, 0, 269, 270, 271, - 595, 596, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 1001, 297, 1002, 299, - 300, 301, 302, 1003, 303, 304, 305, 306, 1004, 597, - 308, 1005, 310, 311, 312, 0, 313, 314, 0, 0, - 1006, 316, 317, 0, 0, 318, 319, 320, 321, 322, - 599, 324, 325, 326, 327, 328, 329, 330, 331, 332, - 333, 0, 334, 335, 600, 337, 338, 339, 340, 341, - 342, 0, 343, 344, 345, 346, 347, 348, 0, 349, - 350, 351, 1007, 353, 354, 355, 356, 0, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, - 369, 0, 370, 371, 372, 373, 374, 375, 1008, 377, - 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 0, 388, 389, 390, 391, 392, 602, 394, 395, 396, - 397, 398, 399, 400, 401, 1009, 403, 0, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, - 416, 417, 603, 419, 0, 420, 421, 0, 422, 423, - 424, 425, 426, 427, 428, 0, 1010, 1011, 0, 0, - 431, 432, 604, 434, 605, 1012, 436, 437, 606, 439, - 440, 441, 442, 443, 0, 0, 444, 445, 446, 447, - 448, 607, 0, 450, 451, 452, 453, 454, 455, 1013, - 0, 457, 458, 459, 460, 461, 462, 463, 0, 0, - 464, 0, 0, 465, 466, 467, 468, 469, 470, 471, - 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, - 482, 483, 484, 485, 1014, 0, 0, 0, 0, 0, - 0, 1015, 1016, 0, 0, 0, 0, 0, 1018, 0, - 1019, 0, 0, 0, 0, 1020, 1021, 1022, 95, 976, - 624, 977, 978, 979, 980, 981, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 96, 97, 98, 99, - 100, 101, 102, 103, 0, 104, 105, 106, 0, 0, - 0, 0, 982, 0, 0, 107, 108, 0, 109, 110, - 111, 112, 113, 114, 115, 116, 983, 118, 984, 985, - 0, 121, 122, 123, 124, 125, 126, 986, 583, 127, - 128, 987, 988, 131, 0, 132, 133, 134, 135, 584, - 0, 585, 0, 989, 139, 140, 141, 142, 143, 144, - 145, 146, 147, 0, 148, 149, 150, 151, 152, 153, - 0, 154, 155, 156, 157, 586, 587, 588, 589, 590, - 591, 592, 163, 164, 165, 166, 167, 168, 169, 990, - 991, 172, 992, 173, 0, 174, 175, 176, 177, 178, - 179, 0, 180, 181, 182, 183, 184, 0, 0, 185, - 186, 754, 188, 189, 0, 190, 191, 192, 0, 193, - 194, 195, 0, 196, 197, 198, 199, 993, 201, 202, - 203, 204, 205, 593, 994, 207, 0, 208, 209, 995, - 211, 0, 212, 0, 213, 214, 1433, 215, 216, 217, - 218, 219, 220, 0, 221, 0, 996, 997, 224, 0, - 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, - 235, 236, 0, 237, 238, 239, 240, 241, 242, 0, - 243, 244, 245, 246, 247, 248, 249, 250, 998, 999, - 0, 1000, 0, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 0, 0, 265, 266, 267, 268, - 0, 269, 270, 271, 595, 596, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, + 496, 1050, 0, 0, 0, 0, 0, 0, 1051, 1052, + 0, 0, 0, 0, 0, 1054, 0, 1055, 0, 0, + 0, 0, 1056, 1057, 1058, 1059, 104, 1012, 515, 1013, + 1014, 1015, 1016, 1017, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 105, 106, 107, 108, 109, 110, + 111, 112, 1647, 113, 114, 115, 0, 0, 0, 0, + 1018, 0, 0, 116, 117, 0, 118, 119, 120, 121, + 122, 123, 124, 125, 1019, 127, 1020, 1021, 0, 130, + 131, 132, 133, 134, 135, 1022, 606, 136, 137, 1023, + 1024, 140, 0, 141, 142, 143, 144, 607, 0, 608, + 0, 1025, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 0, 157, 158, 159, 160, 161, 162, 0, 163, + 164, 165, 166, 609, 610, 611, 612, 613, 614, 615, + 172, 173, 174, 175, 176, 177, 178, 1026, 1027, 181, + 1028, 182, 0, 183, 184, 185, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 0, 0, 194, 195, 785, + 197, 198, 0, 199, 200, 201, 0, 202, 203, 204, + 0, 205, 206, 207, 208, 1029, 210, 211, 212, 213, + 214, 616, 1030, 216, 0, 217, 218, 1031, 220, 0, + 221, 0, 222, 223, 0, 224, 225, 226, 227, 228, + 229, 0, 230, 0, 1032, 1033, 233, 0, 234, 235, + 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, + 0, 246, 247, 248, 249, 250, 251, 0, 252, 253, + 254, 255, 256, 257, 258, 259, 1034, 1035, 0, 1036, + 0, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 0, 0, 274, 275, 276, 277, 0, 278, + 279, 280, 618, 619, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 1037, 306, + 1038, 308, 309, 310, 311, 1039, 312, 313, 314, 315, + 1040, 620, 317, 1041, 319, 320, 321, 0, 322, 323, + 0, 0, 1042, 325, 326, 0, 0, 327, 328, 329, + 330, 331, 622, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 0, 343, 344, 623, 346, 347, 348, + 349, 350, 351, 352, 0, 353, 354, 355, 356, 357, + 358, 0, 359, 360, 361, 1043, 363, 364, 365, 366, + 0, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 0, 380, 381, 382, 383, 384, + 385, 1044, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 0, 398, 399, 400, 401, 402, 625, + 404, 405, 406, 407, 408, 409, 410, 411, 1045, 413, + 0, 414, 415, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, 626, 429, 0, 430, 431, + 0, 432, 433, 434, 435, 436, 437, 438, 0, 1046, + 1047, 0, 0, 441, 442, 627, 444, 628, 1048, 446, + 447, 629, 449, 450, 451, 452, 453, 0, 0, 454, + 455, 456, 457, 458, 459, 630, 0, 461, 462, 463, + 464, 465, 466, 1049, 0, 468, 469, 470, 471, 472, + 473, 474, 0, 0, 475, 0, 0, 476, 477, 478, + 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, + 489, 490, 491, 492, 493, 494, 495, 496, 1050, 0, + 0, 0, 0, 0, 0, 1051, 1052, 1648, 0, 0, + 0, 0, 1054, 0, 1055, 0, 0, 0, 0, 1056, + 1057, 1058, 1059, 104, 1012, 515, 1013, 1014, 1015, 1016, + 1017, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 105, 106, 107, 108, 109, 110, 111, 112, 2842, + 113, 114, 115, 0, 0, 0, 0, 1018, 0, 0, + 116, 117, 0, 118, 119, 120, 121, 122, 123, 124, + 125, 1019, 127, 1020, 1021, 0, 130, 131, 132, 133, + 134, 135, 1022, 606, 136, 137, 1023, 1024, 140, 0, + 141, 142, 143, 144, 607, 0, 608, 0, 1025, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 0, 157, + 158, 159, 160, 161, 162, 0, 163, 164, 2843, 166, + 609, 610, 611, 612, 613, 614, 615, 172, 173, 174, + 175, 176, 177, 178, 1026, 1027, 181, 1028, 182, 0, + 183, 184, 185, 186, 187, 188, 0, 189, 190, 191, + 192, 193, 0, 0, 194, 195, 785, 197, 198, 0, + 199, 200, 201, 0, 202, 203, 204, 0, 205, 206, + 207, 208, 1029, 210, 211, 212, 213, 214, 616, 1030, + 216, 0, 217, 218, 1031, 220, 0, 221, 0, 222, + 223, 0, 224, 225, 226, 227, 228, 229, 0, 230, + 0, 2844, 1033, 233, 0, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 0, 246, 247, + 248, 249, 250, 251, 0, 252, 253, 254, 255, 256, + 257, 258, 259, 1034, 1035, 0, 1036, 0, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 0, + 0, 274, 275, 276, 277, 0, 278, 279, 280, 618, + 619, 281, 282, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 1037, 306, 1038, 308, 309, + 310, 311, 1039, 312, 313, 314, 315, 1040, 620, 317, + 1041, 319, 320, 321, 0, 322, 323, 0, 0, 1042, + 325, 326, 0, 0, 327, 328, 329, 330, 331, 622, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 0, 343, 344, 623, 346, 347, 348, 349, 350, 351, + 352, 0, 353, 354, 355, 356, 357, 358, 0, 359, + 360, 361, 1043, 363, 364, 365, 366, 0, 367, 368, + 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, + 379, 0, 380, 381, 382, 383, 384, 2845, 1044, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + 0, 398, 399, 400, 401, 402, 625, 404, 405, 406, + 407, 408, 409, 410, 411, 1045, 413, 0, 414, 415, + 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, + 426, 427, 626, 429, 0, 430, 431, 0, 432, 433, + 434, 435, 436, 437, 438, 0, 1046, 1047, 0, 0, + 441, 442, 627, 444, 628, 1048, 446, 447, 629, 449, + 450, 451, 452, 453, 0, 0, 454, 455, 456, 457, + 458, 459, 630, 0, 461, 462, 463, 464, 465, 466, + 1049, 0, 468, 469, 470, 471, 472, 473, 474, 0, + 0, 475, 0, 0, 476, 477, 478, 479, 480, 481, + 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, + 492, 493, 494, 495, 496, 1050, 0, 0, 0, 0, + 0, 0, 1051, 1052, 2846, 0, 0, 0, 0, 1054, + 0, 2847, 0, 0, 0, 0, 1056, 1057, 1058, 1059, + 104, 1012, 515, 1013, 1014, 1015, 1016, 1017, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 105, 106, + 107, 108, 109, 110, 111, 112, 0, 113, 114, 115, + 0, 0, 0, 0, 1018, 0, 0, 116, 117, 0, + 118, 119, 120, 121, 122, 123, 124, 125, 1019, 127, + 1020, 1021, 0, 130, 131, 132, 133, 134, 135, 1022, + 606, 136, 137, 1023, 1024, 140, 0, 141, 142, 143, + 144, 607, 0, 608, 0, 1025, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 0, 157, 158, 159, 160, + 161, 162, 0, 163, 164, 165, 166, 609, 610, 611, + 612, 613, 614, 615, 172, 173, 174, 175, 176, 177, + 178, 1026, 1027, 181, 1028, 182, 0, 183, 184, 185, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 0, + 0, 194, 195, 785, 197, 198, 0, 199, 200, 201, + 0, 202, 203, 204, 0, 205, 206, 207, 208, 1029, + 210, 211, 212, 213, 214, 616, 1030, 216, 0, 217, + 218, 1031, 220, 0, 221, 0, 222, 223, 0, 224, + 225, 226, 227, 228, 229, 0, 230, 0, 1032, 1033, + 233, 0, 234, 235, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 0, 246, 247, 248, 249, 250, + 251, 0, 252, 253, 254, 255, 256, 257, 258, 259, + 1034, 1035, 0, 1036, 0, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 0, 0, 274, 275, + 276, 277, 0, 278, 279, 280, 618, 619, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 1037, 306, 1038, 308, 309, 310, 311, 1039, + 312, 313, 314, 315, 1040, 620, 317, 1041, 319, 320, + 321, 0, 322, 323, 0, 0, 1042, 325, 326, 0, + 0, 327, 328, 329, 330, 331, 622, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 0, 343, 344, + 623, 346, 347, 348, 349, 350, 351, 352, 0, 353, + 354, 355, 356, 357, 358, 0, 359, 360, 361, 1043, + 363, 364, 365, 366, 0, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 0, 380, + 381, 382, 383, 384, 385, 1044, 387, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 0, 398, 399, + 400, 401, 402, 625, 404, 405, 406, 407, 408, 409, + 410, 411, 1045, 413, 0, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 426, 427, 626, + 429, 0, 430, 431, 0, 432, 433, 434, 435, 436, + 437, 438, 0, 1046, 1047, 0, 0, 441, 442, 627, + 444, 628, 1048, 446, 447, 629, 449, 450, 451, 452, + 453, 0, 0, 454, 455, 456, 457, 458, 459, 630, + 0, 461, 462, 463, 464, 465, 466, 1049, 0, 468, + 469, 470, 471, 472, 473, 474, 0, 0, 475, 0, + 0, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, + 495, 496, 1050, 0, 0, 0, 0, 0, 0, 1051, + 1052, 1053, 0, 0, 0, 0, 1054, 0, 1055, 0, + 0, 0, 0, 1056, 1057, 1058, 1059, 104, 1663, 515, + 1013, 1014, 1015, 1664, 1017, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 105, 106, 107, 108, 109, + 110, 111, 112, 1665, 113, 114, 115, 0, 0, 0, + 0, 1018, 0, 0, 116, 117, 0, 118, 119, 120, + 121, 122, 123, 124, 125, 1019, 127, 1020, 1021, 0, + 130, 131, 132, 133, 134, 135, 1022, 606, 136, 137, + 1023, 1024, 140, 0, 141, 142, 143, 144, 607, 0, + 608, 0, 1025, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 0, 157, 158, 159, 160, 161, 162, 0, + 163, 164, 165, 166, 609, 610, 611, 612, 613, 614, + 615, 172, 173, 174, 175, 176, 177, 178, 1026, 1027, + 181, 1028, 182, 0, 183, 184, 185, 186, 187, 188, + 0, 189, 190, 191, 192, 193, 0, 0, 194, 195, + 785, 197, 198, 0, 199, 200, 201, 0, 202, 203, + 204, 0, 205, 206, 207, 208, 1029, 210, 211, 212, + 213, 214, 616, 1030, 216, 0, 217, 218, 1031, 220, + 0, 221, 0, 222, 223, 0, 224, 225, 226, 227, + 228, 229, 0, 230, 0, 1032, 1033, 233, 0, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 0, 246, 247, 248, 249, 250, 251, 0, 252, + 253, 254, 255, 256, 257, 258, 259, 1034, 1035, 0, + 1036, 0, 263, 264, 265, 266, 267, 268, 269, 270, + 271, 272, 273, 0, 0, 274, 275, 276, 277, 0, + 278, 279, 280, 618, 619, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 1001, 297, 1002, 299, 300, 301, 302, 1003, 303, 304, - 305, 306, 1004, 597, 308, 1005, 310, 311, 312, 0, - 313, 314, 0, 0, 1006, 316, 317, 0, 0, 318, - 319, 320, 321, 322, 599, 324, 325, 326, 327, 328, - 329, 330, 331, 332, 333, 0, 334, 335, 600, 337, - 338, 339, 340, 341, 342, 0, 343, 344, 345, 346, - 347, 348, 0, 349, 350, 351, 1007, 353, 354, 355, - 356, 0, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 0, 370, 371, 372, 373, - 374, 375, 1008, 377, 378, 379, 380, 381, 382, 383, - 384, 385, 386, 387, 0, 388, 389, 390, 391, 392, - 602, 394, 395, 396, 397, 398, 399, 400, 401, 1009, - 403, 0, 404, 405, 406, 407, 408, 409, 410, 411, - 412, 413, 414, 415, 416, 417, 603, 419, 0, 420, - 421, 0, 422, 423, 424, 425, 426, 427, 428, 0, - 1010, 1011, 0, 0, 431, 432, 604, 434, 605, 1012, - 436, 437, 606, 439, 440, 441, 442, 443, 0, 0, - 444, 445, 446, 447, 448, 607, 0, 450, 451, 452, - 453, 454, 455, 1013, 0, 457, 458, 459, 460, 461, - 462, 463, 0, 0, 464, 0, 0, 465, 466, 467, - 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, - 478, 479, 480, 481, 482, 483, 484, 485, 1014, 0, - 0, 0, 0, 0, 0, 1015, 1016, 0, 0, 0, - 0, 0, 1018, 0, 1019, 0, 0, 0, 0, 1020, - 1021, 1022, 95, 976, 624, 977, 978, 979, 980, 981, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 96, 97, 98, 99, 100, 101, 102, 103, 0, 104, - 105, 106, 0, 0, 0, 0, 982, 0, 0, 107, - 108, 0, 109, 110, 111, 112, 113, 114, 115, 116, - 983, 118, 984, 985, 0, 121, 122, 123, 124, 125, - 126, 986, 583, 127, 128, 987, 988, 131, 0, 132, - 133, 134, 135, 584, 0, 585, 0, 989, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 0, 148, 149, - 150, 151, 152, 153, 0, 154, 155, 156, 157, 586, - 587, 588, 589, 590, 591, 592, 163, 164, 165, 166, - 167, 168, 169, 990, 991, 172, 992, 173, 0, 174, - 175, 176, 177, 178, 179, 0, 180, 181, 182, 183, - 184, 0, 0, 185, 186, 754, 188, 189, 0, 190, - 191, 192, 0, 193, 194, 195, 0, 196, 197, 198, - 199, 993, 201, 202, 203, 204, 205, 593, 994, 207, - 0, 208, 209, 995, 211, 0, 212, 0, 213, 214, - 0, 215, 216, 217, 218, 219, 220, 0, 221, 0, - 996, 997, 224, 0, 225, 226, 227, 228, 229, 230, - 231, 232, 233, 234, 235, 236, 0, 237, 238, 239, - 240, 241, 242, 0, 243, 244, 245, 246, 247, 248, - 249, 250, 998, 999, 0, 1000, 0, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 0, 0, - 265, 266, 267, 268, 0, 269, 270, 271, 595, 596, - 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 1037, + 306, 1038, 308, 309, 310, 311, 1039, 312, 313, 314, + 315, 1040, 620, 317, 1041, 319, 320, 321, 0, 322, + 323, 0, 0, 1042, 325, 326, 0, 0, 327, 328, + 329, 330, 331, 622, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342, 0, 343, 344, 623, 346, 347, + 348, 349, 350, 351, 352, 0, 353, 354, 355, 356, + 357, 358, 0, 359, 360, 361, 1043, 363, 364, 365, + 366, 0, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 0, 380, 381, 382, 383, + 384, 385, 1044, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 0, 398, 399, 400, 401, 402, + 625, 404, 405, 406, 407, 408, 409, 410, 411, 1045, + 413, 0, 414, 415, 416, 417, 418, 419, 420, 421, + 422, 423, 424, 425, 426, 427, 626, 429, 0, 430, + 431, 0, 432, 433, 434, 435, 436, 437, 438, 0, + 1046, 1047, 0, 0, 441, 442, 627, 444, 628, 1048, + 446, 447, 629, 449, 450, 451, 452, 453, 0, 0, + 454, 455, 456, 457, 458, 459, 630, 0, 461, 462, + 463, 464, 465, 466, 1049, 0, 468, 469, 470, 471, + 472, 473, 474, 0, 0, 475, 0, 0, 476, 477, + 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, + 488, 489, 490, 491, 492, 493, 494, 495, 496, 1050, + 0, 0, 0, 0, 0, 0, 1051, 1052, 0, 0, + 0, 0, 0, 1054, 0, 1055, 0, 0, 0, 0, + 1056, 1057, 1058, 1059, 104, 1012, 515, 1013, 1014, 1015, + 1016, 1017, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 105, 106, 107, 108, 109, 110, 111, 112, + 0, 113, 114, 115, 0, 0, 0, 0, 1018, 0, + 0, 116, 117, 0, 118, 119, 120, 121, 122, 123, + 124, 125, 1019, 127, 1020, 1021, 0, 130, 131, 132, + 133, 134, 135, 1022, 606, 136, 137, 1023, 1024, 140, + 0, 141, 142, 143, 144, 607, 0, 608, 0, 1025, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 0, + 157, 158, 159, 160, 161, 162, 0, 163, 164, 165, + 166, 609, 610, 611, 612, 613, 614, 615, 172, 173, + 174, 175, 176, 177, 178, 1026, 1027, 181, 1028, 182, + 0, 183, 184, 185, 186, 187, 188, 0, 189, 190, + 191, 192, 193, 0, 0, 194, 195, 785, 197, 198, + 0, 199, 200, 201, 0, 202, 203, 204, 0, 205, + 206, 207, 208, 1029, 210, 211, 212, 213, 214, 616, + 1030, 216, 0, 217, 218, 1031, 220, 0, 221, 0, + 222, 223, 1484, 224, 225, 226, 227, 228, 229, 0, + 230, 0, 1032, 1033, 233, 0, 234, 235, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 0, 246, + 247, 248, 249, 250, 251, 0, 252, 253, 254, 255, + 256, 257, 258, 259, 1034, 1035, 0, 1036, 0, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 0, 0, 274, 275, 276, 277, 0, 278, 279, 280, + 618, 619, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 1037, 306, 1038, 308, + 309, 310, 311, 1039, 312, 313, 314, 315, 1040, 620, + 317, 1041, 319, 320, 321, 0, 322, 323, 0, 0, + 1042, 325, 326, 0, 0, 327, 328, 329, 330, 331, + 622, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 0, 343, 344, 623, 346, 347, 348, 349, 350, + 351, 352, 0, 353, 354, 355, 356, 357, 358, 0, + 359, 360, 361, 1043, 363, 364, 365, 366, 0, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 0, 380, 381, 382, 383, 384, 385, 1044, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 0, 398, 399, 400, 401, 402, 625, 404, 405, + 406, 407, 408, 409, 410, 411, 1045, 413, 0, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 426, 427, 626, 429, 0, 430, 431, 0, 432, + 433, 434, 435, 436, 437, 438, 0, 1046, 1047, 0, + 0, 441, 442, 627, 444, 628, 1048, 446, 447, 629, + 449, 450, 451, 452, 453, 0, 0, 454, 455, 456, + 457, 458, 459, 630, 0, 461, 462, 463, 464, 465, + 466, 1049, 0, 468, 469, 470, 471, 472, 473, 474, + 0, 0, 475, 0, 0, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, + 491, 492, 493, 494, 495, 496, 1050, 0, 0, 0, + 0, 0, 0, 1051, 1052, 0, 0, 0, 0, 0, + 1054, 0, 1055, 0, 0, 0, 0, 1056, 1057, 1058, + 1059, 104, 1012, 515, 1013, 1014, 1015, 1016, 1017, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, + 106, 107, 108, 109, 110, 111, 112, 0, 113, 114, + 115, 0, 0, 0, 0, 1018, 0, 0, 116, 117, + 0, 118, 119, 120, 121, 122, 123, 124, 125, 1019, + 127, 1020, 1021, 0, 130, 131, 132, 133, 134, 135, + 1022, 606, 136, 137, 1023, 1024, 140, 0, 141, 142, + 143, 144, 607, 0, 608, 0, 1025, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 0, 157, 158, 159, + 160, 161, 162, 0, 163, 164, 165, 166, 609, 610, + 611, 612, 613, 614, 615, 172, 173, 174, 175, 176, + 177, 178, 1026, 1027, 181, 1028, 182, 0, 183, 184, + 185, 186, 187, 188, 0, 189, 190, 191, 192, 193, + 0, 0, 194, 195, 785, 197, 198, 0, 199, 200, + 201, 0, 202, 203, 204, 0, 205, 206, 207, 208, + 1029, 210, 211, 212, 213, 214, 616, 1030, 216, 0, + 217, 218, 1031, 220, 0, 221, 0, 222, 223, 0, + 224, 225, 226, 227, 228, 229, 0, 230, 0, 1032, + 1033, 233, 0, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 0, 246, 247, 248, 249, + 250, 251, 0, 252, 253, 254, 255, 256, 257, 258, + 259, 1034, 1035, 0, 1036, 0, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 0, 0, 274, + 275, 276, 277, 0, 278, 279, 280, 618, 619, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, 293, 294, 295, 1001, 297, 1002, 299, 300, 301, - 302, 1003, 303, 304, 305, 306, 1004, 597, 308, 1005, - 310, 311, 312, 0, 313, 314, 0, 0, 1006, 316, - 317, 0, 0, 318, 319, 320, 321, 322, 599, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 0, - 334, 335, 600, 337, 338, 339, 340, 341, 342, 0, - 343, 344, 345, 346, 347, 348, 0, 349, 350, 351, - 1007, 353, 354, 355, 356, 0, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, 369, 0, - 370, 371, 372, 373, 374, 375, 1008, 377, 378, 379, - 380, 381, 382, 383, 384, 385, 386, 387, 0, 388, - 389, 390, 391, 392, 602, 394, 395, 396, 397, 398, - 399, 400, 401, 1009, 403, 0, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, - 603, 419, 0, 420, 421, 0, 422, 423, 424, 425, - 426, 427, 428, 0, 1010, 1011, 0, 0, 431, 432, - 604, 434, 605, 1012, 436, 437, 606, 439, 440, 441, - 442, 443, 0, 0, 444, 445, 446, 447, 448, 607, - 0, 450, 451, 452, 453, 454, 455, 1013, 0, 457, - 458, 459, 460, 461, 462, 463, 0, 0, 464, 0, - 0, 465, 466, 467, 468, 469, 470, 471, 472, 473, - 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, - 484, 485, 1014, 0, 0, 0, 0, 0, 0, 1015, - 1016, 0, 0, 0, 0, 0, 1018, 0, 1019, 1913, - 0, 0, 0, 1020, 1021, 1022, 1152, 976, 624, 977, - 978, 979, 980, 981, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 96, 97, 98, 99, 100, 101, - 102, 103, 0, 104, 105, 106, 0, 0, 0, 0, - 982, 0, 0, 107, 108, 0, 109, 110, 111, 1154, - 113, 114, 115, 116, 983, 1155, 984, 985, 0, 121, - 122, 123, 124, 125, 126, 986, 583, 127, 128, 987, - 988, 131, 0, 132, 133, 134, 135, 584, 0, 1156, - 0, 1157, 139, 140, 141, 142, 143, 1158, 145, 146, - 147, 0, 148, 149, 150, 151, 152, 153, 0, 1159, - 155, 156, 157, 1160, 1161, 1162, 1163, 590, 591, 1164, - 163, 164, 165, 166, 167, 168, 169, 990, 991, 172, - 992, 173, 0, 174, 175, 176, 177, 178, 179, 0, - 180, 181, 182, 183, 184, 0, 0, 185, 186, 754, - 188, 189, 0, 190, 191, 192, 0, 193, 194, 195, - 0, 196, 197, 198, 199, 993, 201, 202, 203, 204, - 205, 593, 994, 207, 0, 208, 209, 995, 211, 0, - 212, 0, 213, 1166, 0, 1167, 216, 217, 1168, 1169, - 220, 0, 221, 0, 996, 997, 224, 0, 225, 226, - 227, 228, 229, 230, 231, 1170, 233, 234, 235, 236, - 0, 237, 238, 239, 240, 241, 242, 0, 243, 1171, - 245, 246, 247, 248, 249, 250, 998, 999, 0, 1000, - 0, 254, 1172, 1173, 257, 1174, 259, 260, 261, 262, - 263, 264, 0, 0, 265, 1175, 267, 1176, 0, 269, - 270, 271, 595, 596, 272, 273, 274, 275, 276, 1177, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 291, 292, 293, 294, 295, 1001, 1178, - 1002, 299, 300, 301, 302, 1003, 303, 304, 1179, 306, - 1004, 597, 308, 1005, 310, 311, 312, 0, 313, 314, - 0, 0, 1006, 316, 317, 0, 0, 318, 319, 1180, - 321, 1181, 599, 324, 325, 326, 327, 328, 329, 330, - 331, 332, 333, 0, 334, 335, 600, 337, 338, 339, - 340, 341, 342, 0, 343, 344, 345, 346, 347, 348, - 0, 349, 350, 351, 1007, 353, 354, 355, 356, 0, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - 367, 368, 369, 0, 370, 371, 1182, 373, 374, 375, - 1008, 377, 378, 379, 380, 381, 382, 383, 384, 385, - 386, 387, 0, 388, 389, 390, 391, 392, 1183, 394, - 395, 396, 397, 398, 1184, 400, 401, 1009, 403, 0, - 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 1185, 417, 603, 419, 0, 420, 421, 0, - 422, 1186, 424, 425, 426, 427, 428, 0, 1010, 1011, - 0, 0, 431, 432, 604, 434, 605, 1012, 436, 437, - 1187, 439, 440, 441, 442, 443, 0, 0, 444, 445, - 446, 447, 448, 1188, 0, 450, 451, 452, 453, 454, - 455, 1013, 2119, 457, 1190, 459, 460, 461, 462, 463, - 0, 0, 464, 0, 0, 465, 466, 467, 468, 469, - 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, 483, 484, 485, 1014, 0, 0, 0, - 0, 0, 0, 1015, 1016, 0, 0, 0, 0, 0, - 1018, 0, 1019, 0, 0, 0, 0, 1020, 1021, 1022, - 1152, 976, 624, 977, 978, 979, 980, 981, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 96, 97, - 98, 99, 100, 101, 102, 103, 0, 104, 105, 106, - 0, 0, 0, 0, 982, 0, 0, 107, 108, 0, - 109, 110, 111, 1154, 113, 114, 115, 116, 983, 1155, - 984, 985, 0, 121, 122, 123, 124, 125, 126, 986, - 583, 127, 128, 987, 988, 131, 0, 132, 133, 134, - 135, 584, 0, 1156, 0, 1157, 139, 140, 141, 142, - 143, 1158, 145, 146, 147, 0, 148, 149, 150, 151, - 152, 153, 0, 1159, 155, 156, 157, 1160, 1161, 1162, - 1163, 590, 591, 1164, 163, 164, 165, 166, 167, 168, - 169, 990, 991, 172, 992, 173, 0, 174, 175, 176, - 177, 178, 179, 0, 180, 181, 182, 183, 184, 0, - 0, 185, 186, 754, 188, 189, 0, 190, 191, 192, - 0, 193, 194, 195, 0, 196, 197, 198, 199, 993, - 201, 202, 203, 204, 205, 593, 994, 207, 0, 208, - 209, 995, 211, 0, 212, 0, 213, 1166, 0, 1167, - 216, 217, 1168, 1169, 220, 0, 221, 0, 996, 997, - 224, 0, 225, 226, 227, 228, 229, 230, 231, 1170, - 233, 234, 235, 236, 0, 237, 238, 239, 240, 241, - 242, 0, 243, 1171, 245, 246, 247, 248, 249, 250, - 998, 999, 0, 1000, 0, 254, 1172, 1173, 257, 1174, - 259, 260, 261, 262, 263, 264, 0, 0, 265, 1175, - 267, 1176, 0, 269, 270, 271, 595, 596, 272, 273, - 274, 275, 276, 1177, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, - 294, 295, 1001, 1178, 1002, 299, 300, 301, 302, 1003, - 303, 304, 1179, 306, 1004, 597, 308, 1005, 310, 311, - 312, 0, 313, 314, 0, 0, 1006, 316, 317, 0, - 0, 318, 319, 1180, 321, 1181, 599, 324, 325, 326, - 327, 328, 329, 330, 331, 332, 333, 0, 334, 335, - 600, 337, 338, 339, 340, 341, 342, 0, 343, 344, - 345, 346, 347, 348, 0, 349, 350, 351, 1007, 353, - 354, 355, 356, 0, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, 369, 0, 370, 371, - 1182, 373, 374, 375, 1008, 377, 378, 379, 380, 381, - 382, 383, 384, 385, 386, 387, 0, 388, 389, 390, - 391, 392, 1183, 394, 395, 396, 397, 398, 1184, 400, - 401, 1009, 403, 0, 404, 405, 406, 407, 408, 409, - 410, 411, 412, 413, 414, 415, 1185, 417, 603, 419, - 0, 420, 421, 0, 422, 1186, 424, 425, 426, 427, - 428, 0, 1010, 1011, 0, 0, 431, 432, 604, 434, - 605, 1012, 436, 437, 1187, 439, 440, 441, 442, 443, - 0, 0, 444, 445, 446, 447, 448, 1188, 0, 450, - 451, 452, 453, 454, 455, 1013, 0, 457, 1190, 459, - 460, 461, 462, 463, 0, 0, 464, 0, 0, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, - 1014, 0, 0, 0, 0, 0, 0, 1015, 1016, 0, - 0, 0, 0, 0, 1018, 0, 1019, 2166, 0, 0, - 0, 1020, 1021, 1022, 95, 976, 624, 977, 978, 979, - 980, 981, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 96, 97, 98, 99, 100, 101, 102, 103, - 0, 104, 105, 106, 0, 0, 0, 0, 982, 0, - 0, 107, 108, 0, 109, 110, 111, 112, 113, 114, - 115, 116, 983, 118, 984, 985, 0, 121, 122, 123, - 124, 125, 126, 986, 583, 127, 128, 987, 988, 131, - 0, 132, 133, 134, 135, 584, 0, 585, 0, 989, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 0, - 148, 149, 150, 151, 152, 153, 0, 154, 155, 156, - 157, 586, 587, 588, 589, 590, 591, 592, 163, 164, - 165, 166, 167, 168, 169, 990, 991, 172, 992, 173, - 0, 174, 175, 176, 177, 178, 179, 0, 180, 181, - 182, 183, 184, 0, 0, 185, 186, 754, 188, 189, - 0, 190, 191, 192, 0, 193, 194, 195, 0, 196, - 197, 198, 199, 993, 201, 202, 203, 204, 205, 593, - 994, 207, 0, 208, 209, 995, 211, 0, 212, 0, - 213, 214, 0, 215, 216, 217, 218, 219, 220, 0, - 221, 0, 996, 997, 224, 0, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 0, 237, - 238, 239, 240, 241, 242, 0, 243, 244, 245, 246, - 247, 248, 249, 250, 998, 999, 0, 1000, 0, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 0, 0, 265, 266, 267, 268, 0, 269, 270, 271, - 595, 596, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 1001, 297, 1002, 299, - 300, 301, 302, 1003, 303, 304, 305, 306, 1004, 597, - 308, 1005, 310, 311, 312, 0, 313, 314, 0, 0, - 1006, 316, 317, 0, 0, 318, 319, 320, 321, 322, - 599, 324, 325, 326, 327, 328, 329, 330, 331, 332, - 333, 0, 334, 335, 600, 337, 338, 339, 340, 341, - 342, 0, 343, 344, 345, 346, 347, 348, 0, 349, - 350, 351, 1007, 353, 354, 355, 356, 0, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, - 369, 0, 370, 371, 372, 373, 374, 375, 1008, 377, - 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 0, 388, 389, 390, 391, 392, 602, 394, 395, 396, - 397, 398, 399, 400, 401, 1009, 403, 0, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, - 416, 417, 603, 419, 0, 420, 421, 2479, 422, 423, - 424, 425, 426, 427, 428, 0, 1010, 1011, 0, 0, - 431, 432, 604, 434, 605, 1012, 436, 437, 606, 439, - 440, 441, 442, 443, 0, 0, 444, 445, 446, 447, - 448, 607, 0, 450, 451, 452, 453, 454, 455, 1013, - 0, 457, 458, 459, 460, 461, 462, 463, 0, 0, - 464, 0, 0, 465, 466, 467, 468, 469, 470, 471, - 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, - 482, 483, 484, 485, 1014, 0, 0, 0, 0, 0, - 0, 1015, 1016, 0, 0, 0, 0, 0, 1018, 0, - 1019, 0, 0, 0, 0, 1020, 1021, 1022, 95, 976, - 624, 977, 978, 979, 980, 981, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 96, 97, 98, 99, - 100, 101, 102, 103, 0, 104, 105, 106, 0, 0, - 0, 0, 982, 0, 0, 107, 108, 0, 109, 110, - 111, 112, 113, 114, 115, 116, 983, 118, 984, 985, - 0, 121, 122, 123, 124, 125, 126, 986, 583, 127, - 128, 987, 988, 131, 0, 132, 133, 134, 135, 584, - 0, 585, 0, 989, 139, 140, 141, 142, 143, 144, - 145, 146, 147, 0, 148, 149, 150, 151, 152, 153, - 0, 154, 155, 156, 157, 586, 587, 588, 589, 590, - 591, 592, 163, 164, 165, 166, 167, 168, 169, 990, - 991, 172, 992, 173, 0, 174, 175, 176, 177, 178, - 179, 0, 180, 181, 182, 183, 184, 0, 0, 185, - 186, 754, 188, 189, 0, 190, 191, 192, 0, 193, - 194, 195, 0, 196, 197, 198, 199, 993, 201, 202, - 203, 204, 205, 593, 994, 207, 0, 208, 209, 995, - 211, 0, 212, 0, 213, 214, 0, 215, 216, 217, - 218, 219, 220, 0, 221, 0, 996, 997, 224, 0, - 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, - 235, 236, 0, 237, 238, 239, 240, 241, 242, 0, - 243, 244, 245, 246, 247, 248, 249, 250, 998, 999, - 0, 1000, 0, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 0, 0, 265, 266, 267, 268, - 0, 269, 270, 271, 595, 596, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 1001, 297, 1002, 299, 300, 301, 302, 1003, 303, 304, - 305, 306, 1004, 597, 308, 1005, 310, 311, 312, 0, - 313, 314, 0, 0, 1006, 316, 317, 0, 0, 318, - 319, 320, 321, 322, 599, 324, 325, 326, 327, 328, - 329, 330, 331, 332, 333, 0, 334, 335, 600, 337, - 338, 339, 340, 341, 342, 0, 343, 344, 345, 346, - 347, 348, 0, 349, 350, 351, 1007, 353, 354, 355, - 356, 0, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 0, 370, 371, 372, 373, - 374, 375, 1008, 377, 378, 379, 380, 381, 382, 383, - 384, 385, 386, 387, 0, 388, 389, 390, 391, 392, - 602, 394, 395, 396, 397, 398, 399, 400, 401, 1009, - 403, 0, 404, 405, 406, 407, 408, 409, 410, 411, - 412, 413, 414, 415, 416, 417, 603, 419, 0, 420, - 421, 0, 422, 423, 424, 425, 426, 427, 428, 0, - 1010, 1011, 0, 0, 431, 432, 604, 434, 605, 1012, - 436, 437, 606, 439, 440, 441, 442, 443, 0, 0, - 444, 445, 446, 447, 448, 607, 0, 450, 451, 452, - 453, 454, 455, 1013, 0, 457, 458, 459, 460, 461, - 462, 463, 0, 2570, 464, 0, 0, 465, 466, 467, - 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, - 478, 479, 480, 481, 482, 483, 484, 485, 1014, 0, - 0, 0, 0, 0, 0, 1015, 1016, 0, 0, 0, - 0, 0, 1018, 0, 1019, 0, 0, 0, 0, 1020, - 1021, 1022, 95, 976, 624, 977, 978, 979, 980, 981, + 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 1037, 306, 1038, 308, 309, 310, 311, + 1039, 312, 313, 314, 315, 1040, 620, 317, 1041, 319, + 320, 321, 0, 322, 323, 0, 0, 1042, 325, 326, + 0, 0, 327, 328, 329, 330, 331, 622, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 0, 343, + 344, 623, 346, 347, 348, 349, 350, 351, 352, 0, + 353, 354, 355, 356, 357, 358, 0, 359, 360, 361, + 1043, 363, 364, 365, 366, 0, 367, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378, 379, 0, + 380, 381, 382, 383, 384, 385, 1044, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, 0, 398, + 399, 400, 401, 402, 625, 404, 405, 406, 407, 408, + 409, 410, 411, 1045, 413, 0, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, + 626, 429, 0, 430, 431, 0, 432, 433, 434, 435, + 436, 437, 438, 0, 1046, 1047, 0, 0, 441, 442, + 627, 444, 628, 1048, 446, 447, 629, 449, 450, 451, + 452, 453, 0, 0, 454, 455, 456, 457, 458, 459, + 630, 0, 461, 462, 463, 464, 465, 466, 1049, 0, + 468, 469, 470, 471, 472, 473, 474, 0, 0, 475, + 0, 0, 476, 477, 478, 479, 480, 481, 482, 483, + 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, + 494, 495, 496, 1050, 0, 0, 0, 0, 0, 0, + 1051, 1052, 0, 0, 0, 0, 0, 1054, 0, 1055, + 1975, 0, 0, 0, 1056, 1057, 1058, 1059, 1193, 1012, + 515, 1013, 1014, 1015, 1016, 1017, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 105, 106, 107, 108, + 109, 110, 111, 112, 0, 113, 114, 115, 0, 0, + 0, 0, 1018, 0, 0, 116, 117, 0, 118, 119, + 120, 1195, 122, 123, 124, 125, 1019, 1196, 1020, 1021, + 0, 130, 131, 132, 133, 134, 135, 1022, 606, 136, + 137, 1023, 1024, 140, 0, 141, 142, 143, 144, 607, + 0, 1197, 0, 1198, 148, 149, 150, 151, 152, 1199, + 154, 155, 156, 0, 157, 158, 159, 160, 161, 162, + 0, 1200, 164, 165, 166, 1201, 1202, 1203, 1204, 613, + 614, 1205, 172, 173, 174, 175, 176, 177, 178, 1026, + 1027, 181, 1028, 182, 0, 183, 184, 185, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 0, 0, 194, + 195, 785, 197, 198, 0, 199, 200, 201, 0, 202, + 203, 204, 0, 205, 206, 207, 208, 1029, 210, 211, + 212, 213, 214, 616, 1030, 216, 0, 217, 218, 1031, + 220, 0, 221, 0, 222, 1207, 0, 1208, 225, 226, + 1209, 1210, 229, 0, 230, 0, 1032, 1033, 233, 0, + 234, 235, 236, 237, 238, 239, 240, 1211, 242, 243, + 244, 245, 0, 246, 247, 248, 249, 250, 251, 0, + 252, 1212, 254, 255, 256, 257, 258, 259, 1034, 1035, + 0, 1036, 0, 263, 1213, 1214, 266, 1215, 268, 269, + 270, 271, 272, 273, 0, 0, 274, 1216, 276, 1217, + 0, 278, 279, 280, 618, 619, 281, 282, 283, 284, + 285, 1218, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 1037, 1219, 1038, 308, 309, 310, 311, 1039, 312, 313, + 1220, 315, 1040, 620, 317, 1041, 319, 320, 321, 0, + 322, 323, 0, 0, 1042, 325, 326, 0, 0, 327, + 328, 1221, 330, 1222, 622, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 0, 343, 344, 623, 1223, + 347, 348, 349, 350, 351, 352, 0, 353, 354, 355, + 356, 357, 358, 0, 359, 360, 361, 1043, 363, 364, + 365, 366, 0, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 0, 380, 381, 1224, + 383, 384, 385, 1044, 387, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 0, 398, 399, 400, 401, + 402, 1225, 404, 405, 406, 407, 408, 1226, 410, 411, + 1045, 413, 0, 414, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 425, 1227, 427, 626, 429, 0, + 430, 431, 0, 432, 1228, 434, 435, 436, 437, 438, + 0, 1046, 1047, 0, 0, 441, 442, 627, 444, 628, + 1048, 446, 447, 1229, 449, 450, 451, 452, 453, 0, + 0, 454, 455, 456, 457, 458, 459, 1230, 0, 461, + 462, 463, 464, 465, 466, 1049, 2178, 468, 1232, 470, + 471, 472, 473, 474, 0, 0, 475, 0, 0, 476, + 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, + 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, + 1050, 0, 0, 0, 0, 0, 0, 1051, 1052, 0, + 0, 0, 0, 0, 1054, 0, 1055, 0, 0, 0, + 0, 1056, 1057, 1058, 1059, 1193, 1012, 515, 1013, 1014, + 1015, 1016, 1017, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 105, 106, 107, 108, 109, 110, 111, + 112, 0, 113, 114, 115, 0, 0, 0, 0, 1018, + 0, 0, 116, 117, 0, 118, 119, 120, 1195, 122, + 123, 124, 125, 1019, 1196, 1020, 1021, 0, 130, 131, + 132, 133, 134, 135, 1022, 606, 136, 137, 1023, 1024, + 140, 0, 141, 142, 143, 144, 607, 0, 1197, 0, + 1198, 148, 149, 150, 151, 152, 1199, 154, 155, 156, + 0, 157, 158, 159, 160, 161, 162, 0, 1200, 164, + 165, 166, 1201, 1202, 1203, 1204, 613, 614, 1205, 172, + 173, 174, 175, 176, 177, 178, 1026, 1027, 181, 1028, + 182, 0, 183, 184, 185, 186, 187, 188, 0, 189, + 190, 191, 192, 193, 0, 0, 194, 195, 785, 197, + 198, 0, 199, 200, 201, 0, 202, 203, 204, 0, + 205, 206, 207, 208, 1029, 210, 211, 212, 213, 214, + 616, 1030, 216, 0, 217, 218, 1031, 220, 0, 221, + 0, 222, 1207, 0, 1208, 225, 226, 1209, 1210, 229, + 0, 230, 0, 1032, 1033, 233, 0, 234, 235, 236, + 237, 238, 239, 240, 1211, 242, 243, 244, 245, 0, + 246, 247, 248, 249, 250, 251, 0, 252, 1212, 254, + 255, 256, 257, 258, 259, 1034, 1035, 0, 1036, 0, + 263, 1213, 1214, 266, 1215, 268, 269, 270, 271, 272, + 273, 0, 0, 274, 1216, 276, 1217, 0, 278, 279, + 280, 618, 619, 281, 282, 283, 284, 285, 1218, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 1037, 1219, 1038, + 308, 309, 310, 311, 1039, 312, 313, 1220, 315, 1040, + 620, 317, 1041, 319, 320, 321, 0, 322, 323, 0, + 0, 1042, 325, 326, 0, 0, 327, 328, 1221, 330, + 1222, 622, 333, 334, 335, 336, 337, 338, 339, 340, + 341, 342, 0, 343, 344, 623, 1223, 347, 348, 349, + 350, 351, 352, 0, 353, 354, 355, 356, 357, 358, + 0, 359, 360, 361, 1043, 363, 364, 365, 366, 0, + 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, + 377, 378, 379, 0, 380, 381, 1224, 383, 384, 385, + 1044, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 0, 398, 399, 400, 401, 402, 1225, 404, + 405, 406, 407, 408, 1226, 410, 411, 1045, 413, 0, + 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, + 424, 425, 1227, 427, 626, 429, 0, 430, 431, 0, + 432, 1228, 434, 435, 436, 437, 438, 0, 1046, 1047, + 0, 0, 441, 442, 627, 444, 628, 1048, 446, 447, + 1229, 449, 450, 451, 452, 453, 0, 0, 454, 455, + 456, 457, 458, 459, 1230, 0, 461, 462, 463, 464, + 465, 466, 1049, 0, 468, 1232, 470, 471, 472, 473, + 474, 0, 0, 475, 0, 0, 476, 477, 478, 479, + 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, + 490, 491, 492, 493, 494, 495, 496, 1050, 0, 0, + 0, 0, 0, 0, 1051, 1052, 0, 0, 0, 0, + 0, 1054, 0, 1055, 2227, 0, 0, 0, 1056, 1057, + 1058, 1059, 104, 1012, 515, 1013, 1014, 1015, 1016, 1017, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 96, 97, 98, 99, 100, 101, 102, 103, 0, 104, - 105, 106, 0, 0, 0, 0, 982, 0, 0, 107, - 108, 0, 109, 110, 111, 112, 113, 114, 115, 116, - 983, 118, 984, 985, 0, 121, 122, 123, 124, 125, - 126, 986, 583, 127, 128, 987, 988, 131, 0, 132, - 133, 134, 135, 584, 0, 585, 0, 989, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 0, 148, 149, - 150, 151, 152, 153, 0, 154, 155, 156, 157, 586, - 587, 588, 589, 590, 591, 592, 163, 164, 165, 166, - 167, 168, 169, 990, 991, 172, 992, 173, 0, 174, - 175, 176, 177, 178, 179, 0, 180, 181, 182, 183, - 184, 0, 0, 185, 186, 754, 188, 189, 0, 190, - 191, 192, 0, 193, 194, 195, 0, 196, 197, 198, - 199, 993, 201, 202, 203, 204, 205, 593, 994, 207, - 0, 208, 209, 995, 211, 0, 212, 0, 213, 214, - 0, 215, 216, 217, 218, 219, 220, 0, 221, 0, - 996, 997, 224, 0, 225, 226, 227, 228, 229, 230, - 231, 232, 233, 234, 235, 236, 0, 237, 238, 239, - 240, 241, 242, 0, 243, 244, 245, 246, 247, 248, - 249, 250, 998, 999, 0, 1000, 0, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 0, 0, - 265, 266, 267, 268, 0, 269, 270, 271, 595, 596, - 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, 293, 294, 295, 1001, 297, 1002, 299, 300, 301, - 302, 1003, 303, 304, 305, 306, 1004, 597, 308, 1005, - 310, 311, 312, 0, 313, 314, 0, 0, 1006, 316, - 317, 0, 0, 318, 319, 320, 321, 322, 599, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 0, - 334, 335, 600, 337, 338, 339, 340, 341, 342, 0, - 343, 344, 345, 346, 347, 348, 0, 349, 350, 351, - 1007, 353, 354, 355, 356, 0, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, 369, 0, - 370, 371, 372, 373, 374, 375, 1008, 377, 378, 379, - 380, 381, 382, 383, 384, 385, 386, 387, 0, 388, - 389, 390, 391, 392, 602, 394, 395, 396, 397, 398, - 399, 400, 401, 1009, 403, 0, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, - 603, 419, 0, 420, 421, 2887, 422, 423, 424, 425, - 426, 427, 428, 0, 1010, 1011, 0, 0, 431, 432, - 604, 434, 605, 1012, 436, 437, 606, 439, 440, 441, - 442, 443, 0, 0, 444, 445, 446, 447, 448, 607, - 0, 450, 451, 452, 453, 454, 455, 1013, 0, 457, - 458, 459, 460, 461, 462, 463, 0, 0, 464, 0, - 0, 465, 466, 467, 468, 469, 470, 471, 472, 473, - 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, - 484, 485, 1014, 0, 0, 0, 0, 0, 0, 1015, - 1016, 0, 0, 0, 0, 0, 1018, 0, 1019, 0, - 0, 0, 0, 1020, 1021, 1022, 95, 976, 624, 977, - 978, 979, 980, 981, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 96, 97, 98, 99, 100, 101, - 102, 103, 0, 104, 105, 106, 0, 0, 0, 0, - 982, 0, 0, 107, 108, 0, 109, 110, 111, 112, - 113, 114, 115, 116, 983, 118, 984, 985, 0, 121, - 122, 123, 124, 125, 126, 986, 583, 127, 128, 987, - 988, 131, 0, 132, 133, 134, 135, 584, 0, 585, - 0, 989, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 0, 148, 149, 150, 151, 152, 153, 0, 154, - 155, 156, 157, 586, 587, 588, 589, 590, 591, 592, - 163, 164, 165, 166, 167, 168, 169, 990, 991, 172, - 992, 173, 0, 174, 175, 176, 177, 178, 179, 0, - 180, 181, 182, 183, 184, 0, 0, 185, 186, 754, - 188, 189, 0, 190, 191, 192, 0, 193, 194, 195, - 0, 196, 197, 198, 199, 993, 201, 202, 203, 204, - 205, 593, 994, 207, 0, 208, 209, 995, 211, 0, - 212, 0, 213, 214, 0, 215, 216, 217, 218, 219, - 220, 0, 221, 0, 996, 997, 224, 0, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 0, 237, 238, 239, 240, 241, 242, 0, 243, 244, - 245, 246, 247, 248, 249, 250, 998, 999, 0, 1000, - 0, 254, 255, 256, 257, 258, 259, 260, 261, 262, - 263, 264, 0, 0, 265, 266, 267, 268, 0, 269, - 270, 271, 595, 596, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 291, 292, 293, 294, 295, 1001, 297, - 1002, 299, 300, 301, 302, 1003, 303, 304, 305, 306, - 1004, 597, 308, 1005, 310, 311, 312, 0, 313, 314, - 0, 0, 1006, 316, 317, 0, 0, 318, 319, 320, - 321, 322, 599, 324, 325, 326, 327, 328, 329, 330, - 331, 332, 333, 0, 334, 335, 600, 337, 338, 339, - 340, 341, 342, 0, 343, 344, 345, 346, 347, 348, - 0, 349, 350, 351, 1007, 353, 354, 355, 356, 0, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - 367, 368, 369, 0, 370, 371, 372, 373, 374, 375, - 1008, 377, 378, 379, 380, 381, 382, 383, 384, 385, - 386, 387, 0, 388, 389, 390, 391, 392, 602, 394, - 395, 396, 397, 398, 399, 400, 401, 1009, 403, 0, - 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 416, 417, 603, 419, 0, 420, 421, 3005, - 422, 423, 424, 425, 426, 427, 428, 0, 1010, 1011, - 0, 0, 431, 432, 604, 434, 605, 1012, 436, 437, - 606, 439, 440, 441, 442, 443, 0, 0, 444, 445, - 446, 447, 448, 607, 0, 450, 451, 452, 453, 454, - 455, 1013, 0, 457, 458, 459, 460, 461, 462, 463, - 0, 0, 464, 0, 0, 465, 466, 467, 468, 469, - 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, 483, 484, 485, 1014, 0, 0, 0, - 0, 0, 0, 1015, 1016, 0, 0, 0, 0, 0, - 1018, 0, 1019, 0, 0, 0, 0, 1020, 1021, 1022, - 95, 976, 624, 977, 978, 979, 980, 981, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 96, 97, - 98, 99, 100, 101, 102, 103, 0, 104, 105, 106, - 0, 0, 0, 0, 982, 0, 0, 107, 108, 0, - 109, 110, 111, 112, 113, 114, 115, 116, 983, 118, - 984, 985, 0, 121, 122, 123, 124, 125, 126, 986, - 583, 127, 128, 987, 988, 131, 0, 132, 133, 134, - 135, 584, 0, 585, 0, 989, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 0, 148, 149, 150, 151, - 152, 153, 0, 154, 155, 156, 157, 586, 587, 588, - 589, 590, 591, 592, 163, 164, 165, 166, 167, 168, - 169, 990, 991, 172, 992, 173, 0, 174, 175, 176, - 177, 178, 179, 0, 180, 181, 182, 183, 184, 0, - 0, 185, 186, 754, 188, 189, 0, 190, 191, 192, - 0, 193, 194, 195, 0, 196, 197, 198, 199, 993, - 201, 202, 203, 204, 205, 593, 994, 207, 0, 208, - 209, 995, 211, 0, 212, 0, 213, 214, 0, 215, - 216, 217, 218, 219, 220, 0, 221, 0, 996, 997, - 224, 0, 225, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 0, 237, 238, 239, 240, 241, - 242, 0, 243, 244, 245, 246, 247, 248, 249, 250, - 998, 999, 0, 1000, 0, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 0, 0, 265, 266, - 267, 268, 0, 269, 270, 271, 595, 596, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 105, 106, 107, 108, 109, 110, 111, 112, 0, 113, + 114, 115, 0, 0, 0, 0, 1018, 0, 0, 116, + 117, 0, 118, 119, 120, 121, 122, 123, 124, 125, + 1019, 127, 1020, 1021, 0, 130, 131, 132, 133, 134, + 135, 1022, 606, 136, 137, 1023, 1024, 140, 0, 141, + 142, 143, 144, 607, 0, 608, 0, 1025, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 0, 157, 158, + 159, 160, 161, 162, 0, 163, 164, 165, 166, 609, + 610, 611, 612, 613, 614, 615, 172, 173, 174, 175, + 176, 177, 178, 1026, 1027, 181, 1028, 182, 0, 183, + 184, 185, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 0, 0, 194, 195, 785, 197, 198, 0, 199, + 200, 201, 0, 202, 203, 204, 0, 205, 206, 207, + 208, 1029, 210, 211, 212, 213, 214, 616, 1030, 216, + 0, 217, 218, 1031, 220, 0, 221, 0, 222, 223, + 0, 224, 225, 226, 227, 228, 229, 0, 230, 0, + 1032, 1033, 233, 0, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 0, 246, 247, 248, + 249, 250, 251, 0, 252, 253, 254, 255, 256, 257, + 258, 259, 1034, 1035, 0, 1036, 0, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 273, 0, 0, + 274, 275, 276, 277, 0, 278, 279, 280, 618, 619, + 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 1037, 306, 1038, 308, 309, 310, + 311, 1039, 312, 313, 314, 315, 1040, 620, 317, 1041, + 319, 320, 321, 0, 322, 323, 0, 0, 1042, 325, + 326, 0, 0, 327, 328, 329, 330, 331, 622, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 0, + 343, 344, 623, 346, 347, 348, 349, 350, 351, 352, + 0, 353, 354, 355, 356, 357, 358, 0, 359, 360, + 361, 1043, 363, 364, 365, 366, 0, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 0, 380, 381, 382, 383, 384, 385, 1044, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 0, + 398, 399, 400, 401, 402, 625, 404, 405, 406, 407, + 408, 409, 410, 411, 1045, 413, 0, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, + 427, 626, 429, 0, 430, 431, 2541, 432, 433, 434, + 435, 436, 437, 438, 0, 1046, 1047, 0, 0, 441, + 442, 627, 444, 628, 1048, 446, 447, 629, 449, 450, + 451, 452, 453, 0, 0, 454, 455, 456, 457, 458, + 459, 630, 0, 461, 462, 463, 464, 465, 466, 1049, + 0, 468, 469, 470, 471, 472, 473, 474, 0, 0, + 475, 0, 0, 476, 477, 478, 479, 480, 481, 482, + 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, + 493, 494, 495, 496, 1050, 0, 0, 0, 0, 0, + 0, 1051, 1052, 0, 0, 0, 0, 0, 1054, 0, + 1055, 0, 0, 0, 0, 1056, 1057, 1058, 1059, 104, + 1012, 515, 1013, 1014, 1015, 1016, 1017, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 105, 106, 107, + 108, 109, 110, 111, 112, 0, 113, 114, 115, 0, + 0, 0, 0, 1018, 0, 0, 116, 117, 0, 118, + 119, 120, 121, 122, 123, 124, 125, 1019, 127, 1020, + 1021, 0, 130, 131, 132, 133, 134, 135, 1022, 606, + 136, 137, 1023, 1024, 140, 0, 141, 142, 143, 144, + 607, 0, 608, 0, 1025, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 0, 157, 158, 159, 160, 161, + 162, 0, 163, 164, 165, 166, 609, 610, 611, 612, + 613, 614, 615, 172, 173, 174, 175, 176, 177, 178, + 1026, 1027, 181, 1028, 182, 0, 183, 184, 185, 186, + 187, 188, 0, 189, 190, 191, 192, 193, 0, 0, + 194, 195, 785, 197, 198, 0, 199, 200, 201, 0, + 202, 203, 204, 0, 205, 206, 207, 208, 1029, 210, + 211, 212, 213, 214, 616, 1030, 216, 0, 217, 218, + 1031, 220, 0, 221, 0, 222, 223, 0, 224, 225, + 226, 227, 228, 229, 0, 230, 0, 1032, 1033, 233, + 0, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 0, 246, 247, 248, 249, 250, 251, + 0, 252, 253, 254, 255, 256, 257, 258, 259, 1034, + 1035, 0, 1036, 0, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 0, 0, 274, 275, 276, + 277, 0, 278, 279, 280, 618, 619, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, - 294, 295, 1001, 297, 1002, 299, 300, 301, 302, 1003, - 303, 304, 305, 306, 1004, 597, 308, 1005, 310, 311, - 312, 0, 313, 314, 0, 0, 1006, 316, 317, 0, - 0, 318, 319, 320, 321, 322, 599, 324, 325, 326, - 327, 328, 329, 330, 331, 332, 333, 0, 334, 335, - 600, 337, 338, 339, 340, 341, 342, 0, 343, 344, - 345, 346, 347, 348, 0, 349, 350, 351, 1007, 353, - 354, 355, 356, 0, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, 369, 0, 370, 371, - 372, 373, 374, 375, 1008, 377, 378, 379, 380, 381, - 382, 383, 384, 385, 386, 387, 0, 388, 389, 390, - 391, 392, 602, 394, 395, 396, 397, 398, 399, 400, - 401, 1009, 403, 0, 404, 405, 406, 407, 408, 409, - 410, 411, 412, 413, 414, 415, 416, 417, 603, 419, - 0, 420, 421, 0, 422, 423, 424, 425, 426, 427, - 428, 0, 1010, 1011, 0, 0, 431, 432, 604, 434, - 605, 1012, 436, 437, 606, 439, 440, 441, 442, 443, - 0, 0, 444, 445, 446, 447, 448, 607, 0, 450, - 451, 452, 453, 454, 455, 1013, 0, 457, 458, 459, - 460, 461, 462, 463, 0, 0, 464, 0, 0, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 1037, 306, 1038, 308, 309, 310, 311, 1039, 312, + 313, 314, 315, 1040, 620, 317, 1041, 319, 320, 321, + 0, 322, 323, 0, 0, 1042, 325, 326, 0, 0, + 327, 328, 329, 330, 331, 622, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 0, 343, 344, 623, + 346, 347, 348, 349, 350, 351, 352, 0, 353, 354, + 355, 356, 357, 358, 0, 359, 360, 361, 1043, 363, + 364, 365, 366, 0, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378, 379, 0, 380, 381, + 382, 383, 384, 385, 1044, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, 0, 398, 399, 400, + 401, 402, 625, 404, 405, 406, 407, 408, 409, 410, + 411, 1045, 413, 0, 414, 415, 416, 417, 418, 419, + 420, 421, 422, 423, 424, 425, 426, 427, 626, 429, + 0, 430, 431, 0, 432, 433, 434, 435, 436, 437, + 438, 0, 1046, 1047, 0, 0, 441, 442, 627, 444, + 628, 1048, 446, 447, 629, 449, 450, 451, 452, 453, + 0, 0, 454, 455, 456, 457, 458, 459, 630, 0, + 461, 462, 463, 464, 465, 466, 1049, 0, 468, 469, + 470, 471, 472, 473, 474, 0, 2634, 475, 0, 0, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, - 1014, 0, 0, 0, 0, 0, 0, 1015, 1016, 0, - 0, 0, 0, 0, 1018, 0, 1019, 0, 0, 0, - 0, 1020, 1021, 1022, 1152, 976, 624, 977, 978, 979, - 980, 981, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 96, 97, 98, 99, 100, 101, 102, 103, - 0, 104, 105, 106, 0, 0, 0, 0, 982, 0, - 0, 107, 108, 0, 109, 110, 111, 1154, 113, 114, - 115, 116, 983, 1155, 984, 985, 0, 121, 122, 123, - 124, 125, 126, 986, 583, 127, 128, 987, 988, 131, - 0, 132, 133, 134, 135, 584, 0, 1156, 0, 1157, - 139, 140, 141, 142, 143, 1158, 145, 146, 147, 0, - 148, 149, 150, 151, 152, 153, 0, 1159, 155, 156, - 157, 1160, 1161, 1162, 1163, 590, 591, 1164, 163, 164, - 165, 166, 167, 168, 169, 990, 991, 172, 992, 173, - 0, 174, 175, 176, 177, 178, 179, 0, 180, 181, - 182, 183, 184, 0, 0, 185, 186, 754, 188, 189, - 0, 190, 191, 192, 0, 193, 194, 195, 0, 196, - 197, 198, 199, 993, 201, 202, 203, 204, 205, 593, - 994, 207, 0, 208, 209, 995, 211, 0, 212, 0, - 213, 1166, 0, 1167, 216, 217, 1168, 1169, 220, 0, - 221, 0, 996, 997, 224, 0, 225, 226, 227, 228, - 229, 230, 231, 1170, 233, 234, 235, 236, 0, 237, - 238, 239, 240, 241, 242, 0, 243, 1171, 245, 246, - 247, 248, 249, 250, 998, 999, 0, 1000, 0, 254, - 1172, 1173, 257, 1174, 259, 260, 261, 262, 263, 264, - 0, 0, 265, 1175, 267, 1176, 0, 269, 270, 271, - 595, 596, 272, 273, 274, 275, 276, 1177, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 1001, 1178, 1002, 299, - 300, 301, 302, 1003, 303, 304, 1179, 306, 1004, 597, - 308, 1005, 310, 311, 312, 0, 313, 314, 0, 0, - 1006, 316, 317, 0, 0, 318, 319, 1180, 321, 1181, - 599, 324, 325, 326, 327, 328, 329, 330, 331, 332, - 333, 0, 334, 335, 600, 337, 338, 339, 340, 341, - 342, 0, 343, 344, 345, 346, 347, 348, 0, 349, - 350, 351, 1007, 353, 354, 355, 356, 0, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, - 369, 0, 370, 371, 1182, 373, 374, 375, 1008, 377, - 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 0, 388, 389, 390, 391, 392, 1183, 394, 395, 396, - 397, 398, 1184, 400, 401, 1009, 403, 0, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, - 1185, 417, 603, 419, 0, 420, 421, 0, 422, 1186, - 424, 425, 426, 427, 428, 0, 1010, 1011, 0, 0, - 431, 432, 604, 434, 605, 1012, 436, 437, 1187, 439, - 440, 441, 442, 443, 0, 0, 444, 445, 446, 447, - 448, 1188, 0, 450, 451, 452, 453, 454, 455, 1013, - 0, 457, 1190, 459, 460, 461, 462, 463, 0, 0, - 464, 0, 0, 465, 466, 467, 468, 469, 470, 471, - 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, - 482, 483, 484, 485, 1014, 0, 0, 0, 0, 0, - 0, 1015, 1016, 0, 0, 0, 0, 0, 1018, 0, - 1019, 0, 0, 0, 0, 1020, 1021, 1022, 95, 976, - 624, 977, 978, 979, 980, 981, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 96, 97, 98, 99, - 100, 101, 102, 103, 0, 104, 105, 106, 0, 0, - 0, 0, 982, 0, 0, 107, 108, 0, 109, 110, - 111, 112, 113, 114, 115, 116, 983, 118, 984, 985, - 0, 121, 122, 123, 124, 125, 126, 986, 583, 127, - 128, 987, 988, 131, 0, 132, 133, 134, 135, 584, - 0, 585, 0, 989, 139, 140, 141, 142, 143, 144, - 145, 146, 147, 0, 148, 149, 150, 151, 152, 153, - 0, 154, 155, 156, 157, 586, 587, 588, 589, 590, - 591, 592, 163, 164, 165, 166, 167, 168, 169, 990, - 991, 172, 992, 173, 0, 174, 175, 176, 177, 178, - 179, 0, 180, 181, 182, 183, 184, 0, 0, 185, - 186, 754, 188, 189, 0, 190, 191, 192, 0, 193, - 194, 195, 0, 196, 197, 198, 199, 993, 201, 202, - 203, 204, 205, 593, 994, 207, 0, 208, 209, 995, - 211, 0, 212, 0, 213, 214, 0, 215, 216, 217, - 218, 219, 220, 0, 221, 0, 996, 997, 224, 0, - 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, - 235, 236, 0, 237, 238, 239, 240, 241, 242, 0, - 243, 244, 245, 246, 247, 248, 249, 250, 998, 999, - 0, 1000, 0, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 0, 0, 265, 266, 267, 268, - 0, 269, 270, 271, 595, 596, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 1001, 297, 1002, 299, 300, 301, 302, 1003, 303, 304, - 305, 306, 1004, 597, 308, 1005, 310, 311, 312, 0, - 313, 314, 0, 0, 1006, 316, 317, 0, 0, 318, - 319, 320, 321, 322, 599, 324, 325, 326, 327, 328, - 329, 330, 331, 332, 333, 0, 334, 335, 600, 337, - 338, 339, 340, 341, 342, 0, 343, 344, 345, 346, - 347, 348, 0, 349, 350, 351, 1007, 353, 354, 355, - 356, 0, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 0, 370, 371, 372, 373, - 374, 375, 1008, 377, 378, 379, 380, 381, 382, 383, - 384, 385, 386, 387, 0, 388, 389, 390, 391, 392, - 602, 394, 395, 396, 397, 398, 399, 400, 401, 1009, - 403, 0, 404, 405, 406, 407, 408, 409, 410, 411, - 412, 413, 414, 415, 416, 417, 603, 419, 0, 420, - 421, 0, 422, 423, 424, 425, 426, 427, 428, 0, - 1010, 1011, 0, 0, 431, 432, 604, 434, 605, 1012, - 436, 437, 606, 439, 440, 441, 442, 443, 0, 0, - 444, 445, 446, 447, 448, 607, 0, 450, 451, 452, - 453, 454, 455, 1013, 0, 457, 458, 459, 460, 461, - 462, 463, 0, 0, 464, 0, 0, 465, 466, 467, - 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, - 478, 479, 480, 481, 482, 483, 484, 485, 1014, 0, - 0, 0, 0, 0, 0, 1615, 1616, 0, 0, 0, - 0, 0, 1018, 0, 1019, 0, 0, 0, 0, 1020, - 1021, 1022, 95, 2043, 624, 977, 978, 979, 980, 981, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 96, 97, 98, 99, 100, 101, 102, 103, 0, 104, - 105, 106, 0, 0, 0, 0, 982, 0, 0, 107, - 108, 0, 109, 110, 111, 112, 113, 114, 115, 116, - 983, 118, 984, 985, 0, 121, 122, 123, 124, 125, - 126, 986, 583, 127, 128, 987, 988, 131, 0, 132, - 133, 134, 135, 584, 0, 585, 0, 989, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 0, 148, 149, - 150, 151, 152, 153, 0, 154, 155, 156, 157, 586, - 587, 588, 589, 590, 591, 592, 163, 164, 165, 166, - 167, 168, 169, 990, 991, 172, 992, 173, 0, 174, - 175, 176, 177, 178, 179, 0, 180, 181, 182, 183, - 184, 0, 0, 185, 186, 754, 188, 189, 0, 190, - 191, 192, 0, 193, 194, 195, 0, 196, 197, 198, - 199, 993, 201, 202, 203, 204, 205, 593, 994, 207, - 0, 208, 209, 995, 211, 0, 212, 0, 213, 214, - 0, 215, 216, 217, 218, 219, 220, 0, 221, 0, - 996, 997, 224, 0, 225, 226, 227, 228, 229, 230, - 231, 232, 233, 234, 235, 236, 0, 237, 238, 239, - 240, 241, 242, 0, 243, 244, 245, 246, 247, 248, - 249, 250, 998, 999, 0, 1000, 0, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 0, 0, - 265, 266, 267, 268, 0, 269, 270, 271, 595, 596, - 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, + 496, 1050, 0, 0, 0, 0, 0, 0, 1051, 1052, + 0, 0, 0, 0, 0, 1054, 0, 1055, 0, 0, + 0, 0, 1056, 1057, 1058, 1059, 104, 1012, 515, 1013, + 1014, 1015, 1016, 1017, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 105, 106, 107, 108, 109, 110, + 111, 112, 0, 113, 114, 115, 0, 0, 0, 0, + 1018, 0, 0, 116, 117, 0, 118, 119, 120, 121, + 122, 123, 124, 125, 1019, 127, 1020, 1021, 0, 130, + 131, 132, 133, 134, 135, 1022, 606, 136, 137, 1023, + 1024, 140, 0, 141, 142, 143, 144, 607, 0, 608, + 0, 1025, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 0, 157, 158, 159, 160, 161, 162, 0, 163, + 164, 165, 166, 609, 610, 611, 612, 613, 614, 615, + 172, 173, 174, 175, 176, 177, 178, 1026, 1027, 181, + 1028, 182, 0, 183, 184, 185, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 0, 0, 194, 195, 785, + 197, 198, 0, 199, 200, 201, 0, 202, 203, 204, + 0, 205, 206, 207, 208, 1029, 210, 211, 212, 213, + 214, 616, 1030, 216, 0, 217, 218, 1031, 220, 0, + 221, 0, 222, 223, 0, 224, 225, 226, 227, 228, + 229, 0, 230, 0, 1032, 1033, 233, 0, 234, 235, + 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, + 0, 246, 247, 248, 249, 250, 251, 0, 252, 253, + 254, 255, 256, 257, 258, 259, 1034, 1035, 0, 1036, + 0, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 0, 0, 274, 275, 276, 277, 0, 278, + 279, 280, 618, 619, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 1037, 306, + 1038, 308, 309, 310, 311, 1039, 312, 313, 314, 315, + 1040, 620, 317, 1041, 319, 320, 321, 0, 322, 323, + 0, 0, 1042, 325, 326, 0, 0, 327, 328, 329, + 330, 331, 622, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 0, 343, 344, 623, 346, 347, 348, + 349, 350, 351, 352, 0, 353, 354, 355, 356, 357, + 358, 0, 359, 360, 361, 1043, 363, 364, 365, 366, + 0, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 0, 380, 381, 382, 383, 384, + 385, 1044, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 0, 398, 399, 400, 401, 402, 625, + 404, 405, 406, 407, 408, 409, 410, 411, 1045, 413, + 0, 414, 415, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, 626, 429, 0, 430, 431, + 2957, 432, 433, 434, 435, 436, 437, 438, 0, 1046, + 1047, 0, 0, 441, 442, 627, 444, 628, 1048, 446, + 447, 629, 449, 450, 451, 452, 453, 0, 0, 454, + 455, 456, 457, 458, 459, 630, 0, 461, 462, 463, + 464, 465, 466, 1049, 0, 468, 469, 470, 471, 472, + 473, 474, 0, 0, 475, 0, 0, 476, 477, 478, + 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, + 489, 490, 491, 492, 493, 494, 495, 496, 1050, 0, + 0, 0, 0, 0, 0, 1051, 1052, 0, 0, 0, + 0, 0, 1054, 0, 1055, 0, 0, 0, 0, 1056, + 1057, 1058, 1059, 104, 1012, 515, 1013, 1014, 1015, 1016, + 1017, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 105, 106, 107, 108, 109, 110, 111, 112, 0, + 113, 114, 115, 0, 0, 0, 0, 1018, 0, 0, + 116, 117, 0, 118, 119, 120, 121, 122, 123, 124, + 125, 1019, 127, 1020, 1021, 0, 130, 131, 132, 133, + 134, 135, 1022, 606, 136, 137, 1023, 1024, 140, 0, + 141, 142, 143, 144, 607, 0, 608, 0, 1025, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 0, 157, + 158, 159, 160, 161, 162, 0, 163, 164, 165, 166, + 609, 610, 611, 612, 613, 614, 615, 172, 173, 174, + 175, 176, 177, 178, 1026, 1027, 181, 1028, 182, 0, + 183, 184, 185, 186, 187, 188, 0, 189, 190, 191, + 192, 193, 0, 0, 194, 195, 785, 197, 198, 0, + 199, 200, 201, 0, 202, 203, 204, 0, 205, 206, + 207, 208, 1029, 210, 211, 212, 213, 214, 616, 1030, + 216, 0, 217, 218, 1031, 220, 0, 221, 0, 222, + 223, 0, 224, 225, 226, 227, 228, 229, 0, 230, + 0, 1032, 1033, 233, 0, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 0, 246, 247, + 248, 249, 250, 251, 0, 252, 253, 254, 255, 256, + 257, 258, 259, 1034, 1035, 0, 1036, 0, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 0, + 0, 274, 275, 276, 277, 0, 278, 279, 280, 618, + 619, 281, 282, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 1037, 306, 1038, 308, 309, + 310, 311, 1039, 312, 313, 314, 315, 1040, 620, 317, + 1041, 319, 320, 321, 0, 322, 323, 0, 0, 1042, + 325, 326, 0, 0, 327, 328, 329, 330, 331, 622, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 0, 343, 344, 623, 346, 347, 348, 349, 350, 351, + 352, 0, 353, 354, 355, 356, 357, 358, 0, 359, + 360, 361, 1043, 363, 364, 365, 366, 0, 367, 368, + 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, + 379, 0, 380, 381, 382, 383, 384, 385, 1044, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + 0, 398, 399, 400, 401, 402, 625, 404, 405, 406, + 407, 408, 409, 410, 411, 1045, 413, 0, 414, 415, + 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, + 426, 427, 626, 429, 0, 430, 431, 3076, 432, 433, + 434, 435, 436, 437, 438, 0, 1046, 1047, 0, 0, + 441, 442, 627, 444, 628, 1048, 446, 447, 629, 449, + 450, 451, 452, 453, 0, 0, 454, 455, 456, 457, + 458, 459, 630, 0, 461, 462, 463, 464, 465, 466, + 1049, 0, 468, 469, 470, 471, 472, 473, 474, 0, + 0, 475, 0, 0, 476, 477, 478, 479, 480, 481, + 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, + 492, 493, 494, 495, 496, 1050, 0, 0, 0, 0, + 0, 0, 1051, 1052, 0, 0, 0, 0, 0, 1054, + 0, 1055, 0, 0, 0, 0, 1056, 1057, 1058, 1059, + 104, 1012, 515, 1013, 1014, 1015, 1016, 1017, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 105, 106, + 107, 108, 109, 110, 111, 112, 0, 113, 114, 115, + 0, 0, 0, 0, 1018, 0, 0, 116, 117, 0, + 118, 119, 120, 121, 122, 123, 124, 125, 1019, 127, + 1020, 1021, 0, 130, 131, 132, 133, 134, 135, 1022, + 606, 136, 137, 1023, 1024, 140, 0, 141, 142, 143, + 144, 607, 0, 608, 0, 1025, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 0, 157, 158, 159, 160, + 161, 162, 0, 163, 164, 165, 166, 609, 610, 611, + 612, 613, 614, 615, 172, 173, 174, 175, 176, 177, + 178, 1026, 1027, 181, 1028, 182, 0, 183, 184, 185, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 0, + 0, 194, 195, 785, 197, 198, 0, 199, 200, 201, + 0, 202, 203, 204, 0, 205, 206, 207, 208, 1029, + 210, 211, 212, 213, 214, 616, 1030, 216, 0, 217, + 218, 1031, 220, 0, 221, 0, 222, 223, 0, 224, + 225, 226, 227, 228, 229, 0, 230, 0, 1032, 1033, + 233, 0, 234, 235, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 0, 246, 247, 248, 249, 250, + 251, 0, 252, 253, 254, 255, 256, 257, 258, 259, + 1034, 1035, 0, 1036, 0, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 0, 0, 274, 275, + 276, 277, 0, 278, 279, 280, 618, 619, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 1037, 306, 1038, 308, 309, 310, 311, 1039, + 312, 313, 314, 315, 1040, 620, 317, 1041, 319, 320, + 321, 0, 322, 323, 0, 0, 1042, 325, 326, 0, + 0, 327, 328, 329, 330, 331, 622, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 0, 343, 344, + 623, 346, 347, 348, 349, 350, 351, 352, 0, 353, + 354, 355, 356, 357, 358, 0, 359, 360, 361, 1043, + 363, 364, 365, 366, 0, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 0, 380, + 381, 382, 383, 384, 385, 1044, 387, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 0, 398, 399, + 400, 401, 402, 625, 404, 405, 406, 407, 408, 409, + 410, 411, 1045, 413, 0, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 426, 427, 626, + 429, 0, 430, 431, 0, 432, 433, 434, 435, 436, + 437, 438, 0, 1046, 1047, 0, 0, 441, 442, 627, + 444, 628, 1048, 446, 447, 629, 449, 450, 451, 452, + 453, 0, 0, 454, 455, 456, 457, 458, 459, 630, + 0, 461, 462, 463, 464, 465, 466, 1049, 0, 468, + 469, 470, 471, 472, 473, 474, 0, 0, 475, 0, + 0, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, + 495, 496, 1050, 0, 0, 0, 0, 0, 0, 1051, + 1052, 0, 0, 0, 0, 0, 1054, 0, 1055, 0, + 0, 0, 0, 1056, 1057, 1058, 1059, 1193, 1012, 515, + 1013, 1014, 1015, 1016, 1017, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 105, 106, 107, 108, 109, + 110, 111, 112, 0, 113, 114, 115, 0, 0, 0, + 0, 1018, 0, 0, 116, 117, 0, 118, 119, 120, + 1195, 122, 123, 124, 125, 1019, 1196, 1020, 1021, 0, + 130, 131, 132, 133, 134, 135, 1022, 606, 136, 137, + 1023, 1024, 140, 0, 141, 142, 143, 144, 607, 0, + 1197, 0, 1198, 148, 149, 150, 151, 152, 1199, 154, + 155, 156, 0, 157, 158, 159, 160, 161, 162, 0, + 1200, 164, 165, 166, 1201, 1202, 1203, 1204, 613, 614, + 1205, 172, 173, 174, 175, 176, 177, 178, 1026, 1027, + 181, 1028, 182, 0, 183, 184, 185, 186, 187, 188, + 0, 189, 190, 191, 192, 193, 0, 0, 194, 195, + 785, 197, 198, 0, 199, 200, 201, 0, 202, 203, + 204, 0, 205, 206, 207, 208, 1029, 210, 211, 212, + 213, 214, 616, 1030, 216, 0, 217, 218, 1031, 220, + 0, 221, 0, 222, 1207, 0, 1208, 225, 226, 1209, + 1210, 229, 0, 230, 0, 1032, 1033, 233, 0, 234, + 235, 236, 237, 238, 239, 240, 1211, 242, 243, 244, + 245, 0, 246, 247, 248, 249, 250, 251, 0, 252, + 1212, 254, 255, 256, 257, 258, 259, 1034, 1035, 0, + 1036, 0, 263, 1213, 1214, 266, 1215, 268, 269, 270, + 271, 272, 273, 0, 0, 274, 1216, 276, 1217, 0, + 278, 279, 280, 618, 619, 281, 282, 283, 284, 285, + 1218, 287, 288, 289, 290, 291, 292, 293, 294, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 1037, + 1219, 1038, 308, 309, 310, 311, 1039, 312, 313, 1220, + 315, 1040, 620, 317, 1041, 319, 320, 321, 0, 322, + 323, 0, 0, 1042, 325, 326, 0, 0, 327, 328, + 1221, 330, 1222, 622, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342, 0, 343, 344, 623, 1223, 347, + 348, 349, 350, 351, 352, 0, 353, 354, 355, 356, + 357, 358, 0, 359, 360, 361, 1043, 363, 364, 365, + 366, 0, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 0, 380, 381, 1224, 383, + 384, 385, 1044, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 0, 398, 399, 400, 401, 402, + 1225, 404, 405, 406, 407, 408, 1226, 410, 411, 1045, + 413, 0, 414, 415, 416, 417, 418, 419, 420, 421, + 422, 423, 424, 425, 1227, 427, 626, 429, 0, 430, + 431, 0, 432, 1228, 434, 435, 436, 437, 438, 0, + 1046, 1047, 0, 0, 441, 442, 627, 444, 628, 1048, + 446, 447, 1229, 449, 450, 451, 452, 453, 0, 0, + 454, 455, 456, 457, 458, 459, 1230, 0, 461, 462, + 463, 464, 465, 466, 1049, 0, 468, 1232, 470, 471, + 472, 473, 474, 0, 0, 475, 0, 0, 476, 477, + 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, + 488, 489, 490, 491, 492, 493, 494, 495, 496, 1050, + 0, 0, 0, 0, 0, 0, 1051, 1052, 0, 0, + 0, 0, 0, 1054, 0, 1055, 0, 0, 0, 0, + 1056, 1057, 1058, 1059, 104, 1012, 515, 1013, 1014, 1015, + 1016, 1017, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 105, 106, 107, 108, 109, 110, 111, 112, + 0, 113, 114, 115, 0, 0, 0, 0, 1018, 0, + 0, 116, 117, 0, 118, 119, 120, 121, 122, 123, + 124, 125, 1019, 127, 1020, 1021, 0, 130, 131, 132, + 133, 134, 135, 1022, 606, 136, 137, 1023, 1024, 140, + 0, 141, 142, 143, 144, 607, 0, 608, 0, 1025, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 0, + 157, 158, 159, 160, 161, 162, 0, 163, 164, 165, + 166, 609, 610, 611, 612, 613, 614, 615, 172, 173, + 174, 175, 176, 177, 178, 1026, 1027, 181, 1028, 182, + 0, 183, 184, 185, 186, 187, 188, 0, 189, 190, + 191, 192, 193, 0, 0, 194, 195, 785, 197, 198, + 0, 199, 200, 201, 0, 202, 203, 204, 0, 205, + 206, 207, 208, 1029, 210, 211, 212, 213, 214, 616, + 1030, 216, 0, 217, 218, 1031, 220, 0, 221, 0, + 222, 223, 0, 224, 225, 226, 227, 228, 229, 0, + 230, 0, 1032, 1033, 233, 0, 234, 235, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 0, 246, + 247, 248, 249, 250, 251, 0, 252, 253, 254, 255, + 256, 257, 258, 259, 1034, 1035, 0, 1036, 0, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 0, 0, 274, 275, 276, 277, 0, 278, 279, 280, + 618, 619, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 1037, 306, 1038, 308, + 309, 310, 311, 1039, 312, 313, 314, 315, 1040, 620, + 317, 1041, 319, 320, 321, 0, 322, 323, 0, 0, + 1042, 325, 326, 0, 0, 327, 328, 329, 330, 331, + 622, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 0, 343, 344, 623, 346, 347, 348, 349, 350, + 351, 352, 0, 353, 354, 355, 356, 357, 358, 0, + 359, 360, 361, 1043, 363, 364, 365, 366, 0, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 0, 380, 381, 382, 383, 384, 385, 1044, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 0, 398, 399, 400, 401, 402, 625, 404, 405, + 406, 407, 408, 409, 410, 411, 1045, 413, 0, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 426, 427, 626, 429, 0, 430, 431, 0, 432, + 433, 434, 435, 436, 437, 438, 0, 1046, 1047, 0, + 0, 441, 442, 627, 444, 628, 1048, 446, 447, 629, + 449, 450, 451, 452, 453, 0, 0, 454, 455, 456, + 457, 458, 459, 630, 0, 461, 462, 463, 464, 465, + 466, 1049, 0, 468, 469, 470, 471, 472, 473, 474, + 0, 0, 475, 0, 0, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, + 491, 492, 493, 494, 495, 496, 1050, 0, 0, 0, + 0, 0, 0, 1668, 1669, 0, 0, 0, 0, 0, + 1054, 0, 1055, 0, 0, 0, 0, 1056, 1057, 1058, + 1059, 104, 2102, 515, 1013, 1014, 1015, 1016, 1017, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, + 106, 107, 108, 109, 110, 111, 112, 0, 113, 114, + 115, 0, 0, 0, 0, 1018, 0, 0, 116, 117, + 0, 118, 119, 120, 121, 122, 123, 124, 125, 1019, + 127, 1020, 1021, 0, 130, 131, 132, 133, 134, 135, + 1022, 606, 136, 137, 1023, 1024, 140, 0, 141, 142, + 143, 144, 607, 0, 608, 0, 1025, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 0, 157, 158, 159, + 160, 161, 162, 0, 163, 164, 165, 166, 609, 610, + 611, 612, 613, 614, 615, 172, 173, 174, 175, 176, + 177, 178, 1026, 1027, 181, 1028, 182, 0, 183, 184, + 185, 186, 187, 188, 0, 189, 190, 191, 192, 193, + 0, 0, 194, 195, 785, 197, 198, 0, 199, 200, + 201, 0, 202, 203, 204, 0, 205, 206, 207, 208, + 1029, 210, 211, 212, 213, 214, 616, 1030, 216, 0, + 217, 218, 1031, 220, 0, 221, 0, 222, 223, 0, + 224, 225, 226, 227, 228, 229, 0, 230, 0, 1032, + 1033, 233, 0, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 0, 246, 247, 248, 249, + 250, 251, 0, 252, 253, 254, 255, 256, 257, 258, + 259, 1034, 1035, 0, 1036, 0, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 0, 0, 274, + 275, 276, 277, 0, 278, 279, 280, 618, 619, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, 293, 294, 295, 1001, 297, 1002, 299, 300, 301, - 302, 1003, 303, 304, 305, 306, 1004, 597, 308, 1005, - 310, 311, 312, 0, 313, 314, 0, 0, 1006, 316, - 317, 0, 0, 318, 319, 320, 321, 322, 599, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 0, - 334, 335, 600, 337, 338, 339, 340, 341, 342, 0, - 343, 344, 345, 346, 347, 348, 0, 349, 350, 351, - 1007, 353, 354, 355, 356, 0, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, 369, 0, - 370, 371, 372, 373, 374, 375, 1008, 377, 378, 379, - 380, 381, 382, 383, 384, 385, 386, 387, 0, 388, - 389, 390, 391, 392, 602, 394, 395, 396, 397, 398, - 399, 400, 401, 1009, 403, 0, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, - 603, 419, 0, 420, 421, 0, 422, 423, 424, 425, - 426, 427, 428, 0, 1010, 1011, 0, 0, 431, 432, - 604, 434, 605, 1012, 436, 437, 606, 439, 440, 441, - 442, 443, 0, 0, 444, 445, 446, 447, 448, 607, - 0, 450, 451, 452, 453, 454, 455, 1013, 0, 457, - 458, 459, 460, 461, 462, 463, 0, 0, 464, 0, - 0, 465, 466, 467, 468, 469, 470, 471, 472, 473, - 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, - 484, 485, 1014, 0, 0, 0, 0, 0, 0, 1015, - 1016, 0, 0, 0, 0, 0, 1018, 0, 1019, 0, - 0, 0, 0, 1020, 1021, 1022, 95, 976, 624, 977, - 978, 979, 980, 981, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 96, 97, 98, 99, 100, 101, - 102, 103, 0, 104, 105, 106, 0, 0, 0, 0, - 982, 0, 0, 107, 108, 0, 109, 110, 111, 112, - 113, 114, 115, 116, 983, 118, 984, 985, 0, 121, - 122, 123, 124, 125, 126, 986, 583, 127, 128, 987, - 988, 131, 0, 132, 133, 134, 135, 584, 0, 585, - 0, 989, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 0, 148, 149, 150, 151, 152, 153, 0, 154, - 155, 156, 157, 586, 587, 588, 589, 590, 591, 592, - 163, 164, 165, 166, 167, 168, 169, 990, 991, 172, - 992, 173, 0, 174, 175, 176, 177, 178, 179, 0, - 180, 181, 182, 183, 184, 0, 0, 185, 186, 754, - 188, 189, 0, 190, 191, 192, 0, 193, 194, 195, - 0, 196, 197, 198, 199, 993, 201, 202, 203, 204, - 205, 593, 994, 207, 0, 208, 209, 995, 211, 0, - 212, 0, 213, 214, 0, 215, 216, 217, 218, 219, - 220, 0, 221, 0, 996, 997, 224, 0, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 0, 237, 238, 239, 240, 241, 242, 0, 243, 244, - 245, 246, 247, 248, 249, 250, 998, 999, 0, 1000, - 0, 254, 255, 256, 257, 258, 259, 260, 261, 262, - 263, 264, 0, 0, 265, 266, 267, 268, 0, 269, - 270, 271, 595, 596, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 291, 292, 293, 294, 295, 1001, 297, - 1002, 299, 300, 301, 302, 1003, 303, 304, 305, 306, - 1004, 597, 308, 1005, 310, 311, 312, 0, 313, 314, - 0, 0, 1006, 316, 317, 0, 0, 318, 319, 320, - 321, 322, 599, 324, 325, 326, 327, 328, 329, 330, - 331, 332, 333, 0, 334, 335, 600, 337, 338, 339, - 340, 341, 342, 0, 343, 344, 345, 346, 347, 348, - 0, 349, 350, 351, 1007, 353, 354, 355, 356, 0, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - 367, 368, 369, 0, 370, 371, 372, 373, 374, 375, - 1008, 377, 378, 379, 380, 381, 382, 383, 384, 385, - 386, 387, 0, 388, 389, 390, 391, 392, 602, 394, - 395, 396, 397, 398, 399, 400, 401, 1009, 403, 0, - 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 416, 417, 603, 419, 0, 420, 421, 0, - 422, 423, 424, 425, 426, 427, 428, 0, 1010, 1011, - 0, 0, 431, 432, 604, 434, 605, 1012, 436, 437, - 606, 439, 440, 441, 442, 443, 0, 0, 444, 445, - 446, 447, 448, 607, 0, 450, 451, 452, 453, 454, - 455, 1013, 0, 457, 458, 459, 460, 461, 462, 463, - 0, 0, 464, 0, 0, 465, 466, 467, 468, 469, - 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, 483, 484, 485, 1014, 0, 0, 0, - 0, 0, 0, 1015, 1016, 0, 0, 0, 0, 0, - 1018, 0, 2300, 0, 0, 0, 0, 1020, 1021, 1022, - 95, 976, 624, 977, 978, 979, 980, 981, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 96, 97, - 98, 99, 100, 101, 102, 103, 0, 104, 105, 106, - 0, 0, 0, 0, 982, 0, 0, 107, 108, 0, - 109, 110, 111, 112, 113, 114, 115, 116, 983, 118, - 984, 985, 0, 121, 122, 123, 124, 125, 126, 986, - 583, 127, 128, 987, 988, 131, 0, 132, 133, 134, - 135, 584, 0, 585, 0, 989, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 0, 148, 149, 150, 151, - 152, 153, 0, 154, 155, 2772, 157, 586, 587, 588, - 589, 590, 591, 592, 163, 164, 165, 166, 167, 168, - 169, 990, 991, 172, 992, 173, 0, 174, 175, 176, - 177, 178, 179, 0, 180, 181, 182, 183, 184, 0, - 0, 185, 186, 754, 188, 189, 0, 190, 191, 192, - 0, 193, 194, 195, 0, 196, 197, 198, 199, 993, - 201, 202, 203, 204, 205, 593, 994, 207, 0, 208, - 209, 995, 211, 0, 212, 0, 213, 214, 0, 215, - 216, 217, 218, 219, 220, 0, 221, 0, 2773, 997, - 224, 0, 225, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 0, 237, 238, 239, 240, 241, - 242, 0, 243, 244, 245, 246, 247, 248, 249, 250, - 998, 999, 0, 1000, 0, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 0, 0, 265, 266, - 267, 268, 0, 269, 270, 271, 595, 596, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 1037, 306, 1038, 308, 309, 310, 311, + 1039, 312, 313, 314, 315, 1040, 620, 317, 1041, 319, + 320, 321, 0, 322, 323, 0, 0, 1042, 325, 326, + 0, 0, 327, 328, 329, 330, 331, 622, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 0, 343, + 344, 623, 346, 347, 348, 349, 350, 351, 352, 0, + 353, 354, 355, 356, 357, 358, 0, 359, 360, 361, + 1043, 363, 364, 365, 366, 0, 367, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378, 379, 0, + 380, 381, 382, 383, 384, 385, 1044, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, 0, 398, + 399, 400, 401, 402, 625, 404, 405, 406, 407, 408, + 409, 410, 411, 1045, 413, 0, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, + 626, 429, 0, 430, 431, 0, 432, 433, 434, 435, + 436, 437, 438, 0, 1046, 1047, 0, 0, 441, 442, + 627, 444, 628, 1048, 446, 447, 629, 449, 450, 451, + 452, 453, 0, 0, 454, 455, 456, 457, 458, 459, + 630, 0, 461, 462, 463, 464, 465, 466, 1049, 0, + 468, 469, 470, 471, 472, 473, 474, 0, 0, 475, + 0, 0, 476, 477, 478, 479, 480, 481, 482, 483, + 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, + 494, 495, 496, 1050, 0, 0, 0, 0, 0, 0, + 1051, 1052, 0, 0, 0, 0, 0, 1054, 0, 1055, + 0, 0, 0, 0, 1056, 1057, 1058, 1059, 104, 1012, + 515, 1013, 1014, 1015, 1016, 1017, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 105, 106, 107, 108, + 109, 110, 111, 112, 0, 113, 114, 115, 0, 0, + 0, 0, 1018, 0, 0, 116, 117, 0, 118, 119, + 120, 121, 122, 123, 124, 125, 1019, 127, 1020, 1021, + 0, 130, 131, 132, 133, 134, 135, 1022, 606, 136, + 137, 1023, 1024, 140, 0, 141, 142, 143, 144, 607, + 0, 608, 0, 1025, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 0, 157, 158, 159, 160, 161, 162, + 0, 163, 164, 165, 166, 609, 610, 611, 612, 613, + 614, 615, 172, 173, 174, 175, 176, 177, 178, 1026, + 1027, 181, 1028, 182, 0, 183, 184, 185, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 0, 0, 194, + 195, 785, 197, 198, 0, 199, 200, 201, 0, 202, + 203, 204, 0, 205, 206, 207, 208, 1029, 210, 211, + 212, 213, 214, 616, 1030, 216, 0, 217, 218, 1031, + 220, 0, 221, 0, 222, 223, 0, 224, 225, 226, + 227, 228, 229, 0, 230, 0, 1032, 1033, 233, 0, + 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, + 244, 245, 0, 246, 247, 248, 249, 250, 251, 0, + 252, 253, 254, 255, 256, 257, 258, 259, 1034, 1035, + 0, 1036, 0, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 0, 0, 274, 275, 276, 277, + 0, 278, 279, 280, 618, 619, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 1037, 306, 1038, 308, 309, 310, 311, 1039, 312, 313, + 314, 315, 1040, 620, 317, 1041, 319, 320, 321, 0, + 322, 323, 0, 0, 1042, 325, 326, 0, 0, 327, + 328, 329, 330, 331, 622, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 0, 343, 344, 623, 346, + 347, 348, 349, 350, 351, 352, 0, 353, 354, 355, + 356, 357, 358, 0, 359, 360, 361, 1043, 363, 364, + 365, 366, 0, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 0, 380, 381, 382, + 383, 384, 385, 1044, 387, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 0, 398, 399, 400, 401, + 402, 625, 404, 405, 406, 407, 408, 409, 410, 411, + 1045, 413, 0, 414, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 425, 426, 427, 626, 429, 0, + 430, 431, 0, 432, 433, 434, 435, 436, 437, 438, + 0, 1046, 1047, 0, 0, 441, 442, 627, 444, 628, + 1048, 446, 447, 629, 449, 450, 451, 452, 453, 0, + 0, 454, 455, 456, 457, 458, 459, 630, 0, 461, + 462, 463, 464, 465, 466, 1049, 0, 468, 469, 470, + 471, 472, 473, 474, 0, 0, 475, 0, 0, 476, + 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, + 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, + 1050, 0, 0, 0, 0, 0, 0, 1051, 1052, 0, + 0, 0, 0, 0, 1054, 0, 2364, 0, 0, 0, + 0, 1056, 1057, 1058, 1059, 104, 1012, 515, 1013, 1014, + 1015, 1016, 1017, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 105, 106, 107, 108, 109, 110, 111, + 112, 0, 113, 114, 115, 0, 0, 0, 0, 1018, + 0, 0, 116, 117, 0, 118, 119, 120, 121, 122, + 123, 124, 125, 1019, 127, 1020, 1021, 0, 130, 131, + 132, 133, 134, 135, 1022, 606, 136, 137, 1023, 1024, + 140, 0, 141, 142, 143, 144, 607, 0, 608, 0, + 1025, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 0, 157, 158, 159, 160, 161, 162, 0, 163, 164, + 2843, 166, 609, 610, 611, 612, 613, 614, 615, 172, + 173, 174, 175, 176, 177, 178, 1026, 1027, 181, 1028, + 182, 0, 183, 184, 185, 186, 187, 188, 0, 189, + 190, 191, 192, 193, 0, 0, 194, 195, 785, 197, + 198, 0, 199, 200, 201, 0, 202, 203, 204, 0, + 205, 206, 207, 208, 1029, 210, 211, 212, 213, 214, + 616, 1030, 216, 0, 217, 218, 1031, 220, 0, 221, + 0, 222, 223, 0, 224, 225, 226, 227, 228, 229, + 0, 230, 0, 2844, 1033, 233, 0, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 0, + 246, 247, 248, 249, 250, 251, 0, 252, 253, 254, + 255, 256, 257, 258, 259, 1034, 1035, 0, 1036, 0, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 0, 0, 274, 275, 276, 277, 0, 278, 279, + 280, 618, 619, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 1037, 306, 1038, + 308, 309, 310, 311, 1039, 312, 313, 314, 315, 1040, + 620, 317, 1041, 319, 320, 321, 0, 322, 323, 0, + 0, 1042, 325, 326, 0, 0, 327, 328, 329, 330, + 331, 622, 333, 334, 335, 336, 337, 338, 339, 340, + 341, 342, 0, 343, 344, 623, 346, 347, 348, 349, + 350, 351, 352, 0, 353, 354, 355, 356, 357, 358, + 0, 359, 360, 361, 1043, 363, 364, 365, 366, 0, + 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, + 377, 378, 379, 0, 380, 381, 382, 383, 384, 2845, + 1044, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 0, 398, 399, 400, 401, 402, 625, 404, + 405, 406, 407, 408, 409, 410, 411, 1045, 413, 0, + 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, + 424, 425, 426, 427, 626, 429, 0, 430, 431, 0, + 432, 433, 434, 435, 436, 437, 438, 0, 1046, 1047, + 0, 0, 441, 442, 627, 444, 628, 1048, 446, 447, + 629, 449, 450, 451, 452, 453, 0, 0, 454, 455, + 456, 457, 458, 459, 630, 0, 461, 462, 463, 464, + 465, 466, 1049, 0, 468, 469, 470, 471, 472, 473, + 474, 0, 0, 475, 0, 0, 476, 477, 478, 479, + 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, + 490, 491, 492, 493, 494, 495, 496, 1050, 0, 0, + 0, 0, 0, 0, 1051, 1052, 0, 0, 0, 0, + 0, 1054, 0, 2847, 0, 0, 0, 0, 1056, 1057, + 1058, 1059, 104, 1012, 515, 1013, 1014, 1015, 1016, 1017, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 105, 106, 107, 108, 109, 110, 111, 112, 0, 113, + 114, 115, 0, 0, 0, 0, 1018, 0, 0, 116, + 117, 0, 118, 119, 120, 121, 122, 123, 124, 3229, + 1019, 127, 1020, 1021, 0, 130, 131, 132, 133, 134, + 135, 1022, 606, 136, 137, 1023, 1024, 140, 0, 141, + 142, 143, 144, 607, 0, 608, 0, 1025, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 0, 157, 158, + 159, 160, 161, 162, 0, 163, 164, 165, 3230, 609, + 610, 611, 612, 613, 614, 615, 172, 173, 174, 175, + 176, 177, 178, 1026, 1027, 181, 1028, 182, 0, 183, + 184, 185, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 0, 0, 194, 195, 785, 197, 198, 0, 199, + 200, 201, 0, 202, 203, 204, 0, 205, 206, 207, + 208, 1029, 210, 211, 212, 213, 214, 616, 1030, 216, + 0, 217, 218, 1031, 220, 0, 221, 0, 222, 223, + 0, 224, 225, 226, 227, 228, 229, 0, 230, 0, + 1032, 1033, 233, 0, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 0, 246, 247, 248, + 249, 250, 251, 0, 252, 253, 254, 255, 256, 257, + 258, 259, 1034, 1035, 0, 1036, 0, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 273, 0, 0, + 274, 275, 276, 277, 0, 278, 279, 280, 618, 619, + 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 1037, 306, 1038, 308, 309, 310, + 311, 1039, 312, 313, 314, 315, 1040, 620, 317, 1041, + 319, 320, 321, 0, 322, 323, 0, 0, 1042, 325, + 326, 0, 0, 327, 328, 329, 330, 331, 622, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 0, + 343, 344, 623, 346, 347, 348, 349, 350, 351, 352, + 0, 353, 354, 355, 356, 357, 358, 0, 359, 360, + 361, 1043, 363, 364, 365, 366, 0, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 0, 380, 381, 382, 383, 384, 385, 1044, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 0, + 398, 399, 400, 401, 402, 625, 404, 405, 406, 407, + 408, 409, 410, 411, 1045, 413, 0, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, + 427, 626, 429, 0, 430, 431, 0, 432, 433, 434, + 435, 436, 437, 438, 0, 1046, 1047, 0, 0, 441, + 442, 627, 444, 628, 1048, 446, 447, 629, 449, 450, + 3231, 452, 453, 0, 0, 454, 455, 456, 457, 458, + 459, 630, 0, 461, 462, 463, 464, 465, 466, 1049, + 0, 468, 469, 470, 471, 472, 473, 474, 0, 0, + 475, 0, 0, 476, 477, 478, 479, 480, 481, 482, + 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, + 493, 494, 495, 496, 1050, 0, 0, 0, 0, 0, + 0, 1051, 1052, 0, 0, 0, 0, 0, 1054, 0, + 1055, 0, 0, 0, 0, 1056, 1057, 1058, 1059, 104, + 1012, 515, 1013, 1014, 1015, 1016, 1017, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 105, 106, 107, + 108, 109, 110, 111, 112, 0, 113, 114, 115, 0, + 0, 0, 0, 1018, 0, 0, 116, 117, 0, 118, + 119, 120, 121, 122, 123, 124, 125, 1019, 127, 1020, + 1021, 0, 130, 131, 132, 133, 134, 135, 1022, 606, + 136, 137, 1023, 1024, 140, 0, 141, 142, 143, 144, + 607, 0, 608, 0, 1025, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 0, 157, 158, 159, 160, 161, + 162, 0, 163, 164, 165, 3230, 609, 610, 611, 612, + 613, 614, 615, 172, 173, 174, 175, 176, 177, 178, + 1026, 1027, 181, 1028, 182, 0, 183, 184, 185, 186, + 187, 188, 0, 189, 190, 191, 192, 193, 0, 0, + 194, 195, 785, 197, 198, 0, 199, 200, 201, 0, + 202, 203, 204, 0, 205, 206, 207, 208, 1029, 210, + 211, 212, 213, 214, 616, 1030, 216, 0, 217, 218, + 1031, 220, 0, 221, 0, 222, 223, 0, 224, 225, + 226, 227, 228, 229, 0, 230, 0, 1032, 1033, 233, + 0, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 0, 246, 247, 248, 249, 250, 251, + 0, 252, 253, 254, 255, 256, 257, 258, 259, 1034, + 1035, 0, 1036, 0, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 0, 0, 274, 275, 276, + 277, 0, 278, 279, 280, 618, 619, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, - 294, 295, 1001, 297, 1002, 299, 300, 301, 302, 1003, - 303, 304, 305, 306, 1004, 597, 308, 1005, 310, 311, - 312, 0, 313, 314, 0, 0, 1006, 316, 317, 0, - 0, 318, 319, 320, 321, 322, 599, 324, 325, 326, - 327, 328, 329, 330, 331, 332, 333, 0, 334, 335, - 600, 337, 338, 339, 340, 341, 342, 0, 343, 344, - 345, 346, 347, 348, 0, 349, 350, 351, 1007, 353, - 354, 355, 356, 0, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, 369, 0, 370, 371, - 372, 373, 374, 2774, 1008, 377, 378, 379, 380, 381, - 382, 383, 384, 385, 386, 387, 0, 388, 389, 390, - 391, 392, 602, 394, 395, 396, 397, 398, 399, 400, - 401, 1009, 403, 0, 404, 405, 406, 407, 408, 409, - 410, 411, 412, 413, 414, 415, 416, 417, 603, 419, - 0, 420, 421, 0, 422, 423, 424, 425, 426, 427, - 428, 0, 1010, 1011, 0, 0, 431, 432, 604, 434, - 605, 1012, 436, 437, 606, 439, 440, 441, 442, 443, - 0, 0, 444, 445, 446, 447, 448, 607, 0, 450, - 451, 452, 453, 454, 455, 1013, 0, 457, 458, 459, - 460, 461, 462, 463, 0, 0, 464, 0, 0, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 1037, 306, 1038, 308, 309, 310, 311, 1039, 312, + 313, 314, 315, 1040, 620, 317, 1041, 319, 320, 321, + 0, 322, 323, 0, 0, 1042, 325, 326, 0, 0, + 327, 328, 329, 330, 331, 622, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 0, 343, 344, 623, + 346, 347, 348, 349, 350, 351, 352, 0, 353, 354, + 355, 356, 357, 358, 0, 359, 360, 361, 1043, 363, + 364, 365, 366, 0, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378, 379, 0, 380, 381, + 382, 383, 384, 385, 1044, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, 0, 398, 399, 400, + 401, 402, 625, 404, 405, 406, 407, 408, 409, 410, + 411, 1045, 413, 0, 414, 415, 416, 417, 418, 419, + 420, 421, 422, 423, 424, 425, 426, 427, 626, 429, + 0, 430, 431, 0, 432, 433, 434, 435, 436, 437, + 438, 0, 1046, 1047, 0, 0, 441, 442, 627, 444, + 628, 1048, 446, 447, 629, 449, 450, 3231, 452, 453, + 0, 0, 454, 455, 456, 457, 458, 459, 630, 0, + 461, 462, 463, 464, 465, 466, 1049, 0, 468, 469, + 470, 471, 472, 473, 474, 0, 0, 475, 0, 0, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, - 1014, 0, 0, 0, 0, 0, 0, 1015, 1016, 0, - 0, 0, 0, 0, 1018, 0, 2776, 0, 0, 0, - 0, 1020, 1021, 1022, 95, 976, 624, 977, 978, 979, - 980, 981, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 96, 97, 98, 99, 100, 101, 102, 103, - 0, 104, 105, 106, 0, 0, 0, 0, 982, 0, - 0, 107, 108, 0, 109, 110, 111, 112, 113, 114, - 115, 3149, 983, 118, 984, 985, 0, 121, 122, 123, - 124, 125, 126, 986, 583, 127, 128, 987, 988, 131, - 0, 132, 133, 134, 135, 584, 0, 585, 0, 989, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 0, - 148, 149, 150, 151, 152, 153, 0, 154, 155, 156, - 3150, 586, 587, 588, 589, 590, 591, 592, 163, 164, - 165, 166, 167, 168, 169, 990, 991, 172, 992, 173, - 0, 174, 175, 176, 177, 178, 179, 0, 180, 181, - 182, 183, 184, 0, 0, 185, 186, 754, 188, 189, - 0, 190, 191, 192, 0, 193, 194, 195, 0, 196, - 197, 198, 199, 993, 201, 202, 203, 204, 205, 593, - 994, 207, 0, 208, 209, 995, 211, 0, 212, 0, - 213, 214, 0, 215, 216, 217, 218, 219, 220, 0, - 221, 0, 996, 997, 224, 0, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 0, 237, - 238, 239, 240, 241, 242, 0, 243, 244, 245, 246, - 247, 248, 249, 250, 998, 999, 0, 1000, 0, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 0, 0, 265, 266, 267, 268, 0, 269, 270, 271, - 595, 596, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 1001, 297, 1002, 299, - 300, 301, 302, 1003, 303, 304, 305, 306, 1004, 597, - 308, 1005, 310, 311, 312, 0, 313, 314, 0, 0, - 1006, 316, 317, 0, 0, 318, 319, 320, 321, 322, - 599, 324, 325, 326, 327, 328, 329, 330, 331, 332, - 333, 0, 334, 335, 600, 337, 338, 339, 340, 341, - 342, 0, 343, 344, 345, 346, 347, 348, 0, 349, - 350, 351, 1007, 353, 354, 355, 356, 0, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, - 369, 0, 370, 371, 372, 373, 374, 375, 1008, 377, - 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 0, 388, 389, 390, 391, 392, 602, 394, 395, 396, - 397, 398, 399, 400, 401, 1009, 403, 0, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, - 416, 417, 603, 419, 0, 420, 421, 0, 422, 423, - 424, 425, 426, 427, 428, 0, 1010, 1011, 0, 0, - 431, 432, 604, 434, 605, 1012, 436, 437, 606, 439, - 440, 3151, 442, 443, 0, 0, 444, 445, 446, 447, - 448, 607, 0, 450, 451, 452, 453, 454, 455, 1013, - 0, 457, 458, 459, 460, 461, 462, 463, 0, 0, - 464, 0, 0, 465, 466, 467, 468, 469, 470, 471, - 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, - 482, 483, 484, 485, 1014, 0, 0, 0, 0, 0, - 0, 1015, 1016, 0, 0, 0, 0, 0, 1018, 0, - 1019, 0, 0, 0, 0, 1020, 1021, 1022, 95, 976, - 624, 977, 978, 979, 980, 981, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 96, 97, 98, 99, - 100, 101, 102, 103, 0, 104, 105, 106, 0, 0, - 0, 0, 982, 0, 0, 107, 108, 0, 109, 110, - 111, 112, 113, 114, 115, 116, 983, 118, 984, 985, - 0, 121, 122, 123, 124, 125, 126, 986, 583, 127, - 128, 987, 988, 131, 0, 132, 133, 134, 135, 584, - 0, 585, 0, 989, 139, 140, 141, 142, 143, 144, - 145, 146, 147, 0, 148, 149, 150, 151, 152, 153, - 0, 154, 155, 156, 3150, 586, 587, 588, 589, 590, - 591, 592, 163, 164, 165, 166, 167, 168, 169, 990, - 991, 172, 992, 173, 0, 174, 175, 176, 177, 178, - 179, 0, 180, 181, 182, 183, 184, 0, 0, 185, - 186, 754, 188, 189, 0, 190, 191, 192, 0, 193, - 194, 195, 0, 196, 197, 198, 199, 993, 201, 202, - 203, 204, 205, 593, 994, 207, 0, 208, 209, 995, - 211, 0, 212, 0, 213, 214, 0, 215, 216, 217, - 218, 219, 220, 0, 221, 0, 996, 997, 224, 0, - 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, - 235, 236, 0, 237, 238, 239, 240, 241, 242, 0, - 243, 244, 245, 246, 247, 248, 249, 250, 998, 999, - 0, 1000, 0, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 0, 0, 265, 266, 267, 268, - 0, 269, 270, 271, 595, 596, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, + 496, 1050, 0, 0, 0, 0, 0, 0, 1051, 1052, + 0, 0, 0, 0, 0, 1054, 0, 1055, 0, 0, + 0, 0, 1056, 1057, 1058, 1059, 104, 1012, 515, 1013, + 1014, 1015, 1016, 1017, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 105, 106, 107, 108, 109, 110, + 111, 112, 0, 113, 114, 115, 0, 0, 0, 0, + 1018, 0, 0, 116, 117, 0, 118, 119, 120, 121, + 122, 123, 124, 125, 1019, 127, 1020, 1021, 0, 130, + 131, 132, 133, 134, 135, 1022, 606, 136, 137, 1023, + 1024, 140, 0, 141, 142, 143, 144, 607, 0, 608, + 0, 147, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 0, 157, 158, 159, 160, 161, 162, 0, 163, + 164, 165, 166, 609, 610, 611, 612, 613, 614, 615, + 172, 173, 174, 175, 176, 177, 178, 1026, 1027, 181, + 0, 182, 0, 183, 184, 185, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 0, 0, 194, 195, 785, + 197, 198, 0, 199, 200, 201, 0, 202, 203, 204, + 0, 205, 206, 207, 208, 1029, 210, 211, 212, 213, + 214, 616, 1030, 216, 0, 217, 218, 1031, 220, 0, + 221, 0, 222, 223, 0, 224, 225, 226, 227, 228, + 229, 0, 230, 0, 1032, 1033, 233, 0, 234, 235, + 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, + 0, 246, 247, 248, 249, 250, 251, 0, 252, 253, + 254, 255, 256, 257, 258, 259, 1034, 1035, 0, 1036, + 0, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 0, 0, 274, 275, 276, 277, 0, 278, + 279, 280, 618, 619, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 1037, 306, + 1038, 308, 309, 310, 311, 0, 312, 313, 314, 315, + 1040, 620, 317, 1041, 319, 320, 321, 0, 322, 323, + 0, 0, 1042, 325, 326, 0, 0, 327, 328, 329, + 330, 331, 622, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 0, 343, 344, 623, 346, 347, 348, + 349, 350, 351, 352, 0, 353, 354, 355, 356, 357, + 358, 0, 359, 360, 361, 1043, 363, 364, 365, 366, + 0, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 0, 380, 381, 382, 383, 384, + 385, 1044, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 0, 398, 399, 400, 401, 402, 625, + 404, 405, 406, 407, 408, 409, 410, 411, 1045, 413, + 0, 414, 415, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, 626, 429, 0, 430, 431, + 0, 432, 433, 434, 435, 436, 437, 438, 0, 1046, + 1047, 0, 0, 441, 442, 627, 444, 628, 1048, 446, + 447, 629, 449, 450, 451, 452, 453, 0, 0, 454, + 455, 456, 457, 458, 459, 630, 0, 461, 462, 463, + 464, 465, 466, 1049, 0, 468, 469, 470, 471, 472, + 473, 474, 0, 0, 475, 0, 0, 476, 477, 478, + 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, + 489, 490, 491, 492, 493, 494, 495, 496, 0, 0, + 0, 0, 0, 0, 0, 1471, 1472, 0, 0, 0, + 0, 0, 1054, 0, 1055, 0, 0, 0, 0, 1056, + 1057, 1058, 1059, 104, 1012, 515, 1013, 1014, 0, 1016, + 1017, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 105, 106, 107, 108, 109, 110, 111, 112, 0, + 113, 114, 115, 0, 0, 0, 0, 1018, 0, 0, + 116, 117, 0, 118, 119, 120, 121, 122, 123, 124, + 125, 1019, 127, 1020, 1021, 0, 130, 131, 132, 133, + 134, 135, 1022, 606, 136, 137, 1023, 1024, 140, 0, + 141, 142, 143, 144, 607, 0, 608, 0, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 0, 157, + 158, 159, 160, 161, 162, 0, 163, 164, 165, 166, + 609, 610, 611, 612, 613, 614, 615, 172, 173, 174, + 175, 176, 177, 178, 1026, 1027, 181, 0, 182, 0, + 183, 184, 185, 186, 187, 188, 0, 189, 190, 191, + 192, 193, 0, 0, 194, 195, 785, 197, 198, 0, + 199, 200, 201, 0, 202, 203, 204, 0, 205, 206, + 207, 208, 1029, 210, 211, 212, 213, 214, 616, 1030, + 216, 0, 217, 218, 1031, 220, 0, 221, 0, 222, + 223, 0, 224, 225, 226, 227, 228, 229, 0, 230, + 0, 1032, 1033, 233, 0, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 0, 246, 247, + 248, 249, 250, 251, 0, 252, 253, 254, 255, 256, + 257, 258, 259, 1034, 1035, 0, 1036, 0, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 0, + 0, 274, 275, 276, 277, 0, 278, 279, 280, 618, + 619, 281, 282, 283, 284, 285, 286, 287, 288, 289, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 1037, 306, 1038, 308, 309, + 310, 311, 0, 312, 313, 314, 315, 1040, 620, 317, + 1041, 319, 320, 321, 0, 322, 323, 0, 0, 324, + 325, 326, 0, 0, 327, 328, 329, 330, 331, 622, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 0, 343, 344, 623, 346, 347, 348, 349, 350, 351, + 352, 0, 353, 354, 355, 356, 357, 358, 0, 359, + 360, 361, 1043, 363, 364, 365, 366, 0, 367, 368, + 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, + 379, 0, 380, 381, 382, 383, 384, 385, 2088, 2089, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + 0, 398, 399, 400, 401, 402, 625, 404, 405, 406, + 407, 408, 409, 410, 411, 1045, 413, 0, 414, 415, + 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, + 426, 427, 626, 429, 0, 430, 431, 0, 432, 433, + 434, 435, 436, 437, 438, 0, 1046, 1047, 0, 0, + 441, 442, 627, 444, 628, 1048, 446, 447, 629, 449, + 450, 451, 452, 453, 0, 0, 454, 455, 456, 457, + 458, 459, 630, 0, 461, 462, 463, 464, 465, 466, + 1049, 0, 468, 469, 470, 471, 472, 473, 474, 0, + 0, 475, 0, 0, 476, 477, 478, 479, 480, 481, + 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, + 492, 493, 494, 495, 496, 0, 0, 0, 0, 0, + 0, 0, 2090, 2091, 0, 0, 0, 0, 0, 1054, + 0, 1055, 0, 0, 0, 0, 1056, 1057, 1058, 1059, + 104, 1012, 515, 1013, 1014, 1015, 1016, 1017, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 105, 106, + 107, 108, 109, 110, 111, 112, 0, 113, 114, 115, + 0, 0, 0, 0, 1018, 0, 0, 116, 117, 0, + 118, 119, 120, 121, 122, 123, 124, 125, 1019, 127, + 1020, 1021, 0, 130, 131, 132, 133, 134, 135, 1022, + 606, 136, 137, 1023, 1024, 140, 0, 141, 142, 143, + 144, 607, 0, 608, 0, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 0, 157, 158, 159, 160, + 161, 162, 0, 163, 164, 165, 166, 609, 610, 611, + 612, 613, 614, 615, 172, 173, 174, 175, 176, 177, + 178, 1026, 1027, 181, 0, 182, 0, 183, 184, 185, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 0, + 0, 194, 195, 785, 197, 198, 0, 199, 200, 201, + 0, 202, 203, 204, 0, 205, 206, 207, 208, 1029, + 210, 211, 212, 213, 214, 616, 1030, 216, 0, 217, + 218, 1031, 220, 0, 221, 0, 222, 223, 0, 224, + 225, 226, 227, 228, 229, 0, 230, 0, 1032, 1033, + 233, 0, 234, 235, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 0, 246, 247, 248, 249, 250, + 251, 0, 252, 253, 254, 255, 256, 257, 258, 259, + 1034, 1035, 0, 1036, 0, 263, 0, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 0, 0, 274, 275, + 276, 277, 0, 278, 279, 280, 618, 619, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 1037, 306, 1038, 308, 309, 310, 311, 0, + 312, 313, 314, 315, 1040, 620, 317, 1041, 319, 320, + 321, 0, 322, 323, 0, 0, 1042, 325, 326, 0, + 0, 327, 328, 329, 330, 331, 622, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 0, 343, 344, + 623, 346, 347, 348, 349, 350, 351, 352, 0, 353, + 354, 355, 356, 357, 358, 0, 359, 360, 361, 1043, + 363, 364, 365, 366, 0, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 0, 380, + 381, 382, 383, 384, 385, 1044, 387, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 0, 398, 399, + 400, 401, 402, 625, 404, 405, 406, 407, 408, 409, + 410, 411, 1045, 413, 0, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 426, 427, 626, + 429, 0, 430, 431, 0, 432, 433, 434, 435, 436, + 437, 438, 0, 1046, 1047, 0, 0, 441, 442, 627, + 444, 628, 1048, 446, 447, 629, 449, 450, 451, 452, + 453, 0, 0, 454, 455, 456, 457, 458, 459, 630, + 0, 461, 462, 463, 464, 465, 466, 1049, 0, 468, + 469, 470, 471, 472, 473, 474, 0, 0, 475, 0, + 0, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, + 495, 496, 0, 0, 0, 0, 0, 0, 0, 1471, + 1472, 0, 0, 0, 0, 0, 1054, 0, 1055, 0, + 0, 0, 0, 1056, 1057, 1058, 1059, 104, 1012, 515, + 1013, 1014, 1015, 1016, 1017, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 105, 106, 107, 108, 109, + 110, 111, 112, 0, 113, 114, 115, 0, 0, 0, + 0, 1018, 0, 0, 116, 117, 0, 118, 119, 120, + 121, 122, 123, 124, -1916, 1019, 127, 1020, 1021, 0, + 130, 131, 132, 133, 134, 135, 1022, 606, 136, 137, + 1023, 1024, 140, 0, 141, 142, 143, 144, 607, 0, + 608, 0, 1025, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 0, 157, 158, 159, 160, 161, 162, 0, + 163, 164, 165, 3230, 609, 610, 611, 612, 613, 614, + 615, 172, 173, 174, 175, 176, 177, 178, 1026, 1027, + 181, 1028, 182, 0, 183, 184, 185, 186, 187, 188, + 0, 189, 190, 191, 192, 193, 0, 0, 194, 195, + 785, 197, 198, 0, 199, 200, 201, 0, 202, 203, + 204, 0, 205, 206, 207, 208, 1029, 210, 211, 212, + 213, 214, 616, 1030, 216, 0, 217, 218, 1031, 220, + 0, 221, 0, 222, 223, 0, 224, 225, 226, 227, + -1916, 229, 0, 230, 0, 1032, 1033, 233, 0, 234, + 235, 236, 237, 238, 239, 240, -1916, 242, 243, 244, + 245, 0, 246, 247, 248, 249, 250, 251, 0, 252, + 253, 254, 255, 256, 257, 258, 259, 1034, 1035, 0, + 1036, 0, 263, 0, 0, 266, 267, 268, 269, 270, + 271, 272, 273, 0, 0, 274, 275, 276, -1916, 0, + 278, 279, 280, 618, 619, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 1001, 297, 1002, 299, 300, 301, 302, 1003, 303, 304, - 305, 306, 1004, 597, 308, 1005, 310, 311, 312, 0, - 313, 314, 0, 0, 1006, 316, 317, 0, 0, 318, - 319, 320, 321, 322, 599, 324, 325, 326, 327, 328, - 329, 330, 331, 332, 333, 0, 334, 335, 600, 337, - 338, 339, 340, 341, 342, 0, 343, 344, 345, 346, - 347, 348, 0, 349, 350, 351, 1007, 353, 354, 355, - 356, 0, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 0, 370, 371, 372, 373, - 374, 375, 1008, 377, 378, 379, 380, 381, 382, 383, - 384, 385, 386, 387, 0, 388, 389, 390, 391, 392, - 602, 394, 395, 396, 397, 398, 399, 400, 401, 1009, - 403, 0, 404, 405, 406, 407, 408, 409, 410, 411, - 412, 413, 414, 415, 416, 417, 603, 419, 0, 420, - 421, 0, 422, 423, 424, 425, 426, 427, 428, 0, - 1010, 1011, 0, 0, 431, 432, 604, 434, 605, 1012, - 436, 437, 606, 439, 440, 3151, 442, 443, 0, 0, - 444, 445, 446, 447, 448, 607, 0, 450, 451, 452, - 453, 454, 455, 1013, 0, 457, 458, 459, 460, 461, - 462, 463, 0, 0, 464, 0, 0, 465, 466, 467, - 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, - 478, 479, 480, 481, 482, 483, 484, 485, 1014, 0, - 0, 0, 0, 0, 0, 1015, 1016, 0, 0, 0, - 0, 0, 1018, 0, 1019, 0, 0, 0, 0, 1020, - 1021, 1022, 95, 976, 624, 977, 978, 979, 980, 981, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 1037, + 306, 1038, 308, 309, 310, 311, 0, 312, 313, 0, + 315, 1040, 620, 317, 1041, 319, 320, 321, 0, 322, + 323, 0, 0, 1042, 325, 326, 0, 0, 327, 328, + 329, 330, 331, 622, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342, 0, 343, 344, 623, 346, 347, + 348, 349, 350, 351, 352, 0, 353, 354, 355, 356, + 357, 358, 0, 359, 360, 361, 1043, 363, 364, 365, + 366, 0, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 0, 380, 381, 382, 383, + 384, 385, 1044, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 0, 398, 399, 400, 401, 402, + 625, 404, 405, 406, 407, 408, -1916, 410, 411, 1045, + 413, 0, 414, 415, 416, 417, 418, 419, 420, 421, + 422, 423, 424, 425, 426, 427, 626, 429, 0, 430, + 431, 0, 432, 433, 434, 435, 436, 437, 438, 0, + 1046, 1047, 0, 0, 441, 442, 627, 444, 628, 1048, + 446, 447, 629, 449, 450, 3231, 452, 453, 0, 0, + 454, 455, 456, 457, 458, 459, 630, 0, 461, 462, + 463, 464, 465, 466, 1049, 0, 468, 469, 470, 471, + 472, 473, 474, 0, 0, 475, 0, 0, 476, 477, + 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, + 488, 489, 490, 491, 492, 493, 494, 495, 496, -1916, + 0, 0, 0, 0, 0, 0, 1051, 1052, 0, 0, + 0, 0, 0, 1054, 0, 1055, 0, 0, 0, 0, + 1056, 1057, 1058, 1059, 104, 1012, 515, 1013, 1014, 1015, + 1016, 1017, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 105, 106, 107, 108, 109, 110, 111, 112, + 0, 113, 114, 115, 0, 0, 0, 0, 1018, 0, + 0, 116, 117, 0, 118, 119, 120, 121, 122, 123, + 124, 0, 1019, 127, 1020, 1021, 0, 130, 131, 132, + 133, 134, 135, 1022, 606, 136, 137, 1023, 1024, 140, + 0, 141, 142, 143, 144, 607, 0, 608, 0, 1025, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 0, + 157, 158, 159, 160, 161, 162, 0, 163, 164, 165, + 166, 609, 610, 611, 612, 613, 614, 615, 172, 173, + 174, 175, 176, 177, 178, 1026, 1027, 181, 1028, 182, + 0, 183, 184, 185, 186, 187, 188, 0, 189, 190, + 191, 192, 193, 0, 0, 194, 195, 785, 197, 198, + 0, 199, 200, 201, 0, 202, 0, 204, 0, 205, + 206, 207, 208, 1029, 210, 211, 212, 213, 214, 616, + 1030, 216, 0, 217, 218, 1031, 220, 0, 221, 0, + 222, 223, 0, 224, 225, 226, 227, 0, 229, 0, + 230, 0, 1032, 1033, 233, 0, 234, 235, 236, 237, + 238, 239, 240, 0, 242, 243, 244, 245, 0, 246, + 247, 248, 249, 250, 251, 0, 252, 253, 254, 255, + 256, 257, 258, 259, 1034, 1035, 0, 1036, 0, 263, + 0, 0, 266, 267, 268, 269, 270, 271, 272, 273, + 0, 0, 274, 275, 276, 0, 0, 278, 279, 280, + 618, 619, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 1037, 306, 1038, 308, + 309, 310, 311, 0, 312, 313, 0, 315, 1040, 620, + 317, 1041, 319, 320, 321, 0, 322, 323, 0, 0, + 1042, 325, 326, 0, 0, 327, 328, 329, 330, 331, + 622, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 0, 343, 344, 623, 346, 347, 348, 349, 350, + 351, 352, 0, 353, 354, 355, 356, 357, 358, 0, + 359, 360, 361, 1043, 363, 364, 365, 366, 0, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 0, 380, 381, 382, 383, 384, 385, 1044, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 0, 398, 399, 400, 401, 402, 625, 404, 405, + 406, 407, 408, 0, 410, 411, 1045, 413, 0, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 426, 427, 626, 429, 0, 430, 431, 0, 432, + 433, 434, 435, 436, 437, 438, 0, 1046, 1047, 0, + 0, 441, 442, 627, 444, 628, 1048, 446, 447, 629, + 449, 450, 451, 452, 453, 0, 0, 454, 455, 456, + 457, 458, 459, 630, 0, 461, 462, 463, 464, 465, + 466, 1049, 0, 468, 469, 470, 471, 472, 473, 474, + 0, 0, 475, 0, 0, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, + 491, 492, 493, 494, 495, 496, 0, 0, 0, 0, + 0, 0, 0, 1051, 1052, 504, 0, 0, 0, 0, + 1054, 0, 1055, 0, 0, 0, 0, 1056, 1057, 1058, + 1059, 0, 0, 105, 106, 107, 108, 109, 110, 111, + 112, 0, 113, 114, 115, 0, 0, 0, 0, 0, + 977, 0, 116, 117, 0, 118, 119, 120, 0, 122, + 123, 124, 125, 126, 0, 128, 129, 0, 130, 131, + 132, 133, 134, 135, 0, 0, 136, 137, 138, 139, + 140, 0, 141, 142, 143, 144, 145, 0, 0, 0, + 147, 148, 149, 150, 151, 152, 0, 154, 155, 156, + 0, 157, 158, 159, 160, 161, 162, 0, 0, 164, + 165, 166, 0, 0, 0, 0, 0, 0, 0, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 0, + 182, 0, 183, 184, 185, 186, 187, 188, 0, 189, + 190, 191, 192, 193, 0, 0, 194, 195, 196, 197, + 198, 0, 199, 200, 201, 0, 202, 203, 204, -488, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 0, 216, -488, 217, 218, 219, 220, -488, 221, + 0, 222, 0, 0, 0, 225, 226, 505, 0, 229, + 0, 230, 0, 231, 232, 233, 0, 234, 235, 236, + 237, 238, 239, 240, 0, 242, 243, 244, 245, 0, + 246, 247, 248, 249, 250, 251, 0, 252, 0, 254, + 255, 256, 257, 258, 259, 260, 261, -488, 262, 0, + 263, 0, 0, 266, 0, 268, 269, 270, 271, 272, + 273, 0, 0, 274, 0, 276, 0, -488, 278, 279, + 280, 0, 0, 281, 282, 283, 284, 285, 506, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, 0, 307, + 308, 309, 310, 311, 0, 312, 313, 0, 315, 0, + 316, 317, 318, 319, 320, 321, -488, 322, 323, 0, + 0, 324, 325, 326, 0, -488, 327, 328, 0, 330, + 0, 332, 333, 334, 335, 336, 337, 338, 339, 340, + 341, 342, 0, 343, 344, 345, 0, 347, 348, 349, + 350, 351, 352, 0, 353, 354, 355, 356, 357, 358, + 0, 359, 360, 361, 362, 363, 364, 365, 366, 0, + 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, + 377, 378, 379, 0, 380, 381, 0, 383, 384, 385, + 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 0, 398, 399, 400, 401, 402, 0, 404, + 405, 406, 407, 408, 0, 410, 411, 412, 413, 0, + 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, + 424, 425, 507, 427, 428, 429, 0, 430, 431, 0, + 432, 0, 434, 435, 436, 437, 438, 0, 439, 440, + 0, 0, 441, 442, 443, 444, 445, 0, 446, 447, + 448, 449, 450, 451, 452, 453, -488, 0, 454, 455, + 456, 457, 458, 459, 0, 0, 461, 462, 463, 464, + 465, 466, 467, 0, 468, 0, 470, 471, 472, 473, + 474, 0, 0, 475, 0, 0, 476, 477, 478, 479, + 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, + 490, 491, 492, 493, 494, 495, 496, 104, 0, 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 96, 97, 98, 99, 100, 101, 102, 103, 0, 104, - 105, 106, 0, 0, 0, 0, 982, 0, 0, 107, - 108, 0, 109, 110, 111, 112, 113, 114, 115, 116, - 983, 118, 984, 985, 0, 121, 122, 123, 124, 125, - 126, 986, 583, 127, 128, 987, 988, 131, 0, 132, - 133, 134, 135, 584, 0, 585, 0, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 0, 148, 149, - 150, 151, 152, 153, 0, 154, 155, 156, 157, 586, - 587, 588, 589, 590, 591, 592, 163, 164, 165, 166, - 167, 168, 169, 990, 991, 172, 0, 173, 0, 174, - 175, 176, 177, 178, 179, 0, 180, 181, 182, 183, - 184, 0, 0, 185, 186, 754, 188, 189, 0, 190, - 191, 192, 0, 193, 194, 195, 0, 196, 197, 198, - 199, 993, 201, 202, 203, 204, 205, 593, 994, 207, - 0, 208, 209, 995, 211, 0, 212, 0, 213, 214, - 0, 215, 216, 217, 218, 219, 220, 0, 221, 0, - 996, 997, 224, 0, 225, 226, 227, 228, 229, 230, - 231, 232, 233, 234, 235, 236, 0, 237, 238, 239, - 240, 241, 242, 0, 243, 244, 245, 246, 247, 248, - 249, 250, 998, 999, 0, 1000, 0, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 0, 0, - 265, 266, 267, 268, 0, 269, 270, 271, 595, 596, - 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, 293, 294, 295, 1001, 297, 1002, 299, 300, 301, - 302, 0, 303, 304, 305, 306, 1004, 597, 308, 1005, - 310, 311, 312, 0, 313, 314, 0, 0, 1006, 316, - 317, 0, 0, 318, 319, 320, 321, 322, 599, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 0, - 334, 335, 600, 337, 338, 339, 340, 341, 342, 0, - 343, 344, 345, 346, 347, 348, 0, 349, 350, 351, - 1007, 353, 354, 355, 356, 0, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, 369, 0, - 370, 371, 372, 373, 374, 375, 1008, 377, 378, 379, - 380, 381, 382, 383, 384, 385, 386, 387, 0, 388, - 389, 390, 391, 392, 602, 394, 395, 396, 397, 398, - 399, 400, 401, 1009, 403, 0, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, - 603, 419, 0, 420, 421, 0, 422, 423, 424, 425, - 426, 427, 428, 0, 1010, 1011, 0, 0, 431, 432, - 604, 434, 605, 1012, 436, 437, 606, 439, 440, 441, - 442, 443, 0, 0, 444, 445, 446, 447, 448, 607, - 0, 450, 451, 452, 453, 454, 455, 1013, 0, 457, - 458, 459, 460, 461, 462, 463, 0, 0, 464, 0, - 0, 465, 466, 467, 468, 469, 470, 471, 472, 473, - 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, - 484, 485, 0, 0, 0, 0, 0, 0, 0, 1420, - 1421, 0, 0, 0, 0, 0, 1018, 0, 1019, 0, - 0, 0, 0, 1020, 1021, 1022, 95, 976, 624, 977, - 978, 0, 980, 981, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 96, 97, 98, 99, 100, 101, - 102, 103, 0, 104, 105, 106, 0, 0, 0, 0, - 982, 0, 0, 107, 108, 0, 109, 110, 111, 112, - 113, 114, 115, 116, 983, 118, 984, 985, 0, 121, - 122, 123, 124, 125, 126, 986, 583, 127, 128, 987, - 988, 131, 0, 132, 133, 134, 135, 584, 0, 585, - 0, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 0, 148, 149, 150, 151, 152, 153, 0, 154, - 155, 156, 157, 586, 587, 588, 589, 590, 591, 592, - 163, 164, 165, 166, 167, 168, 169, 990, 991, 172, - 0, 173, 0, 174, 175, 176, 177, 178, 179, 0, - 180, 181, 182, 183, 184, 0, 0, 185, 186, 754, - 188, 189, 0, 190, 191, 192, 0, 193, 194, 195, - 0, 196, 197, 198, 199, 993, 201, 202, 203, 204, - 205, 593, 994, 207, 0, 208, 209, 995, 211, 0, - 212, 0, 213, 214, 0, 215, 216, 217, 218, 219, - 220, 0, 221, 0, 996, 997, 224, 0, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 0, 237, 238, 239, 240, 241, 242, 0, 243, 244, - 245, 246, 247, 248, 249, 250, 998, 999, 0, 1000, - 0, 254, 255, 256, 257, 258, 259, 260, 261, 262, - 263, 264, 0, 0, 265, 266, 267, 268, 0, 269, - 270, 271, 595, 596, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 291, 292, 293, 294, 295, 1001, 297, - 1002, 299, 300, 301, 302, 0, 303, 304, 305, 306, - 1004, 597, 308, 1005, 310, 311, 312, 0, 313, 314, - 0, 0, 315, 316, 317, 0, 0, 318, 319, 320, - 321, 322, 599, 324, 325, 326, 327, 328, 329, 330, - 331, 332, 333, 0, 334, 335, 600, 337, 338, 339, - 340, 341, 342, 0, 343, 344, 345, 346, 347, 348, - 0, 349, 350, 351, 1007, 353, 354, 355, 356, 0, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - 367, 368, 369, 0, 370, 371, 372, 373, 374, 375, - 2029, 2030, 378, 379, 380, 381, 382, 383, 384, 385, - 386, 387, 0, 388, 389, 390, 391, 392, 602, 394, - 395, 396, 397, 398, 399, 400, 401, 1009, 403, 0, - 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, - 414, 415, 416, 417, 603, 419, 0, 420, 421, 0, - 422, 423, 424, 425, 426, 427, 428, 0, 1010, 1011, - 0, 0, 431, 432, 604, 434, 605, 1012, 436, 437, - 606, 439, 440, 441, 442, 443, 0, 0, 444, 445, - 446, 447, 448, 607, 0, 450, 451, 452, 453, 454, - 455, 1013, 0, 457, 458, 459, 460, 461, 462, 463, - 0, 0, 464, 0, 0, 465, 466, 467, 468, 469, - 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, 483, 484, 485, 0, 0, 0, 0, - 0, 0, 0, 2031, 2032, 0, 0, 0, 0, 0, - 1018, 0, 1019, 0, 0, 0, 0, 1020, 1021, 1022, - 95, 976, 624, 977, 978, 979, 980, 981, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 96, 97, - 98, 99, 100, 101, 102, 103, 0, 104, 105, 106, - 0, 0, 0, 0, 982, 0, 0, 107, 108, 0, - 109, 110, 111, 112, 113, 114, 115, 116, 983, 118, - 984, 985, 0, 121, 122, 123, 124, 125, 126, 986, - 583, 127, 128, 987, 988, 131, 0, 132, 133, 134, - 135, 584, 0, 585, 0, 138, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 0, 148, 149, 150, 151, - 152, 153, 0, 154, 155, 156, 157, 586, 587, 588, - 589, 590, 591, 592, 163, 164, 165, 166, 167, 168, - 169, 990, 991, 172, 0, 173, 0, 174, 175, 176, - 177, 178, 179, 0, 180, 181, 182, 183, 184, 0, - 0, 185, 186, 754, 188, 189, 0, 190, 191, 192, - 0, 193, 194, 195, 0, 196, 197, 198, 199, 993, - 201, 202, 203, 204, 205, 593, 994, 207, 0, 208, - 209, 995, 211, 0, 212, 0, 213, 214, 0, 215, - 216, 217, 218, 219, 220, 0, 221, 0, 996, 997, - 224, 0, 225, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 0, 237, 238, 239, 240, 241, - 242, 0, 243, 244, 245, 246, 247, 248, 249, 250, - 998, 999, 0, 1000, 0, 254, 0, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 0, 0, 265, 266, - 267, 268, 0, 269, 270, 271, 595, 596, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, - 294, 295, 1001, 297, 1002, 299, 300, 301, 302, 0, - 303, 304, 305, 306, 1004, 597, 308, 1005, 310, 311, - 312, 0, 313, 314, 0, 0, 1006, 316, 317, 0, - 0, 318, 319, 320, 321, 322, 599, 324, 325, 326, - 327, 328, 329, 330, 331, 332, 333, 0, 334, 335, - 600, 337, 338, 339, 340, 341, 342, 0, 343, 344, - 345, 346, 347, 348, 0, 349, 350, 351, 1007, 353, - 354, 355, 356, 0, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, 369, 0, 370, 371, - 372, 373, 374, 375, 1008, 377, 378, 379, 380, 381, - 382, 383, 384, 385, 386, 387, 0, 388, 389, 390, - 391, 392, 602, 394, 395, 396, 397, 398, 399, 400, - 401, 1009, 403, 0, 404, 405, 406, 407, 408, 409, - 410, 411, 412, 413, 414, 415, 416, 417, 603, 419, - 0, 420, 421, 0, 422, 423, 424, 425, 426, 427, - 428, 0, 1010, 1011, 0, 0, 431, 432, 604, 434, - 605, 1012, 436, 437, 606, 439, 440, 441, 442, 443, - 0, 0, 444, 445, 446, 447, 448, 607, 0, 450, - 451, 452, 453, 454, 455, 1013, 0, 457, 458, 459, - 460, 461, 462, 463, 0, 0, 464, 0, 0, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, - 0, 0, 0, 0, 0, 0, 0, 1420, 1421, 0, - 0, 0, 0, 0, 1018, 0, 1019, 0, 0, 0, - 0, 1020, 1021, 1022, 95, 976, 624, 977, 978, 979, - 980, 981, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 96, 97, 98, 99, 100, 101, 102, 103, - 0, 104, 105, 106, 0, 0, 0, 0, 982, 0, - 0, 107, 108, 0, 109, 110, 111, 112, 113, 114, - 115, -1873, 983, 118, 984, 985, 0, 121, 122, 123, - 124, 125, 126, 986, 583, 127, 128, 987, 988, 131, - 0, 132, 133, 134, 135, 584, 0, 585, 0, 989, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 0, - 148, 149, 150, 151, 152, 153, 0, 154, 155, 156, - 3150, 586, 587, 588, 589, 590, 591, 592, 163, 164, - 165, 166, 167, 168, 169, 990, 991, 172, 992, 173, - 0, 174, 175, 176, 177, 178, 179, 0, 180, 181, - 182, 183, 184, 0, 0, 185, 186, 754, 188, 189, - 0, 190, 191, 192, 0, 193, 194, 195, 0, 196, - 197, 198, 199, 993, 201, 202, 203, 204, 205, 593, - 994, 207, 0, 208, 209, 995, 211, 0, 212, 0, - 213, 214, 0, 215, 216, 217, 218, -1873, 220, 0, - 221, 0, 996, 997, 224, 0, 225, 226, 227, 228, - 229, 230, 231, -1873, 233, 234, 235, 236, 0, 237, - 238, 239, 240, 241, 242, 0, 243, 244, 245, 246, - 247, 248, 249, 250, 998, 999, 0, 1000, 0, 254, - 0, 0, 257, 258, 259, 260, 261, 262, 263, 264, - 0, 0, 265, 266, 267, -1873, 0, 269, 270, 271, - 595, 596, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 1001, 297, 1002, 299, - 300, 301, 302, 0, 303, 304, 0, 306, 1004, 597, - 308, 1005, 310, 311, 312, 0, 313, 314, 0, 0, - 1006, 316, 317, 0, 0, 318, 319, 320, 321, 322, - 599, 324, 325, 326, 327, 328, 329, 330, 331, 332, - 333, 0, 334, 335, 600, 337, 338, 339, 340, 341, - 342, 0, 343, 344, 345, 346, 347, 348, 0, 349, - 350, 351, 1007, 353, 354, 355, 356, 0, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, - 369, 0, 370, 371, 372, 373, 374, 375, 1008, 377, - 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 0, 388, 389, 390, 391, 392, 602, 394, 395, 396, - 397, 398, -1873, 400, 401, 1009, 403, 0, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, - 416, 417, 603, 419, 0, 420, 421, 0, 422, 423, - 424, 425, 426, 427, 428, 0, 1010, 1011, 0, 0, - 431, 432, 604, 434, 605, 1012, 436, 437, 606, 439, - 440, 3151, 442, 443, 0, 0, 444, 445, 446, 447, - 448, 607, 0, 450, 451, 452, 453, 454, 455, 1013, - 0, 457, 458, 459, 460, 461, 462, 463, 0, 0, - 464, 0, 0, 465, 466, 467, 468, 469, 470, 471, - 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, - 482, 483, 484, 485, -1873, 0, 0, 0, 0, 0, - 0, 1015, 1016, 0, 0, 0, 0, 0, 1018, 0, - 1019, 0, 0, 0, 0, 1020, 1021, 1022, 95, 976, - 624, 977, 978, 979, 980, 981, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 96, 97, 98, 99, - 100, 101, 102, 103, 0, 104, 105, 106, 0, 0, - 0, 0, 982, 0, 0, 107, 108, 0, 109, 110, - 111, 112, 113, 114, 115, 0, 983, 118, 984, 985, - 0, 121, 122, 123, 124, 125, 126, 986, 583, 127, - 128, 987, 988, 131, 0, 132, 133, 134, 135, 584, - 0, 585, 0, 989, 139, 140, 141, 142, 143, 144, - 145, 146, 147, 0, 148, 149, 150, 151, 152, 153, - 0, 154, 155, 156, 157, 586, 587, 588, 589, 590, - 591, 592, 163, 164, 165, 166, 167, 168, 169, 990, - 991, 172, 992, 173, 0, 174, 175, 176, 177, 178, - 179, 0, 180, 181, 182, 183, 184, 0, 0, 185, - 186, 754, 188, 189, 0, 190, 191, 192, 0, 193, - 0, 195, 0, 196, 197, 198, 199, 993, 201, 202, - 203, 204, 205, 593, 994, 207, 0, 208, 209, 995, - 211, 0, 212, 0, 213, 214, 0, 215, 216, 217, - 218, 0, 220, 0, 221, 0, 996, 997, 224, 0, - 225, 226, 227, 228, 229, 230, 231, 0, 233, 234, - 235, 236, 0, 237, 238, 239, 240, 241, 242, 0, - 243, 244, 245, 246, 247, 248, 249, 250, 998, 999, - 0, 1000, 0, 254, 0, 0, 257, 258, 259, 260, - 261, 262, 263, 264, 0, 0, 265, 266, 267, 0, - 0, 269, 270, 271, 595, 596, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, + 0, 0, 0, 0, 1123, 105, 106, 107, 108, 109, + 110, 111, 112, 0, 113, 114, 115, 0, 0, 0, + 0, 0, 0, 0, 116, 117, 0, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 0, + 130, 131, 132, 133, 134, 135, 0, 606, 136, 137, + 138, 139, 140, 0, 141, 142, 143, 144, 607, 0, + 608, 0, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 0, 157, 158, 159, 160, 161, 162, 0, + 163, 164, 165, 166, 609, 610, 611, 612, 613, 614, + 615, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 0, 182, 0, 183, 184, 185, 186, 187, 188, + 0, 189, 190, 191, 192, 193, 0, 0, 194, 195, + 196, 197, 198, 0, 199, 200, 201, 0, 202, 203, + 204, 0, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 616, 0, 216, 0, 217, 218, 219, 220, + 0, 221, 0, 222, 223, 21, 224, 225, 226, 227, + 228, 229, 0, 230, 0, 231, 232, 233, 0, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 0, 246, 247, 248, 249, 250, 251, 0, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 0, + 262, 0, 263, 264, 265, 266, 267, 268, 269, 270, + 271, 272, 273, 617, 0, 274, 275, 276, 277, 0, + 278, 279, 280, 618, 619, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 1001, 297, 1002, 299, 300, 301, 302, 0, 303, 304, - 0, 306, 1004, 597, 308, 1005, 310, 311, 312, 0, - 313, 314, 0, 0, 1006, 316, 317, 0, 0, 318, - 319, 320, 321, 322, 599, 324, 325, 326, 327, 328, - 329, 330, 331, 332, 333, 0, 334, 335, 600, 337, - 338, 339, 340, 341, 342, 0, 343, 344, 345, 346, - 347, 348, 0, 349, 350, 351, 1007, 353, 354, 355, - 356, 0, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 0, 370, 371, 372, 373, - 374, 375, 1008, 377, 378, 379, 380, 381, 382, 383, - 384, 385, 386, 387, 0, 388, 389, 390, 391, 392, - 602, 394, 395, 396, 397, 398, 0, 400, 401, 1009, - 403, 0, 404, 405, 406, 407, 408, 409, 410, 411, - 412, 413, 414, 415, 416, 417, 603, 419, 0, 420, - 421, 0, 422, 423, 424, 425, 426, 427, 428, 0, - 1010, 1011, 0, 0, 431, 432, 604, 434, 605, 1012, - 436, 437, 606, 439, 440, 441, 442, 443, 0, 0, - 444, 445, 446, 447, 448, 607, 0, 450, 451, 452, - 453, 454, 455, 1013, 0, 457, 458, 459, 460, 461, - 462, 463, 0, 0, 464, 0, 0, 465, 466, 467, - 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, - 478, 479, 480, 481, 482, 483, 484, 485, 0, 0, - 0, 0, 0, 0, 508, 1015, 1016, 0, 0, 0, - 0, 0, 1018, 0, 1019, 0, 0, 0, 0, 1020, - 1021, 1022, 96, 97, 98, 99, 100, 101, 102, 103, - 0, 104, 105, 106, 0, 0, 0, 0, 0, 942, - 0, 107, 108, 0, 109, 110, 111, 0, 113, 114, - 115, 116, 117, 0, 119, 120, 0, 121, 122, 123, - 124, 125, 126, 0, 0, 127, 128, 129, 130, 131, - 0, 132, 133, 134, 135, 136, 0, 0, 0, 138, - 139, 140, 141, 142, 143, 0, 145, 146, 147, 0, - 148, 149, 150, 151, 152, 153, 0, -641, 155, 156, - 157, 0, 0, 0, 0, 0, 0, 0, 163, 164, - 165, 166, 167, 168, 169, 170, 171, 172, 0, 173, - 0, 174, 175, 176, 177, 178, 179, 0, 180, 181, - 182, 183, 184, 0, 0, 185, 186, 187, 188, 189, - 0, 190, 191, 192, 0, 193, 194, 195, 0, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 0, 207, 0, 208, 209, 210, 211, 0, 212, 0, - 213, 0, 0, -641, 216, 217, 511, 0, 220, 0, - 221, 0, 222, 223, 224, 0, 225, 226, 227, 228, - 229, 230, 231, 0, 233, 234, 235, 236, 0, 237, - 238, 239, 240, 241, 242, 0, 243, -641, 245, 246, - 247, 248, 249, 250, 251, 252, 0, 253, 0, 254, - 0, 0, 257, -641, 259, 260, 261, 262, 263, 264, - 0, 0, 265, -641, 267, 0, 0, 269, 270, 271, - 0, 0, 272, 273, 274, 275, 276, 512, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 296, -641, 298, 299, - 300, 301, 302, 0, 303, 304, 0, 306, 0, 307, - 308, 309, 310, 311, 312, 0, 313, 314, 0, 0, - 315, 316, 317, 0, 0, 318, 319, 0, 321, 0, - 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, - 333, 0, 334, 335, 336, 337, 338, 339, 340, 341, - 342, 0, 343, 344, 345, 346, 347, 348, 0, 349, - 350, 351, 352, 353, 354, 355, 356, 0, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, - 369, 0, 370, 371, -641, 373, 374, 375, 376, 377, - 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 0, 388, 389, 390, 391, 392, 0, 394, 395, 396, - 397, 398, 0, 400, 401, 402, 403, 0, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, - 514, 417, 418, 419, 0, 420, 421, 0, 422, -641, - 424, 425, 426, 427, 428, 0, 429, 430, 0, 0, - 431, 432, 433, 434, 435, 0, 436, 437, 438, 439, - 440, 441, 442, 443, 0, 0, 444, 445, 446, 447, - 448, 0, 0, 450, 451, 452, 453, 454, 455, 456, - 0, 457, 0, 459, 460, 461, 462, 463, 0, 0, - 464, 0, 0, 465, 466, 467, 468, 469, 470, 471, - 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, - 482, 483, 484, 485, 95, 0, 509, 0, 0, 0, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + 306, 307, 308, 309, 310, 311, 0, 312, 313, 314, + 315, 0, 620, 317, 318, 319, 320, 321, 0, 322, + 323, 0, 621, 324, 325, 326, 0, 0, 327, 328, + 329, 330, 331, 622, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342, 0, 343, 344, 623, 346, 347, + 348, 349, 350, 351, 352, 0, 353, 354, 355, 356, + 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, + 366, 0, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 0, 380, 381, 382, 383, + 384, 385, 386, 624, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 29, 398, 399, 400, 401, 402, + 625, 404, 405, 406, 407, 408, 409, 410, 411, 412, + 413, 0, 414, 415, 416, 417, 418, 419, 420, 421, + 422, 423, 424, 425, 426, 427, 626, 429, 0, 430, + 431, 34, 432, 433, 434, 435, 436, 437, 438, 0, + 439, 440, 0, 0, 441, 442, 627, 444, 628, 0, + 446, 447, 629, 449, 450, 451, 452, 453, 0, 0, + 454, 455, 456, 457, 458, 459, 630, 0, 461, 462, + 463, 464, 465, 631, 467, 0, 468, 469, 470, 471, + 472, 473, 474, 0, 0, 475, 0, 39, 476, 477, + 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, + 488, 489, 490, 491, 492, 493, 494, 495, 496, 0, + 0, 40, 855, 1427, 515, 0, 0, 0, 1016, 0, + 0, 0, 0, 0, 0, 632, 0, 0, 0, 0, + 105, 106, 107, 108, 109, 110, 111, 112, 0, 113, + 114, 115, 0, 0, 0, 0, 0, 0, 0, 116, + 117, 0, 118, 119, 120, 856, 122, 123, 124, 857, + 858, 859, 860, 861, 0, 130, 131, 132, 133, 134, + 135, 0, 0, 136, 137, 862, 863, 140, 0, 141, + 142, 143, 144, 864, 0, 865, 0, 866, 148, 149, + 150, 151, 152, 867, 154, 155, 156, 0, 157, 158, + 159, 160, 161, 162, 0, 868, 164, 165, 166, 869, + 870, 871, 872, 0, 0, 873, 172, 173, 174, 175, + 176, 177, 178, 874, 875, 181, 0, 182, 0, 183, + 184, 185, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 0, 0, 194, 195, 196, 197, 198, 0, 199, + 200, 201, 0, 202, 203, 204, 0, 205, 206, 207, + 208, 876, 210, 211, 212, 213, 214, 877, 1428, 216, + 0, 217, 218, 878, 220, 0, 221, 0, 222, 879, + 0, 880, 225, 226, 881, 882, 229, 0, 230, 0, + 883, 884, 233, 0, 234, 235, 236, 237, 238, 239, + 240, 885, 242, 243, 244, 245, 0, 246, 247, 248, + 249, 250, 251, 0, 252, 886, 887, 255, 256, 257, + 258, 259, 888, 889, 0, 890, 0, 263, 891, 892, + 266, 893, 268, 269, 270, 271, 272, 273, 0, 0, + 274, 894, 276, 895, 0, 278, 279, 280, 0, 0, + 281, 282, 283, 284, 285, 896, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 897, 898, 899, 308, 309, 310, + 900, 0, 312, 313, 901, 315, 0, 902, 317, 903, + 319, 320, 321, 0, 322, 323, 1429, 0, 324, 325, + 326, 0, 0, 327, 904, 905, 330, 906, 907, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 0, + 343, 344, 908, 909, 347, 348, 910, 350, 351, 352, + 0, 353, 354, 355, 356, 357, 358, 0, 359, 360, + 361, 911, 363, 364, 365, 366, 0, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 0, 380, 381, 912, 383, 384, 385, 913, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 0, + 398, 399, 400, 401, 402, 914, 404, 915, 406, 407, + 408, 916, 410, 411, 917, 413, 0, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 918, + 427, 919, 429, 0, 430, 431, 0, 432, 920, 434, + 435, 436, 437, 438, 0, 921, 922, 0, 0, 441, + 442, 923, 444, 924, 1430, 446, 447, 925, 449, 450, + 451, 452, 453, 0, 0, 454, 455, 456, 457, 458, + 459, 926, 0, 461, 462, 463, 464, 465, 1312, 928, + 0, 468, 929, 470, 471, 472, 473, 474, 0, 0, + 475, 0, 0, 476, 477, 478, 479, 480, 481, 930, + 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, + 493, 494, 495, 496, 104, 0, 530, 0, 0, 0, + 0, 1431, 1432, 2265, 0, 0, 0, 0, 0, 0, + 2266, 0, 105, 106, 107, 108, 109, 110, 111, 112, + 0, 113, 114, 115, 0, 0, 0, 0, 0, 0, + 0, 116, 117, 0, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 0, 130, 131, 132, + 133, 134, 135, 0, 606, 136, 137, 138, 139, 140, + 0, 141, 142, 143, 144, 607, 0, 608, 0, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 0, + 157, 158, 159, 160, 161, 162, 0, 163, 164, 165, + 166, 609, 610, 611, 612, 613, 614, 615, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 0, 182, + 0, 183, 184, 185, 186, 187, 188, 0, 189, 190, + 191, 192, 193, 0, 0, 194, 195, 196, 197, 198, + 0, 199, 200, 201, 0, 202, 203, 204, 0, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 616, + 0, 216, 0, 217, 218, 219, 220, 0, 221, 0, + 222, 223, 0, 224, 225, 226, 227, 228, 229, 0, + 230, 0, 231, 232, 233, 0, 234, 235, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 0, 246, + 247, 248, 249, 250, 251, 0, 252, 253, 254, 255, + 256, 257, 258, 259, 260, 261, 0, 262, 0, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 617, 0, 274, 275, 276, 277, 0, 278, 279, 280, + 618, 619, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 0, 312, 313, 314, 315, 0, 620, + 317, 318, 319, 320, 321, 0, 322, 323, 0, 621, + 324, 325, 326, 0, 0, 327, 328, 329, 330, 331, + 622, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 0, 343, 344, 623, 346, 347, 348, 349, 350, + 351, 352, 0, 353, 354, 355, 356, 357, 358, 0, + 359, 360, 361, 362, 363, 364, 365, 366, 0, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 0, 380, 381, 382, 383, 384, 385, 386, + 624, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 0, 398, 399, 400, 401, 402, 625, 404, 405, + 406, 407, 408, 409, 410, 411, 412, 413, 0, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 426, 427, 626, 429, 0, 430, 431, 0, 432, + 433, 434, 435, 436, 437, 438, 0, 439, 440, 0, + 0, 441, 442, 627, 444, 628, 0, 446, 447, 629, + 449, 450, 451, 452, 453, 0, 0, 454, 455, 456, + 457, 458, 459, 630, 0, 461, 462, 463, 464, 465, + 631, 467, 0, 468, 469, 470, 471, 472, 473, 474, + 0, 0, 475, 0, 0, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, + 491, 492, 493, 494, 495, 496, 855, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1085, 96, 97, 98, 99, 100, 101, 102, 103, - 0, 104, 105, 106, 0, 0, 0, 0, 0, 0, - 0, 107, 108, 0, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 0, 121, 122, 123, - 124, 125, 126, 0, 583, 127, 128, 129, 130, 131, - 0, 132, 133, 134, 135, 584, 0, 585, 0, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 0, - 148, 149, 150, 151, 152, 153, 0, 154, 155, 156, - 157, 586, 587, 588, 589, 590, 591, 592, 163, 164, - 165, 166, 167, 168, 169, 170, 171, 172, 0, 173, - 0, 174, 175, 176, 177, 178, 179, 0, 180, 181, - 182, 183, 184, 0, 0, 185, 186, 187, 188, 189, - 0, 190, 191, 192, 0, 193, 194, 195, 0, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 593, - 0, 207, 0, 208, 209, 210, 211, 0, 212, 0, - 213, 214, 19, 215, 216, 217, 218, 219, 220, 0, - 221, 0, 222, 223, 224, 0, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 0, 237, - 238, 239, 240, 241, 242, 0, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 0, 253, 0, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 594, 0, 265, 266, 267, 268, 0, 269, 270, 271, - 595, 596, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, - 300, 301, 302, 0, 303, 304, 305, 306, 0, 597, - 308, 309, 310, 311, 312, 0, 313, 314, 0, 598, - 315, 316, 317, 0, 0, 318, 319, 320, 321, 322, - 599, 324, 325, 326, 327, 328, 329, 330, 331, 332, - 333, 0, 334, 335, 600, 337, 338, 339, 340, 341, - 342, 0, 343, 344, 345, 346, 347, 348, 0, 349, - 350, 351, 352, 353, 354, 355, 356, 0, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, - 369, 0, 370, 371, 372, 373, 374, 375, 376, 601, - 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, - 27, 388, 389, 390, 391, 392, 602, 394, 395, 396, - 397, 398, 399, 400, 401, 402, 403, 0, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, - 416, 417, 603, 419, 0, 420, 421, 32, 422, 423, - 424, 425, 426, 427, 428, 0, 429, 430, 0, 0, - 431, 432, 604, 434, 605, 0, 436, 437, 606, 439, - 440, 441, 442, 443, 0, 0, 444, 445, 446, 447, - 448, 607, 0, 450, 451, 452, 453, 454, 608, 456, - 0, 457, 458, 459, 460, 461, 462, 463, 0, 0, - 464, 0, 36, 465, 466, 467, 468, 469, 470, 471, - 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, - 482, 483, 484, 485, 0, 0, 37, 823, 1377, 624, - 0, 0, 0, 980, 0, 0, 0, 0, 0, 0, - 609, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 824, 113, 114, 115, 825, 826, 827, 828, 829, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 830, 831, 131, 0, 132, 133, 134, 135, 832, 0, - 833, 0, 834, 139, 140, 141, 142, 143, 835, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 836, 155, 156, 157, 837, 838, 839, 840, 0, 0, - 841, 163, 164, 165, 166, 167, 168, 169, 842, 843, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 844, 201, 202, 203, - 204, 205, 845, 1378, 207, 0, 208, 209, 846, 211, - 0, 212, 0, 213, 847, 0, 848, 216, 217, 849, - 850, 220, 0, 221, 0, 851, 852, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 853, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 854, 855, 246, 247, 248, 249, 250, 856, 857, 0, - 858, 0, 254, 859, 860, 257, 861, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 862, 267, 863, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 864, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 865, - 866, 867, 299, 300, 301, 868, 0, 303, 304, 869, - 306, 0, 870, 308, 871, 310, 311, 312, 0, 313, - 314, 1379, 0, 315, 316, 317, 0, 0, 318, 872, - 873, 321, 874, 875, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 876, 337, 338, - 877, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 878, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 879, 373, 374, - 375, 880, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 881, - 394, 882, 396, 397, 398, 883, 400, 401, 884, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 885, 417, 886, 419, 0, 420, 421, - 0, 422, 887, 424, 425, 426, 427, 428, 0, 888, - 889, 0, 0, 431, 432, 890, 434, 891, 1380, 436, - 437, 892, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 893, 0, 450, 451, 452, 453, - 454, 1270, 895, 0, 457, 896, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 897, 898, 899, 900, 901, 902, 903, 904, - 905, 906, 907, 482, 483, 484, 485, 95, 0, 509, - 0, 0, 0, 0, 1381, 1382, 2203, 0, 0, 0, - 0, 0, 0, 2204, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 583, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 584, 0, - 585, 0, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 154, 155, 156, 157, 586, 587, 588, 589, 590, 591, - 592, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 593, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 214, 0, 215, 216, 217, 218, - 219, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 244, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 264, 594, 0, 265, 266, 267, 268, 0, - 269, 270, 271, 595, 596, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 0, 0, 632, 0, 105, 106, 107, 108, 109, 110, + 111, 112, 0, 113, 114, 115, 3, 4, 0, 0, + 0, 0, 0, 116, 117, 0, 118, 119, 120, 856, + 122, 123, 124, 857, 858, 859, 860, 861, 0, 130, + 131, 132, 133, 134, 135, 0, 0, 136, 137, 862, + 863, 140, 0, 141, 142, 143, 144, 864, 0, 865, + 0, 866, 148, 149, 150, 151, 152, 867, 154, 155, + 156, 0, 157, 158, 159, 160, 161, 162, 0, 868, + 164, 165, 166, 869, 870, 871, 872, 0, 0, 873, + 172, 173, 174, 175, 176, 177, 178, 874, 875, 181, + 0, 182, 0, 183, 184, 185, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 0, 0, 194, 195, 196, + 197, 198, 0, 199, 200, 201, 0, 202, 203, 204, + 0, 205, 206, 207, 208, 876, 210, 211, 212, 213, + 214, 877, 0, 216, 0, 217, 218, 878, 220, 0, + 221, 0, 222, 879, 21, 880, 225, 226, 881, 882, + 229, 0, 230, 0, 883, 884, 233, 0, 234, 235, + 236, 237, 238, 239, 240, 885, 242, 243, 244, 245, + 0, 246, 247, 248, 249, 250, 251, 0, 252, 886, + 887, 255, 256, 257, 258, 259, 888, 889, 0, 890, + 0, 263, 891, 892, 266, 893, 268, 269, 270, 271, + 272, 273, 0, 0, 274, 894, 276, 895, 0, 278, + 279, 280, 0, 0, 281, 282, 283, 284, 285, 896, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 0, 303, 304, 305, - 306, 0, 597, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 598, 315, 316, 317, 0, 0, 318, 319, - 320, 321, 322, 599, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 600, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 372, 373, 374, - 375, 376, 601, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 602, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 416, 417, 603, 419, 0, 420, 421, - 0, 422, 423, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 604, 434, 605, 0, 436, - 437, 606, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 607, 0, 450, 451, 452, 453, - 454, 608, 456, 0, 457, 458, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 823, 0, 0, + 297, 298, 299, 300, 301, 302, 303, 304, 897, 898, + 899, 308, 309, 310, 900, 0, 312, 313, 901, 315, + 0, 902, 317, 903, 319, 320, 321, 0, 322, 323, + 0, 0, 324, 325, 326, 0, 0, 327, 904, 905, + 330, 906, 907, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 0, 343, 344, 908, 909, 347, 348, + 910, 350, 351, 352, 0, 353, 354, 355, 356, 357, + 358, 0, 359, 360, 361, 911, 363, 364, 365, 366, + 0, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 0, 380, 381, 912, 383, 384, + 385, 913, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 29, 398, 399, 400, 401, 402, 914, + 404, 915, 406, 407, 408, 916, 410, 411, 917, 413, + 0, 414, 415, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 425, 918, 427, 919, 429, 0, 430, 431, + 34, 432, 920, 434, 435, 436, 437, 438, 0, 921, + 922, 0, 0, 441, 442, 923, 444, 924, 0, 446, + 447, 925, 449, 450, 451, 452, 453, 0, 0, 454, + 455, 456, 457, 458, 459, 926, 0, 461, 462, 463, + 464, 465, 927, 928, 0, 468, 929, 470, 471, 472, + 473, 474, 0, 0, 475, 0, 39, 476, 477, 478, + 479, 480, 481, 930, 931, 932, 933, 934, 935, 936, + 937, 938, 939, 940, 493, 494, 495, 496, 104, 0, + 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 41, 0, 105, 106, 107, 108, + 109, 110, 111, 112, 0, 113, 114, 115, 0, 0, + 0, 0, 0, 0, 0, 116, 117, 0, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 0, 130, 131, 132, 133, 134, 135, 0, 606, 136, + 137, 138, 139, 140, 0, 141, 142, 143, 144, 607, + 0, 608, 0, 147, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 0, 157, 158, 159, 160, 161, 162, + 0, 163, 164, 165, 166, 609, 610, 611, 612, 613, + 614, 615, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 0, 182, 0, 183, 184, 185, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 0, 0, 194, + 195, 196, 197, 198, 0, 199, 200, 201, 0, 202, + 203, 204, 0, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 616, 0, 216, 0, 217, 218, 219, + 220, 0, 221, 0, 222, 223, 0, 224, 225, 226, + 227, 228, 229, 0, 230, 0, 231, 232, 233, 0, + 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, + 244, 245, 0, 246, 247, 248, 249, 250, 251, 0, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + 0, 262, 0, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 0, 0, 274, 275, 276, 277, + 0, 278, 279, 280, 618, 619, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 0, 312, 313, + 314, 315, 0, 620, 317, 318, 319, 320, 321, 0, + 322, 323, 0, 0, 324, 325, 326, 0, 0, 327, + 328, 329, 330, 331, 622, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 0, 343, 344, 623, 346, + 347, 348, 349, 350, 351, 352, 0, 353, 354, 355, + 356, 357, 358, 0, 359, 360, 361, 362, 363, 364, + 365, 366, 0, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 0, 380, 381, 382, + 383, 384, 385, 386, 624, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 0, 398, 399, 400, 401, + 402, 625, 404, 405, 406, 407, 408, 409, 410, 411, + 412, 413, 0, 414, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 425, 426, 427, 626, 429, 0, + 430, 431, 0, 432, 433, 434, 435, 436, 437, 438, + 0, 439, 440, 0, 0, 441, 442, 627, 444, 628, + 0, 446, 447, 629, 449, 450, 451, 452, 453, 0, + 0, 454, 455, 456, 457, 458, 459, 630, 0, 461, + 462, 463, 464, 465, 466, 467, 0, 468, 469, 470, + 471, 472, 473, 474, 0, 0, 475, 0, 0, 476, + 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, + 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, + 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 41, 0, 105, 106, + 107, 108, 109, 110, 111, 112, 0, 113, 114, 115, + 0, 0, 0, 0, 0, 0, 0, 116, 117, 0, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 0, 130, 131, 132, 133, 134, 135, 0, + 606, 136, 137, 138, 139, 140, 0, 141, 142, 143, + 144, 607, 0, 608, 0, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 0, 157, 158, 159, 160, + 161, 162, 0, 163, 164, 165, 166, 609, 610, 611, + 612, 613, 614, 615, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 0, 182, 0, 183, 184, 185, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 0, + 0, 194, 195, 196, 197, 198, 0, 199, 200, 201, + 0, 202, 203, 204, 0, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 616, 0, 216, 0, 217, + 218, 219, 220, 0, 221, 0, 222, 223, 0, 224, + 225, 226, 227, 228, 229, 0, 230, 0, 231, 232, + 233, 0, 234, 235, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 0, 246, 247, 248, 249, 250, + 251, 0, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 0, 262, 0, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 0, 0, 274, 275, + 276, 277, 0, 278, 279, 280, 618, 619, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, 310, 311, 0, + 312, 313, 314, 315, 0, 620, 317, 318, 319, 320, + 321, 0, 322, 323, 0, 0, 324, 325, 326, 0, + 0, 327, 328, 329, 330, 331, 622, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 0, 343, 344, + 623, 346, 347, 348, 349, 350, 351, 352, 0, 353, + 354, 355, 356, 357, 358, 0, 359, 360, 361, 362, + 363, 364, 365, 366, 0, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 0, 380, + 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 0, 398, 399, + 400, 401, 402, 625, 404, 405, 406, 407, 408, 409, + 410, 411, 412, 413, 0, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 426, 427, 626, + 429, 0, 430, 431, 0, 432, 433, 434, 435, 436, + 437, 438, 0, 439, 440, 0, 0, 441, 442, 627, + 444, 628, 0, 446, 447, 629, 449, 450, 451, 452, + 453, 0, 0, 454, 455, 456, 457, 458, 459, 630, + 0, 461, 462, 463, 464, 465, 466, 467, 0, 468, + 469, 470, 471, 472, 473, 474, 0, 0, 475, 0, + 0, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, + 495, 496, 504, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3079, 0, + 105, 106, 107, 108, 109, 110, 111, 112, 711, 113, + 114, 115, 0, 0, 0, 0, 0, 0, 0, 116, + 117, 0, 118, 119, 120, 0, 122, 123, 124, 125, + 126, 0, 128, 129, 0, 130, 131, 132, 133, 134, + 135, 0, 0, 136, 137, 138, 139, 140, 0, 141, + 142, 143, 144, 145, 0, 0, 0, 147, 148, 149, + 150, 151, 152, 0, 154, 155, 156, 0, 157, 158, + 159, 160, 161, 162, 0, 0, 164, 165, 166, 0, + 0, 0, 0, 0, 0, 0, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 0, 182, 0, 183, + 184, 185, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 0, 0, 194, 195, 196, 197, 198, 0, 199, + 200, 201, 0, 202, 203, 204, 0, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 0, 216, + 0, 217, 218, 219, 220, 0, 221, 0, 222, 0, + 21, 0, 225, 226, 505, 0, 229, 0, 230, 0, + 231, 232, 233, 0, 234, 235, 236, 237, 238, 239, + 240, 0, 242, 243, 244, 245, 0, 246, 247, 248, + 249, 250, 251, 0, 252, 0, 254, 255, 256, 257, + 258, 259, 260, 261, 0, 262, 0, 263, 0, 0, + 266, 0, 268, 269, 270, 271, 272, 273, 0, 0, + 274, 0, 276, 0, 0, 278, 279, 280, 0, 0, + 281, 282, 283, 284, 285, 506, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, 0, 307, 308, 309, 310, + 311, 0, 312, 313, 0, 315, 0, 316, 317, 318, + 319, 320, 321, 0, 322, 323, 0, 0, 324, 325, + 326, 0, 0, 327, 328, 0, 330, 0, 332, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 0, + 343, 344, 345, 0, 347, 348, 349, 350, 351, 352, + 0, 353, 354, 355, 356, 357, 358, 0, 359, 360, + 361, 362, 363, 364, 365, 366, 0, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 0, 380, 381, 0, 383, 384, 385, 386, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 29, + 398, 399, 400, 401, 402, 0, 404, 405, 406, 407, + 408, 0, 410, 411, 412, 413, 0, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 507, + 427, 428, 429, 0, 430, 431, 34, 432, 0, 434, + 435, 436, 437, 438, 0, 712, 440, 0, 0, 713, + 442, 443, 444, 445, 0, 446, 447, 448, 449, 450, + 451, 452, 453, 0, 0, 454, 455, 456, 457, 458, + 459, 0, 0, 461, 462, 463, 464, 465, 631, 467, + 0, 468, 0, 470, 471, 472, 473, 474, 0, 0, + 475, 0, 39, 476, 477, 478, 479, 480, 481, 482, + 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, + 493, 494, 495, 496, 504, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 609, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 3, 4, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 824, 113, 114, 115, 825, 826, 827, 828, 829, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 830, 831, 131, 0, 132, 133, 134, 135, 832, 0, - 833, 0, 834, 139, 140, 141, 142, 143, 835, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 836, 155, 156, 157, 837, 838, 839, 840, 0, 0, - 841, 163, 164, 165, 166, 167, 168, 169, 842, 843, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 844, 201, 202, 203, - 204, 205, 845, 0, 207, 0, 208, 209, 846, 211, - 0, 212, 0, 213, 847, 19, 848, 216, 217, 849, - 850, 220, 0, 221, 0, 851, 852, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 853, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 854, 855, 246, 247, 248, 249, 250, 856, 857, 0, - 858, 0, 254, 859, 860, 257, 861, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 862, 267, 863, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 864, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 865, - 866, 867, 299, 300, 301, 868, 0, 303, 304, 869, - 306, 0, 870, 308, 871, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 872, - 873, 321, 874, 875, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 876, 337, 338, - 877, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 878, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 879, 373, 374, - 375, 880, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 27, 388, 389, 390, 391, 392, 881, - 394, 882, 396, 397, 398, 883, 400, 401, 884, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 885, 417, 886, 419, 0, 420, 421, - 32, 422, 887, 424, 425, 426, 427, 428, 0, 888, - 889, 0, 0, 431, 432, 890, 434, 891, 0, 436, - 437, 892, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 893, 0, 450, 451, 452, 453, - 454, 894, 895, 0, 457, 896, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 36, 465, 466, 467, 468, - 469, 470, 897, 898, 899, 900, 901, 902, 903, 904, - 905, 906, 907, 482, 483, 484, 485, 95, 0, 37, + 41, 0, 105, 106, 107, 108, 109, 110, 111, 112, + 0, 113, 114, 115, 0, 0, 0, 0, 0, 0, + 0, 116, 117, 0, 118, 119, 120, 0, 122, 123, + 124, 125, 126, 0, 128, 129, 0, 130, 131, 132, + 133, 134, 135, 0, 0, 136, 137, 138, 139, 140, + 0, 141, 142, 143, 144, 145, 0, 0, 0, 147, + 148, 149, 150, 151, 152, 0, 154, 155, 156, 0, + 157, 158, 159, 160, 161, 162, 0, 0, 164, 165, + 166, 0, 0, 0, 0, 0, 0, 0, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 0, 182, + 0, 183, 184, 185, 186, 187, 188, 0, 189, 190, + 191, 192, 193, 0, 0, 194, 195, 196, 197, 198, + 0, 199, 200, 201, 0, 202, 203, 204, 0, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 0, 216, 0, 217, 218, 219, 220, 0, 221, 0, + 222, 0, 21, 0, 225, 226, 505, 0, 229, 0, + 230, 0, 231, 232, 233, 0, 234, 235, 236, 237, + 238, 239, 240, 0, 242, 243, 244, 245, 0, 246, + 247, 248, 249, 250, 251, 0, 252, 0, 254, 255, + 256, 257, 258, 259, 260, 261, 0, 262, 0, 263, + 0, 0, 266, 0, 268, 269, 270, 271, 272, 273, + 0, 0, 274, 0, 276, 0, 0, 278, 279, 280, + 0, 0, 281, 282, 283, 284, 285, 506, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 0, 307, 308, + 309, 310, 311, 0, 312, 313, 0, 315, 0, 316, + 317, 318, 319, 320, 321, 0, 322, 323, 0, 0, + 324, 325, 326, 0, 0, 327, 328, 0, 330, 0, + 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 0, 343, 344, 345, 0, 347, 348, 349, 350, + 351, 352, 0, 353, 354, 355, 356, 357, 358, 0, + 359, 360, 361, 362, 363, 364, 365, 366, 0, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 0, 380, 381, 0, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 29, 398, 399, 400, 401, 402, 0, 404, 405, + 406, 407, 408, 0, 410, 411, 412, 413, 0, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 507, 427, 428, 429, 0, 430, 431, 34, 432, + 0, 434, 435, 436, 437, 438, 0, 439, 440, 0, + 0, 441, 442, 443, 444, 445, 0, 446, 447, 448, + 449, 450, 451, 452, 453, 0, 0, 454, 455, 456, + 457, 458, 459, 0, 0, 461, 462, 463, 464, 465, + 631, 467, 0, 468, 0, 470, 471, 472, 473, 474, + 0, 0, 475, 0, 39, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, + 491, 492, 493, 494, 495, 496, 0, 504, 40, 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 38, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 583, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 584, 0, - 585, 0, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 154, 155, 156, 157, 586, 587, 588, 589, 590, 591, - 592, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 593, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 214, 0, 215, 216, 217, 218, - 219, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 244, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 266, 267, 268, 0, - 269, 270, 271, 595, 596, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 0, 303, 304, 305, - 306, 0, 597, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 320, 321, 322, 599, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 600, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 372, 373, 374, - 375, 376, 601, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 602, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 416, 417, 603, 419, 0, 420, 421, - 0, 422, 423, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 604, 434, 605, 0, 436, - 437, 606, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 607, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 458, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 95, 0, 0, + 0, 0, 41, 0, 0, 105, 106, 107, 108, 109, + 110, 111, 112, 0, 113, 114, 115, 0, 0, 0, + 0, 0, 0, 0, 116, 117, 0, 118, 119, 120, + 0, 122, 123, 124, 125, 126, 0, 128, 129, 0, + 130, 131, 132, 133, 134, 135, 0, 0, 136, 137, + 138, 139, 140, 0, 141, 142, 143, 144, 145, 0, + 0, 0, 147, 148, 149, 150, 151, 152, 0, 154, + 155, 156, 0, 157, 158, 159, 160, 161, 162, 0, + 0, 164, 165, 166, 0, 0, 0, 0, 0, 0, + 0, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 0, 182, 0, 183, 184, 185, 186, 187, 188, + 0, 189, 190, 191, 192, 193, 0, 0, 194, 195, + 196, 197, 198, 0, 199, 200, 201, 0, 202, 203, + 204, 0, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 0, 216, 0, 217, 218, 219, 220, + 0, 221, 0, 222, 0, 0, 0, 225, 226, 505, + 0, 229, 0, 230, 0, 231, 232, 233, 0, 234, + 235, 236, 237, 238, 239, 240, 0, 242, 243, 244, + 245, 0, 246, 247, 248, 249, 250, 251, 0, 252, + 0, 254, 255, 256, 257, 258, 259, 260, 261, 0, + 262, 0, 263, 0, 0, 266, 0, 268, 269, 270, + 271, 272, 273, 0, 0, 274, 0, 276, 0, 0, + 278, 279, 280, 0, 0, 281, 282, 283, 284, 285, + 506, 287, 288, 289, 290, 291, 292, 293, 294, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + 0, 307, 308, 309, 310, 311, 0, 312, 313, 0, + 315, 0, 316, 317, 318, 319, 320, 321, 0, 322, + 323, 0, 0, 324, 325, 326, 0, 0, 327, 328, + 0, 330, 0, 332, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342, 0, 343, 344, 345, 0, 347, + 348, 349, 350, 351, 352, 0, 353, 354, 355, 356, + 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, + 366, 0, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 0, 380, 381, 0, 383, + 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 0, 398, 399, 400, 401, 402, + 0, 404, 405, 406, 407, 408, 0, 410, 411, 412, + 413, 0, 414, 415, 416, 417, 418, 419, 420, 421, + 422, 423, 424, 425, 507, 427, 428, 429, 0, 430, + 431, 0, 432, 0, 434, 435, 436, 437, 438, 0, + 439, 440, 0, 0, 441, 442, 443, 444, 445, 0, + 446, 447, 448, 449, 450, 451, 452, 453, 0, 0, + 454, 455, 456, 457, 458, 459, 0, 0, 461, 462, + 463, 464, 465, 466, 467, 0, 468, 0, 470, 471, + 472, 473, 474, 0, 0, 475, 0, 0, 476, 477, + 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, + 488, 489, 490, 491, 492, 493, 494, 495, 496, 504, + 0, 530, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 964, 0, 105, 106, 107, + 108, 109, 110, 111, 112, 0, 113, 114, 115, 0, + 0, 0, 0, 0, 0, 0, 116, 117, 0, 118, + 119, 120, 0, 122, 123, 124, 125, 126, 0, 128, + 129, 0, 130, 131, 132, 133, 134, 135, 0, 0, + 136, 137, 138, 139, 140, 0, 141, 142, 143, 144, + 145, 0, 0, 0, 147, 148, 149, 150, 151, 152, + 0, 154, 155, 156, 0, 157, 158, 159, 160, 161, + 162, 0, 0, 164, 165, 166, 0, 0, 0, 0, + 0, 0, 0, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 0, 182, 0, 183, 184, 185, 186, + 187, 188, 0, 189, 190, 191, 192, 193, 0, 0, + 194, 195, 196, 197, 198, 0, 199, 200, 201, 0, + 202, 203, 204, 0, 205, 206, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 0, 216, 0, 217, 218, + 219, 220, 0, 221, 0, 222, 0, 0, 0, 225, + 226, 505, 0, 229, 0, 230, 0, 231, 232, 233, + 0, 234, 235, 236, 237, 238, 239, 240, 0, 242, + 243, 244, 245, 0, 246, 247, 248, 249, 250, 251, + 0, 252, 0, 254, 255, 256, 257, 258, 259, 260, + 261, 0, 262, 0, 263, 0, 0, 266, 0, 268, + 269, 270, 271, 272, 273, 0, 0, 274, 0, 276, + 0, 0, 278, 279, 280, 0, 0, 281, 282, 283, + 284, 285, 506, 287, 288, 289, 290, 291, 292, 293, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, 0, 307, 308, 309, 310, 311, 0, 312, + 313, 0, 315, 0, 316, 317, 318, 319, 320, 321, + 0, 322, 323, 0, 0, 324, 325, 326, 0, 0, + 327, 328, 0, 330, 0, 332, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 0, 343, 344, 345, + 0, 347, 348, 349, 350, 351, 352, 0, 353, 354, + 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, + 364, 365, 366, 0, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378, 379, 0, 380, 381, + 0, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, 0, 398, 399, 400, + 401, 402, 0, 404, 405, 406, 407, 408, 0, 410, + 411, 412, 413, 0, 414, 415, 416, 417, 418, 419, + 420, 421, 422, 423, 424, 425, 507, 427, 428, 429, + 0, 430, 431, 0, 432, 0, 434, 435, 436, 437, + 438, 0, 439, 440, 0, 0, 441, 442, 443, 444, + 445, 0, 446, 447, 448, 449, 450, 451, 452, 453, + 0, 0, 454, 455, 456, 457, 458, 459, 0, 0, + 461, 462, 463, 464, 465, 466, 467, 0, 468, 0, + 470, 471, 472, 473, 474, 0, 0, 475, 0, 0, + 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, + 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, + 496, 504, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1514, 0, 105, + 106, 107, 108, 109, 110, 111, 112, 0, 113, 114, + 115, 0, 0, 0, 0, 0, 0, 0, 116, 117, + 0, 118, 119, 120, 0, 122, 123, 124, 125, 126, + 0, 128, 129, 0, 130, 131, 132, 133, 134, 135, + 0, 0, 136, 137, 138, 139, 140, 0, 141, 142, + 143, 144, 145, 0, 0, 0, 147, 148, 149, 150, + 151, 152, 0, 154, 155, 156, 0, 157, 158, 159, + 160, 161, 162, 0, 0, 164, 165, 166, 0, 0, + 0, 0, 0, 0, 0, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 0, 182, 0, 183, 184, + 185, 186, 187, 188, 0, 189, 190, 191, 192, 193, + 0, 0, 194, 195, 196, 197, 198, 0, 199, 200, + 201, 0, 202, 203, 204, 0, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 0, 216, 0, + 217, 218, 219, 220, 0, 221, 0, 222, 0, 0, + 0, 225, 226, 505, 0, 229, 0, 230, 0, 231, + 232, 233, 0, 234, 235, 236, 237, 238, 239, 240, + 0, 242, 243, 244, 245, 0, 246, 247, 248, 249, + 250, 251, 0, 252, 0, 254, 255, 256, 257, 258, + 259, 260, 261, 0, 262, 0, 263, 0, 0, 266, + 0, 268, 269, 270, 271, 272, 273, 0, 0, 274, + 0, 276, 0, 0, 278, 279, 280, 0, 0, 281, + 282, 283, 284, 285, 506, 287, 288, 289, 290, 291, + 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, 0, 307, 308, 309, 310, 311, + 0, 312, 313, 0, 315, 0, 316, 317, 318, 319, + 320, 321, 0, 322, 323, 0, 0, 324, 325, 326, + 0, 0, 327, 328, 0, 330, 0, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 0, 343, + 344, 345, 0, 347, 348, 349, 350, 351, 352, 0, + 353, 354, 355, 356, 357, 358, 0, 359, 360, 361, + 362, 363, 364, 365, 366, 0, 367, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378, 379, 0, + 380, 381, 0, 383, 384, 385, 386, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, 0, 398, + 399, 400, 401, 402, 0, 404, 405, 406, 407, 408, + 0, 410, 411, 412, 413, 0, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 425, 507, 427, + 428, 429, 0, 430, 431, 0, 432, 0, 434, 435, + 436, 437, 438, 0, 439, 440, 0, 0, 441, 442, + 443, 444, 445, 0, 446, 447, 448, 449, 450, 451, + 452, 453, 0, 0, 454, 455, 456, 457, 458, 459, + 0, 0, 461, 462, 463, 464, 465, 466, 467, 0, + 468, 0, 470, 471, 472, 473, 474, 0, 0, 475, + 0, 0, 476, 477, 478, 479, 480, 481, 482, 483, + 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, + 494, 495, 496, 504, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1977, + 0, 105, 106, 107, 108, 109, 110, 111, 112, 0, + 113, 114, 115, 0, 0, 0, 0, 0, 0, 0, + 116, 117, 0, 118, 119, 120, 0, 122, 123, 124, + 125, 126, 0, 128, 129, 0, 130, 131, 132, 133, + 134, 135, 0, 0, 136, 137, 138, 139, 140, 0, + 141, 142, 143, 144, 145, 0, 0, 0, 147, 148, + 149, 150, 151, 152, 0, 154, 155, 156, 0, 157, + 158, 159, 160, 161, 162, 0, 0, 164, 165, 166, + 0, 0, 0, 0, 0, 0, 0, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 0, 182, 0, + 183, 184, 185, 186, 187, 188, 0, 189, 190, 191, + 192, 193, 0, 0, 194, 195, 196, 197, 198, 0, + 199, 200, 201, 0, 202, 203, 204, 0, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 0, + 216, 0, 217, 218, 219, 220, 0, 221, 0, 222, + 0, 0, 0, 225, 226, 505, 0, 229, 0, 230, + 0, 231, 232, 233, 0, 234, 235, 236, 237, 238, + 239, 240, 0, 242, 243, 244, 245, 0, 246, 247, + 248, 249, 250, 251, 0, 252, 0, 254, 255, 256, + 257, 258, 259, 260, 261, 0, 262, 0, 263, 0, + 0, 266, 0, 268, 269, 270, 271, 272, 273, 0, + 0, 274, 0, 276, 0, 0, 278, 279, 280, 0, + 0, 281, 282, 283, 284, 285, 506, 287, 288, 289, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 0, 307, 308, 309, + 310, 311, 0, 312, 313, 0, 315, 0, 316, 317, + 318, 319, 320, 321, 0, 322, 323, 0, 0, 324, + 325, 326, 0, 0, 327, 328, 0, 330, 0, 332, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 0, 343, 344, 345, 0, 347, 348, 349, 350, 351, + 352, 0, 353, 354, 355, 356, 357, 358, 0, 359, + 360, 361, 362, 363, 364, 365, 366, 0, 367, 368, + 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, + 379, 0, 380, 381, 0, 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + 0, 398, 399, 400, 401, 402, 0, 404, 405, 406, + 407, 408, 0, 410, 411, 412, 413, 0, 414, 415, + 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, + 507, 427, 428, 429, 0, 430, 431, 0, 432, 0, + 434, 435, 436, 437, 438, 0, 439, 440, 0, 0, + 441, 442, 443, 444, 445, 0, 446, 447, 448, 449, + 450, 451, 452, 453, 0, 0, 454, 455, 456, 457, + 458, 459, 0, 0, 461, 462, 463, 464, 465, 466, + 467, 0, 468, 0, 470, 471, 472, 473, 474, 0, + 0, 475, 0, 0, 476, 477, 478, 479, 480, 481, + 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, + 492, 493, 494, 495, 496, 504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 38, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 583, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 584, 0, - 585, 0, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 154, 155, 156, 157, 586, 587, 588, 589, 590, 591, - 592, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 593, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 214, 0, 215, 216, 217, 218, - 219, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 244, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 266, 267, 268, 0, - 269, 270, 271, 595, 596, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 0, 303, 304, 305, - 306, 0, 597, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 320, 321, 322, 599, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 600, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 602, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 416, 417, 603, 419, 0, 420, 421, - 0, 422, 423, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 604, 434, 605, 0, 436, - 437, 606, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 607, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 458, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 0, + 0, 2073, 0, 105, 106, 107, 108, 109, 110, 111, + 112, 0, 113, 114, 115, 0, 0, 0, 0, 0, + 0, 0, 116, 117, 0, 118, 119, 120, 0, 122, + 123, 124, 125, 126, 0, 128, 129, 0, 130, 131, + 132, 133, 134, 135, 0, 0, 136, 137, 138, 139, + 140, 0, 141, 142, 143, 144, 145, 0, 0, 0, + 147, 148, 149, 150, 151, 152, 0, 154, 155, 156, + 0, 157, 158, 159, 160, 161, 162, 0, 0, 164, + 165, 166, 0, 0, 0, 0, 0, 0, 0, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 0, + 182, 0, 183, 184, 185, 186, 187, 188, 0, 189, + 190, 191, 192, 193, 0, 0, 194, 195, 196, 197, + 198, 0, 199, 200, 201, 0, 202, 203, 204, 0, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 0, 216, 0, 217, 218, 219, 220, 0, 221, + 0, 222, 0, 0, 0, 225, 226, 505, 0, 229, + 0, 230, 0, 231, 232, 233, 0, 234, 235, 236, + 237, 238, 239, 240, 0, 242, 243, 244, 245, 0, + 246, 247, 248, 249, 250, 251, 0, 252, 0, 254, + 255, 256, 257, 258, 259, 260, 261, 0, 262, 0, + 263, 0, 0, 266, 0, 268, 269, 270, 271, 272, + 273, 0, 0, 274, 0, 276, 0, 0, 278, 279, + 280, 0, 0, 281, 282, 283, 284, 285, 506, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, 0, 307, + 308, 309, 310, 311, 0, 312, 313, 0, 315, 0, + 316, 317, 318, 319, 320, 321, 0, 322, 323, 0, + 0, 324, 325, 326, 0, 0, 327, 328, 0, 330, + 0, 332, 333, 334, 335, 336, 337, 338, 339, 340, + 341, 342, 0, 343, 344, 345, 0, 347, 348, 349, + 350, 351, 352, 0, 353, 354, 355, 356, 357, 358, + 0, 359, 360, 361, 362, 363, 364, 365, 366, 0, + 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, + 377, 378, 379, 0, 380, 381, 0, 383, 384, 385, + 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 0, 398, 399, 400, 401, 402, 0, 404, + 405, 406, 407, 408, 0, 410, 411, 412, 413, 0, + 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, + 424, 425, 507, 427, 428, 429, 0, 430, 431, 0, + 432, 0, 434, 435, 436, 437, 438, 0, 439, 440, + 0, 0, 441, 442, 443, 444, 445, 0, 446, 447, + 448, 449, 450, 451, 452, 453, 0, 0, 454, 455, + 456, 457, 458, 459, 0, 0, 461, 462, 463, 464, + 465, 466, 467, 0, 468, 0, 470, 471, 472, 473, + 474, 0, 0, 475, 0, 0, 476, 477, 478, 479, + 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, + 490, 491, 492, 493, 494, 495, 496, 0, 0, 2725, + 1427, 515, 0, 0, 1958, 1016, 0, 0, 0, 0, + 0, 1959, 0, 2883, 1960, 1961, 1962, 105, 106, 107, + 108, 109, 110, 111, 112, 1245, 113, 114, 115, 1246, + 1247, 1248, 1249, 1250, 1251, 1252, 116, 117, 1253, 118, + 119, 120, 2726, 122, 123, 124, 0, 768, 2727, 770, + 771, 1254, 130, 131, 132, 133, 134, 135, 1255, 1256, + 136, 137, 772, 773, 140, 1257, 141, 142, 143, 144, + 0, 1258, 2728, 1259, 2729, 148, 149, 150, 151, 152, + 2730, 154, 155, 156, 1260, 157, 158, 159, 160, 161, + 162, 1261, 2731, 164, 165, 166, 2732, 2733, 2734, 2735, + 1262, 1263, 2736, 172, 173, 174, 175, 176, 177, 178, + 783, 784, 181, 1264, 182, 1265, 183, 184, 185, 186, + 187, 188, 1266, 189, 190, 191, 192, 193, 1267, 1268, + 194, 195, 785, 197, 198, 1269, 199, 200, 201, 1270, + 202, 203, 204, 1271, 205, 206, 207, 208, 0, 210, + 211, 212, 213, 214, 0, 1272, 216, 1273, 217, 218, + 786, 220, 1274, 221, 1275, 222, 2737, 1276, 2738, 225, + 226, 2739, 2740, 229, 1277, 230, 1278, 0, 0, 233, + 1279, 234, 235, 236, 237, 238, 239, 240, 2741, 242, + 243, 244, 245, 1280, 246, 247, 248, 249, 250, 251, + 1281, 252, 2742, 0, 255, 256, 257, 258, 259, 793, + 794, 1282, 795, 1283, 263, 2743, 2744, 266, 2745, 268, + 269, 270, 271, 272, 273, 1284, 1285, 274, 2746, 276, + 2747, 1286, 278, 279, 280, 1287, 1288, 281, 282, 283, + 284, 285, 2748, 287, 288, 289, 290, 291, 292, 293, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 802, 2749, 804, 308, 309, 310, 2750, 1289, 312, + 313, 2751, 315, 1290, 0, 317, 806, 319, 320, 321, + 1291, 322, 323, 1292, 1293, 2752, 325, 326, 1294, 1295, + 327, 0, 2753, 330, 2754, 0, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 1296, 343, 344, 0, + 2755, 347, 348, 0, 350, 351, 352, 1297, 353, 354, + 355, 356, 357, 358, 1298, 359, 360, 361, 810, 363, + 364, 365, 366, 1299, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378, 379, 1300, 380, 381, + 2756, 383, 384, 385, 812, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, 1301, 398, 399, 400, + 401, 402, 2757, 404, 2758, 406, 407, 408, 2759, 410, + 411, 816, 413, 1302, 414, 415, 416, 417, 418, 419, + 420, 421, 422, 423, 424, 425, 2760, 427, 0, 429, + 1303, 430, 431, 1304, 432, 2761, 434, 435, 436, 437, + 438, 1305, 819, 820, 1306, 1307, 441, 442, 0, 444, + 0, 1308, 446, 447, 2762, 449, 450, 451, 452, 453, + 2763, 1310, 454, 455, 456, 457, 458, 459, 2764, 1311, + 461, 462, 463, 464, 465, 0, 824, 1313, 468, 2765, + 470, 471, 472, 473, 474, 1314, 1315, 475, 1316, 1317, + 476, 477, 478, 479, 480, 481, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 493, 494, 495, + 496, 0, 504, 0, 1963, 1964, 1965, 1958, 2766, 2767, + 1968, 1969, 1970, 1971, 1959, 0, 0, 1960, 1961, 1962, + 105, 106, 107, 108, 109, 110, 111, 112, 0, 113, + 114, 115, 0, 0, 0, 0, 0, 0, 0, 116, + 117, 0, 118, 119, 120, 0, 122, 123, 124, 125, + 126, 0, 128, 129, 0, 130, 131, 132, 133, 134, + 135, 0, 0, 136, 137, 138, 139, 140, 0, 141, + 142, 143, 144, 145, 0, 0, 0, 147, 148, 149, + 150, 151, 152, 0, 154, 155, 156, 0, 157, 158, + 159, 160, 161, 162, 0, 0, 164, 165, 166, 0, + 0, 0, 0, 0, 0, 0, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 0, 182, 0, 183, + 184, 185, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 0, 0, 194, 195, 196, 197, 198, 0, 199, + 200, 201, 0, 202, 203, 204, 0, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 0, 216, + 0, 217, 218, 219, 220, 0, 221, 0, 222, 0, + 0, 0, 225, 226, 505, 0, 229, 0, 230, 0, + 231, 232, 233, 0, 234, 235, 236, 237, 238, 239, + 240, 0, 242, 243, 244, 245, 0, 246, 247, 248, + 249, 250, 251, 0, 252, 0, 254, 255, 256, 257, + 258, 259, 260, 261, 0, 262, 0, 263, 0, 0, + 266, 0, 268, 269, 270, 271, 272, 273, 0, 0, + 274, 0, 276, 0, 0, 278, 279, 280, 0, 0, + 281, 282, 283, 284, 285, 506, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, 0, 307, 308, 309, 310, + 311, 0, 312, 313, 0, 315, 0, 316, 317, 318, + 319, 320, 321, 0, 322, 323, 0, 0, 324, 325, + 326, 0, 0, 327, 328, 0, 330, 0, 332, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 0, + 343, 344, 345, 0, 347, 348, 349, 350, 351, 352, + 0, 353, 354, 355, 356, 357, 358, 0, 359, 360, + 361, 362, 363, 364, 365, 366, 0, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 0, 380, 381, 0, 383, 384, 385, 386, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 0, + 398, 399, 400, 401, 402, 0, 404, 405, 406, 407, + 408, 0, 410, 411, 412, 413, 0, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 507, + 427, 428, 429, 0, 430, 431, 0, 432, 0, 434, + 435, 436, 437, 438, 0, 439, 440, 0, 0, 441, + 442, 443, 444, 445, 0, 446, 447, 448, 449, 450, + 451, 452, 453, 0, 0, 454, 455, 456, 457, 458, + 459, 0, 0, 461, 462, 463, 464, 465, 466, 467, + 0, 468, 0, 470, 471, 472, 473, 474, 0, 0, + 475, 0, 0, 476, 477, 478, 479, 480, 481, 482, + 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, + 493, 494, 495, 496, 0, 0, 0, 1963, 1964, 1965, + 0, 1966, 1967, 1968, 1969, 1970, 1971, 1565, 0, 0, + 1566, 0, 0, 0, 1567, 1568, 1569, 1570, 1571, 1572, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 2947, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 688, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 19, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 27, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 32, 422, 0, 424, 425, 426, 427, 428, 0, 689, - 430, 0, 0, 690, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 608, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 36, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 37, + 0, 0, 0, 0, 1573, 0, 1565, 0, 0, 1566, + 0, 0, 1575, 1567, 1568, 1569, 1570, 1571, 1572, 1576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 38, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 19, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 27, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 32, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 608, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 36, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 0, 508, 37, - 509, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 38, 0, 0, 96, 97, 98, 99, - 100, 101, 102, 103, 0, 104, 105, 106, 0, 0, - 0, 0, 0, 0, 0, 107, 108, 0, 109, 110, - 111, 0, 113, 114, 115, 116, 117, 0, 119, 120, - 0, 121, 122, 123, 124, 125, 126, 0, 0, 127, - 128, 129, 130, 131, 0, 132, 133, 134, 135, 136, - 0, 0, 0, 138, 139, 140, 141, 142, 143, 0, - 145, 146, 147, 0, 148, 149, 150, 151, 152, 153, - 0, 0, 155, 156, 157, 0, 0, 0, 0, 0, - 0, 0, 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 0, 173, 0, 174, 175, 176, 177, 178, - 179, 0, 180, 181, 182, 183, 184, 0, 0, 185, - 186, 187, 188, 189, 0, 190, 191, 192, 0, 193, - 194, 195, 0, 196, 197, 198, 199, 200, 201, 202, - 203, 204, 205, 206, 0, 207, 0, 208, 209, 210, - 211, 0, 212, 0, 213, 0, 0, 0, 216, 217, - 511, 0, 220, 0, 221, 0, 222, 223, 224, 0, - 225, 226, 227, 228, 229, 230, 231, 0, 233, 234, - 235, 236, 0, 237, 238, 239, 240, 241, 242, 0, - 243, 0, 245, 246, 247, 248, 249, 250, 251, 252, - 0, 253, 0, 254, 0, 0, 257, 0, 259, 260, - 261, 262, 263, 264, 0, 0, 265, 0, 267, 0, - 0, 269, 270, 271, 0, 0, 272, 273, 274, 275, - 276, 512, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 296, 0, 298, 299, 300, 301, 302, 0, 303, 304, - 0, 306, 0, 307, 308, 309, 310, 311, 312, 0, - 313, 314, 0, 0, 315, 316, 317, 0, 0, 318, - 319, 0, 321, 0, 323, 324, 325, 326, 327, 328, - 329, 330, 331, 332, 333, 0, 334, 335, 336, 337, - 338, 339, 340, 341, 342, 0, 343, 344, 345, 346, - 347, 348, 0, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 0, 370, 371, 0, 373, - 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, - 384, 385, 386, 387, 0, 388, 389, 390, 391, 392, - 0, 394, 395, 396, 397, 398, 0, 400, 401, 402, - 403, 0, 404, 405, 406, 407, 408, 409, 410, 411, - 412, 413, 414, 415, 514, 417, 418, 419, 0, 420, - 421, 0, 422, 0, 424, 425, 426, 427, 428, 0, - 429, 430, 0, 0, 431, 432, 433, 434, 435, 0, - 436, 437, 438, 439, 440, 441, 442, 443, 0, 0, - 444, 445, 446, 447, 448, 0, 0, 450, 451, 452, - 453, 454, 455, 456, 0, 457, 0, 459, 460, 461, - 462, 463, 0, 0, 464, 0, 0, 465, 466, 467, - 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, - 478, 479, 480, 481, 482, 483, 484, 485, 508, 0, - 509, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 929, 0, 96, 97, 98, 99, - 100, 101, 102, 103, 0, 104, 105, 106, 0, 0, - 0, 0, 0, 0, 0, 107, 108, 0, 109, 110, - 111, 0, 113, 114, 115, 116, 117, 0, 119, 120, - 0, 121, 122, 123, 124, 125, 126, 0, 0, 127, - 128, 129, 130, 131, 0, 132, 133, 134, 135, 136, - 0, 0, 0, 138, 139, 140, 141, 142, 143, 0, - 145, 146, 147, 0, 148, 149, 150, 151, 152, 153, - 0, 0, 155, 156, 157, 0, 0, 0, 0, 0, - 0, 0, 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 0, 173, 0, 174, 175, 176, 177, 178, - 179, 0, 180, 181, 182, 183, 184, 0, 0, 185, - 186, 187, 188, 189, 0, 190, 191, 192, 0, 193, - 194, 195, 0, 196, 197, 198, 199, 200, 201, 202, - 203, 204, 205, 206, 0, 207, 0, 208, 209, 210, - 211, 0, 212, 0, 213, 0, 0, 0, 216, 217, - 511, 0, 220, 0, 221, 0, 222, 223, 224, 0, - 225, 226, 227, 228, 229, 230, 231, 0, 233, 234, - 235, 236, 0, 237, 238, 239, 240, 241, 242, 0, - 243, 0, 245, 246, 247, 248, 249, 250, 251, 252, - 0, 253, 0, 254, 0, 0, 257, 0, 259, 260, - 261, 262, 263, 264, 0, 0, 265, 0, 267, 0, - 0, 269, 270, 271, 0, 0, 272, 273, 274, 275, - 276, 512, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 296, 0, 298, 299, 300, 301, 302, 0, 303, 304, - 0, 306, 0, 307, 308, 309, 310, 311, 312, 0, - 313, 314, 0, 0, 315, 316, 317, 0, 0, 318, - 319, 0, 321, 0, 323, 324, 325, 326, 327, 328, - 329, 330, 331, 332, 333, 0, 334, 335, 336, 337, - 338, 339, 340, 341, 342, 0, 343, 344, 345, 346, - 347, 348, 0, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 0, 370, 371, 0, 373, - 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, - 384, 385, 386, 387, 0, 388, 389, 390, 391, 392, - 0, 394, 395, 396, 397, 398, 0, 400, 401, 402, - 403, 0, 404, 405, 406, 407, 408, 409, 410, 411, - 412, 413, 414, 415, 514, 417, 418, 419, 0, 420, - 421, 0, 422, 0, 424, 425, 426, 427, 428, 0, - 429, 430, 0, 0, 431, 432, 433, 434, 435, 0, - 436, 437, 438, 439, 440, 441, 442, 443, 0, 0, - 444, 445, 446, 447, 448, 0, 0, 450, 451, 452, - 453, 454, 455, 456, 0, 457, 0, 459, 460, 461, - 462, 463, 0, 0, 464, 0, 0, 465, 466, 467, - 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, - 478, 479, 480, 481, 482, 483, 484, 485, 508, 0, + 0, 0, 0, 1573, 0, 0, 0, 0, 0, 0, + 0, 1575, 1565, 0, 1577, 1566, 0, 0, 1576, 1567, + 1568, 1569, 1570, 1571, 1572, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1573, + 0, 1565, 0, 1577, 1566, 0, 0, 1575, 1567, 1568, + 1569, 1570, 1571, 1572, 1576, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1573, 0, + 0, 0, 0, 0, 0, 0, 1575, 0, 0, 1577, + 0, 0, 0, 1576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1462, 0, 96, 97, 98, 99, - 100, 101, 102, 103, 0, 104, 105, 106, 0, 0, - 0, 0, 0, 0, 0, 107, 108, 0, 109, 110, - 111, 0, 113, 114, 115, 116, 117, 0, 119, 120, - 0, 121, 122, 123, 124, 125, 126, 0, 0, 127, - 128, 129, 130, 131, 0, 132, 133, 134, 135, 136, - 0, 0, 0, 138, 139, 140, 141, 142, 143, 0, - 145, 146, 147, 0, 148, 149, 150, 151, 152, 153, - 0, 0, 155, 156, 157, 0, 0, 0, 0, 0, - 0, 0, 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 0, 173, 0, 174, 175, 176, 177, 178, - 179, 0, 180, 181, 182, 183, 184, 0, 0, 185, - 186, 187, 188, 189, 0, 190, 191, 192, 0, 193, - 194, 195, 0, 196, 197, 198, 199, 200, 201, 202, - 203, 204, 205, 206, 0, 207, 0, 208, 209, 210, - 211, 0, 212, 0, 213, 0, 0, 0, 216, 217, - 511, 0, 220, 0, 221, 0, 222, 223, 224, 0, - 225, 226, 227, 228, 229, 230, 231, 0, 233, 234, - 235, 236, 0, 237, 238, 239, 240, 241, 242, 0, - 243, 0, 245, 246, 247, 248, 249, 250, 251, 252, - 0, 253, 0, 254, 0, 0, 257, 0, 259, 260, - 261, 262, 263, 264, 0, 0, 265, 0, 267, 0, - 0, 269, 270, 271, 0, 0, 272, 273, 274, 275, - 276, 512, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 296, 0, 298, 299, 300, 301, 302, 0, 303, 304, - 0, 306, 0, 307, 308, 309, 310, 311, 312, 0, - 313, 314, 0, 0, 315, 316, 317, 0, 0, 318, - 319, 0, 321, 0, 323, 324, 325, 326, 327, 328, - 329, 330, 331, 332, 333, 0, 334, 335, 336, 337, - 338, 339, 340, 341, 342, 0, 343, 344, 345, 346, - 347, 348, 0, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 0, 370, 371, 0, 373, - 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, - 384, 385, 386, 387, 0, 388, 389, 390, 391, 392, - 0, 394, 395, 396, 397, 398, 0, 400, 401, 402, - 403, 0, 404, 405, 406, 407, 408, 409, 410, 411, - 412, 413, 414, 415, 514, 417, 418, 419, 0, 420, - 421, 0, 422, 0, 424, 425, 426, 427, 428, 0, - 429, 430, 0, 0, 431, 432, 433, 434, 435, 0, - 436, 437, 438, 439, 440, 441, 442, 443, 0, 0, - 444, 445, 446, 447, 448, 0, 0, 450, 451, 452, - 453, 454, 455, 456, 0, 457, 0, 459, 460, 461, - 462, 463, 0, 0, 464, 0, 0, 465, 466, 467, - 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, - 478, 479, 480, 481, 482, 483, 484, 485, 508, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1577, 0, + 0, 0, 0, 0, 0, 1578, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1915, 0, 96, 97, 98, 99, - 100, 101, 102, 103, 0, 104, 105, 106, 0, 0, - 0, 0, 0, 0, 0, 107, 108, 0, 109, 110, - 111, 0, 113, 114, 115, 116, 117, 0, 119, 120, - 0, 121, 122, 123, 124, 125, 126, 0, 0, 127, - 128, 129, 130, 131, 0, 132, 133, 134, 135, 136, - 0, 0, 0, 138, 139, 140, 141, 142, 143, 0, - 145, 146, 147, 0, 148, 149, 150, 151, 152, 153, - 0, 0, 155, 156, 157, 0, 0, 0, 0, 0, - 0, 0, 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 0, 173, 0, 174, 175, 176, 177, 178, - 179, 0, 180, 181, 182, 183, 184, 0, 0, 185, - 186, 187, 188, 189, 0, 190, 191, 192, 0, 193, - 194, 195, 0, 196, 197, 198, 199, 200, 201, 202, - 203, 204, 205, 206, 0, 207, 0, 208, 209, 210, - 211, 0, 212, 0, 213, 0, 0, 0, 216, 217, - 511, 0, 220, 0, 221, 0, 222, 223, 224, 0, - 225, 226, 227, 228, 229, 230, 231, 0, 233, 234, - 235, 236, 0, 237, 238, 239, 240, 241, 242, 0, - 243, 0, 245, 246, 247, 248, 249, 250, 251, 252, - 0, 253, 0, 254, 0, 0, 257, 0, 259, 260, - 261, 262, 263, 264, 0, 0, 265, 0, 267, 0, - 0, 269, 270, 271, 0, 0, 272, 273, 274, 275, - 276, 512, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 296, 0, 298, 299, 300, 301, 302, 0, 303, 304, - 0, 306, 0, 307, 308, 309, 310, 311, 312, 0, - 313, 314, 0, 0, 315, 316, 317, 0, 0, 318, - 319, 0, 321, 0, 323, 324, 325, 326, 327, 328, - 329, 330, 331, 332, 333, 0, 334, 335, 336, 337, - 338, 339, 340, 341, 342, 0, 343, 344, 345, 346, - 347, 348, 0, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 0, 370, 371, 0, 373, - 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, - 384, 385, 386, 387, 0, 388, 389, 390, 391, 392, - 0, 394, 395, 396, 397, 398, 0, 400, 401, 402, - 403, 0, 404, 405, 406, 407, 408, 409, 410, 411, - 412, 413, 414, 415, 514, 417, 418, 419, 0, 420, - 421, 0, 422, 0, 424, 425, 426, 427, 428, 0, - 429, 430, 0, 0, 431, 432, 433, 434, 435, 0, - 436, 437, 438, 439, 440, 441, 442, 443, 0, 0, - 444, 445, 446, 447, 448, 0, 0, 450, 451, 452, - 453, 454, 455, 456, 0, 457, 0, 459, 460, 461, - 462, 463, 0, 0, 464, 0, 0, 465, 466, 467, - 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, - 478, 479, 480, 481, 482, 483, 484, 485, 508, 0, + 0, 1579, 0, 0, 0, 0, 1580, 0, 0, 0, + 0, 0, 0, 0, 1578, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1581, 1582, + 1579, 0, 0, 0, 0, 1580, 0, 0, 0, 0, + 0, 0, 0, 1583, 0, 0, 0, 0, 0, 0, + 1578, 0, 0, 0, 0, 0, 0, 1581, 1582, 0, + 0, 0, 0, 0, 0, 0, 1579, 0, 0, 0, + 0, 1580, 1583, 0, 0, 0, 0, 0, 0, 1578, + 0, 1584, 0, 0, 1585, 0, 0, 0, 0, 0, + 0, 0, 0, 1581, 1582, 1579, 0, 0, 1586, 0, + 1580, 1587, 0, 0, 0, 0, 0, 0, 1583, 0, + 1584, 0, 0, 1585, 0, 0, 0, 0, 0, 0, + 0, 0, 1581, 1582, 0, 0, 0, 1586, 0, 0, + 1587, 0, 0, 0, 0, 0, 0, 1583, 0, 0, + 0, 0, 0, 0, 0, 0, 1584, 0, 0, 1585, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 2014, 0, 96, 97, 98, 99, - 100, 101, 102, 103, 0, 104, 105, 106, 0, 0, - 0, 0, 0, 0, 0, 107, 108, 0, 109, 110, - 111, 0, 113, 114, 115, 116, 117, 0, 119, 120, - 0, 121, 122, 123, 124, 125, 126, 0, 0, 127, - 128, 129, 130, 131, 0, 132, 133, 134, 135, 136, - 0, 0, 0, 138, 139, 140, 141, 142, 143, 0, - 145, 146, 147, 0, 148, 149, 150, 151, 152, 153, - 0, 0, 155, 156, 157, 0, 0, 0, 0, 0, - 0, 0, 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 0, 173, 0, 174, 175, 176, 177, 178, - 179, 0, 180, 181, 182, 183, 184, 0, 0, 185, - 186, 187, 188, 189, 0, 190, 191, 192, 0, 193, - 194, 195, 0, 196, 197, 198, 199, 200, 201, 202, - 203, 204, 205, 206, 0, 207, 0, 208, 209, 210, - 211, 0, 212, 0, 213, 0, 0, 0, 216, 217, - 511, 0, 220, 0, 221, 0, 222, 223, 224, 0, - 225, 226, 227, 228, 229, 230, 231, 0, 233, 234, - 235, 236, 0, 237, 238, 239, 240, 241, 242, 0, - 243, 0, 245, 246, 247, 248, 249, 250, 251, 252, - 0, 253, 0, 254, 0, 0, 257, 0, 259, 260, - 261, 262, 263, 264, 0, 0, 265, 0, 267, 0, - 0, 269, 270, 271, 0, 0, 272, 273, 274, 275, - 276, 512, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 296, 0, 298, 299, 300, 301, 302, 0, 303, 304, - 0, 306, 0, 307, 308, 309, 310, 311, 312, 0, - 313, 314, 0, 0, 315, 316, 317, 0, 0, 318, - 319, 0, 321, 0, 323, 324, 325, 326, 327, 328, - 329, 330, 331, 332, 333, 0, 334, 335, 336, 337, - 338, 339, 340, 341, 342, 0, 343, 344, 345, 346, - 347, 348, 0, 349, 350, 351, 352, 353, 354, 355, - 356, 0, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 0, 370, 371, 0, 373, - 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, - 384, 385, 386, 387, 0, 388, 389, 390, 391, 392, - 0, 394, 395, 396, 397, 398, 0, 400, 401, 402, - 403, 0, 404, 405, 406, 407, 408, 409, 410, 411, - 412, 413, 414, 415, 514, 417, 418, 419, 0, 420, - 421, 0, 422, 0, 424, 425, 426, 427, 428, 0, - 429, 430, 0, 0, 431, 432, 433, 434, 435, 0, - 436, 437, 438, 439, 440, 441, 442, 443, 0, 0, - 444, 445, 446, 447, 448, 0, 0, 450, 451, 452, - 453, 454, 455, 456, 0, 457, 0, 459, 460, 461, - 462, 463, 0, 0, 464, 0, 0, 465, 466, 467, - 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, - 478, 479, 480, 481, 482, 483, 484, 485, 0, 0, - 2657, 1377, 624, 0, 0, 1896, 980, 0, 0, 0, - 0, 0, 1897, 0, 2812, 1898, 1899, 1900, 96, 97, - 98, 99, 100, 101, 102, 103, 1203, 104, 105, 106, - 1204, 1205, 1206, 1207, 1208, 1209, 1210, 107, 108, 1211, - 109, 110, 111, 2658, 113, 114, 115, 0, 737, 2659, - 739, 740, 1212, 121, 122, 123, 124, 125, 126, 1213, - 1214, 127, 128, 741, 742, 131, 1215, 132, 133, 134, - 135, 0, 1216, 2660, 1217, 2661, 139, 140, 141, 142, - 143, 2662, 145, 146, 147, 1218, 148, 149, 150, 151, - 152, 153, 1219, 2663, 155, 156, 157, 2664, 2665, 2666, - 2667, 1220, 1221, 2668, 163, 164, 165, 166, 167, 168, - 169, 752, 753, 172, 1222, 173, 1223, 174, 175, 176, - 177, 178, 179, 1224, 180, 181, 182, 183, 184, 1225, - 1226, 185, 186, 754, 188, 189, 1227, 190, 191, 192, - 1228, 193, 194, 195, 1229, 196, 197, 198, 199, 0, - 201, 202, 203, 204, 205, 0, 1230, 207, 1231, 208, - 209, 755, 211, 1232, 212, 1233, 213, 2669, 1234, 2670, - 216, 217, 2671, 2672, 220, 1235, 221, 1236, 0, 0, - 224, 1237, 225, 226, 227, 228, 229, 230, 231, 2673, - 233, 234, 235, 236, 1238, 237, 238, 239, 240, 241, - 242, 1239, 243, 2674, 0, 246, 247, 248, 249, 250, - 762, 763, 1240, 764, 1241, 254, 2675, 2676, 257, 2677, - 259, 260, 261, 262, 263, 264, 1242, 1243, 265, 2678, - 267, 2679, 1244, 269, 270, 271, 1245, 1246, 272, 273, - 274, 275, 276, 2680, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, - 294, 295, 771, 2681, 773, 299, 300, 301, 2682, 1247, - 303, 304, 2683, 306, 1248, 0, 308, 775, 310, 311, - 312, 1249, 313, 314, 1250, 1251, 2684, 316, 317, 1252, - 1253, 318, 0, 2685, 321, 2686, 0, 324, 325, 326, - 327, 328, 329, 330, 331, 332, 333, 1254, 334, 335, - 0, 337, 338, 0, 340, 341, 342, 1255, 343, 344, - 345, 346, 347, 348, 1256, 349, 350, 351, 778, 353, - 354, 355, 356, 1257, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, 369, 1258, 370, 371, - 2687, 373, 374, 375, 780, 377, 378, 379, 380, 381, - 382, 383, 384, 385, 386, 387, 1259, 388, 389, 390, - 391, 392, 2688, 394, 2689, 396, 397, 398, 2690, 400, - 401, 784, 403, 1260, 404, 405, 406, 407, 408, 409, - 410, 411, 412, 413, 414, 415, 2691, 417, 0, 419, - 1261, 420, 421, 1262, 422, 2692, 424, 425, 426, 427, - 428, 1263, 787, 788, 1264, 1265, 431, 432, 0, 434, - 0, 1266, 436, 437, 2693, 439, 440, 441, 442, 443, - 2694, 1268, 444, 445, 446, 447, 448, 2695, 1269, 450, - 451, 452, 453, 454, 0, 792, 1271, 457, 2696, 459, - 460, 461, 462, 463, 1272, 1273, 464, 1274, 1275, 465, - 466, 467, 468, 469, 470, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 482, 483, 484, 485, - 0, 508, 0, 1901, 1902, 1903, 1896, 2697, 2698, 1906, - 1907, 1908, 1909, 1897, 0, 0, 1898, 1899, 1900, 96, - 97, 98, 99, 100, 101, 102, 103, 0, 104, 105, - 106, 0, 0, 0, 0, 0, 0, 0, 107, 108, - 0, 109, 110, 111, 0, 113, 114, 115, 116, 117, - 0, 119, 120, 0, 121, 122, 123, 124, 125, 126, - 0, 0, 127, 128, 129, 130, 131, 0, 132, 133, - 134, 135, 136, 0, 0, 0, 138, 139, 140, 141, - 142, 143, 0, 145, 146, 147, 0, 148, 149, 150, - 151, 152, 153, 0, 0, 155, 156, 157, 0, 0, - 0, 0, 0, 0, 0, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 0, 173, 0, 174, 175, - 176, 177, 178, 179, 0, 180, 181, 182, 183, 184, - 0, 0, 185, 186, 187, 188, 189, 0, 190, 191, - 192, 0, 193, 194, 195, 0, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 0, 207, 0, - 208, 209, 210, 211, 0, 212, 0, 213, 0, 0, - 0, 216, 217, 511, 0, 220, 0, 221, 0, 222, - 223, 224, 0, 225, 226, 227, 228, 229, 230, 231, - 0, 233, 234, 235, 236, 0, 237, 238, 239, 240, - 241, 242, 0, 243, 0, 245, 246, 247, 248, 249, - 250, 251, 252, 0, 253, 0, 254, 0, 0, 257, - 0, 259, 260, 261, 262, 263, 264, 0, 0, 265, - 0, 267, 0, 0, 269, 270, 271, 0, 0, 272, - 273, 274, 275, 276, 512, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, - 293, 294, 295, 296, 0, 298, 299, 300, 301, 302, - 0, 303, 304, 0, 306, 0, 307, 308, 309, 310, - 311, 312, 0, 313, 314, 0, 0, 315, 316, 317, - 0, 0, 318, 319, 0, 321, 0, 323, 324, 325, - 326, 327, 328, 329, 330, 331, 332, 333, 0, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 0, 343, - 344, 345, 346, 347, 348, 0, 349, 350, 351, 352, - 353, 354, 355, 356, 0, 357, 358, 359, 360, 361, - 362, 363, 364, 365, 366, 367, 368, 369, 0, 370, - 371, 0, 373, 374, 375, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, 386, 387, 0, 388, 389, - 390, 391, 392, 0, 394, 395, 396, 397, 398, 0, - 400, 401, 402, 403, 0, 404, 405, 406, 407, 408, - 409, 410, 411, 412, 413, 414, 415, 514, 417, 418, - 419, 0, 420, 421, 0, 422, 0, 424, 425, 426, - 427, 428, 0, 429, 430, 0, 0, 431, 432, 433, - 434, 435, 0, 436, 437, 438, 439, 440, 441, 442, - 443, 0, 0, 444, 445, 446, 447, 448, 0, 0, - 450, 451, 452, 453, 454, 455, 456, 0, 457, 0, - 459, 460, 461, 462, 463, 0, 0, 464, 0, 0, - 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, - 485, 0, 0, 0, 1901, 1902, 1903, 0, 1904, 1905, - 1906, 1907, 1908, 1909, 1513, 0, 0, 1514, 0, 0, - 0, 1515, 1516, 1517, 1518, 1519, 1520, 0, 0, 0, + 0, 1565, 0, 1586, 1566, 0, 1587, 0, 1567, 1568, + 1569, 1570, 1571, 1572, 0, 1584, 0, 0, 1585, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1573, 0, + 1565, 1588, 1586, 1566, 0, 1587, 1575, 1567, 1568, 1569, + 1570, 1571, 1572, 1576, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1573, 0, 0, + 1588, 0, 0, 0, 0, 1575, 1565, 0, 1577, 1566, + 0, 0, 1576, 1567, 1568, 1569, 1570, 1571, 1572, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1521, 0, 1513, 0, 0, 1514, 0, 0, 1523, - 1515, 1516, 1517, 1518, 1519, 1520, 1524, 0, 0, 0, + 0, 0, 0, 1573, 0, 0, 1588, 1577, 0, 0, + 0, 1575, 0, 0, 0, 0, 0, 0, 1576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1521, 0, 0, 0, 0, 0, 0, 0, 1523, 1513, - 0, 1525, 1514, 0, 0, 1524, 1515, 1516, 1517, 1518, - 1519, 1520, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1521, 0, 1513, 0, - 1525, 1514, 0, 0, 1523, 1515, 1516, 1517, 1518, 1519, - 1520, 1524, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1521, 0, 0, 0, 0, - 0, 0, 0, 1523, 0, 0, 1525, 0, 0, 0, - 1524, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1588, 0, 0, 0, 0, + 0, 0, 0, 1577, 1589, 0, 0, 1590, 1591, 1592, + 0, 1593, 1594, 1595, 1596, 1597, 1598, 0, 0, 0, + 0, 2571, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1589, 0, 0, 1590, 1591, 1592, 1578, + 1593, 1594, 1595, 1596, 1597, 1598, 0, 0, 0, 0, + 2613, 0, 0, 0, 0, 1579, 0, 0, 0, 0, + 1580, 0, 0, 0, 0, 0, 0, 0, 1578, 1589, + 0, 0, 1590, 1591, 1592, 0, 1593, 1594, 1595, 1596, + 1597, 1598, 1581, 1582, 1579, 0, 2670, 0, 0, 1580, + 0, 0, 0, 0, 0, 0, 0, 1583, 1589, 0, + 0, 1590, 1591, 1592, 1578, 1593, 1594, 1595, 1596, 1597, + 1598, 1581, 1582, 0, 0, 2879, 0, 0, 0, 0, + 1579, 0, 0, 0, 0, 1580, 1583, 0, 0, 0, + 0, 0, 0, 0, 0, 1584, 0, 0, 1585, 0, + 0, 0, 0, 0, 0, 0, 0, 1581, 1582, 0, + 0, 0, 1586, 0, 0, 1587, 0, 0, 0, 0, + 0, 0, 1583, 0, 1584, 0, 0, 1585, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1565, + 0, 1586, 1566, 0, 1587, 0, 1567, 1568, 1569, 1570, + 1571, 1572, 0, 0, 0, 0, 0, 0, 0, 0, + 1584, 0, 0, 1585, 0, 0, 1573, 0, 0, 0, + 0, 0, 0, 0, 1575, 1565, 0, 1586, 1566, 0, + 1587, 1576, 1567, 1568, 1569, 1570, 1571, 1572, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1525, 0, 0, 0, 0, - 0, 0, 1526, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1527, 0, - 0, 0, 0, 1528, 0, 0, 1513, 0, 0, 1514, - 0, 1526, 0, 1515, 1516, 1517, 1518, 1519, 1520, 0, - 0, 0, 0, 0, 0, 1529, 1530, 1527, 0, 0, - 0, 0, 1528, 1521, 0, 0, 0, 0, 0, 0, - 1531, 1523, 0, 0, 0, 0, 0, 1526, 1524, 0, - 0, 0, 0, 0, 1529, 1530, 0, 0, 0, 0, - 0, 0, 0, 1527, 0, 0, 0, 0, 1528, 1531, - 0, 0, 0, 1525, 0, 0, 1526, 0, 1532, 0, - 0, 1533, 0, 0, 0, 0, 0, 0, 0, 0, - 1529, 1530, 1527, 0, 0, 1534, 0, 1528, 1535, 0, - 0, 0, 0, 0, 0, 1531, 0, 1532, 0, 0, - 1533, 0, 0, 0, 0, 0, 0, 0, 0, 1529, - 1530, 0, 0, 0, 1534, 0, 0, 1535, 0, 0, - 0, 0, 0, 0, 1531, 0, 0, 0, 0, 0, - 0, 0, 0, 1532, 0, 0, 1533, 0, 0, 0, + 0, 0, 1573, 0, 1565, 1588, 1577, 1566, 0, 0, + 1575, 1567, 1568, 1569, 1570, 1571, 1572, 1576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1534, 0, 0, 1535, 0, 0, 0, 0, 0, 0, - 0, 0, 1532, 0, 1526, 1533, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1536, 0, 1534, - 1527, 0, 1535, 0, 0, 1528, 0, 0, 0, 0, + 0, 1573, 0, 0, 1588, 0, 0, 0, 0, 1575, + 0, 0, 1577, 0, 0, 0, 1576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1536, 1529, 1530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1531, 0, 0, 0, 1513, 0, 0, 1514, - 0, 0, 0, 1515, 1516, 1517, 1518, 1519, 1520, 0, - 0, 0, 1536, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1521, 0, 0, 0, 0, 0, 0, - 1532, 1523, 0, 1533, 0, 0, 0, 0, 1524, 0, - 0, 1536, 0, 0, 0, 0, 0, 1534, 0, 1537, - 1535, 0, 1538, 1539, 1540, 0, 1541, 1542, 1543, 1544, - 1545, 1546, 0, 1525, 0, 0, 1921, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1537, 0, - 0, 1538, 1539, 1540, 0, 1541, 1542, 1543, 1544, 1545, - 1546, 0, 0, 0, 0, 2218, 0, 0, 0, 0, - 1513, 0, 0, 1514, 0, 0, 0, 1515, 1516, 1517, - 1518, 1519, 1520, 0, 1537, 0, 0, 1538, 1539, 1540, - 0, 1541, 1542, 1543, 1544, 1545, 1546, 1521, 0, 0, - 0, 2309, 0, 0, 0, 1523, 0, 0, 0, 1536, - 0, 0, 1524, 1537, 0, 0, 1538, 1539, 1540, 0, - 1541, 1542, 1543, 1544, 1545, 1546, 0, 0, 0, 0, - 2507, 0, 1513, 0, 1526, 1514, 0, 1525, 0, 1515, - 1516, 1517, 1518, 1519, 1520, 0, 0, 0, 0, 0, - 1527, 0, 0, 0, 0, 1528, 0, 0, 0, 1521, - 0, 0, 0, 0, 0, 0, 0, 1523, 0, 0, - 0, 0, 0, 0, 1524, 0, 0, 1529, 1530, 0, + 1588, 1577, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1531, 0, 0, 0, 0, 1513, 0, 1525, - 1514, 0, 0, 0, 1515, 1516, 1517, 1518, 1519, 1520, - 0, 1537, 0, 0, 1538, 1539, 1540, 0, 1541, 1542, - 1543, 1544, 1545, 1546, 1521, 0, 0, 0, 2549, 0, - 1532, 0, 1523, 1533, 0, 0, 0, 0, 1526, 1524, - 0, 0, 0, 0, 0, 0, 0, 1534, 0, 0, - 1535, 0, 0, 0, 1527, 0, 0, 0, 0, 1528, - 0, 0, 0, 0, 1525, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1529, 1530, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1531, 0, 0, 0, - 1526, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1513, 1527, 0, 1514, 0, - 0, 1528, 1515, 1516, 1517, 1518, 1519, 1520, 0, 0, - 0, 0, 0, 0, 1532, 0, 0, 1533, 0, 1536, - 0, 0, 1521, 1529, 1530, 0, 0, 0, 0, 0, - 1523, 1534, 0, 0, 1535, 0, 0, 1524, 1531, 0, - 0, 0, 0, 0, 0, 1526, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1578, 1589, 0, + 0, 1590, 1591, 1592, 0, 1593, 1594, 1595, 1596, 1597, + 1598, 0, 0, 1579, 0, 2882, 0, 0, 1580, 0, + 0, 0, 0, 0, 0, 0, 0, 1589, 0, 0, + 1590, 1591, 1592, 1578, 1593, 1594, 1595, 1596, 1597, 1598, + 1581, 1582, 0, 0, 3009, 0, 0, 0, 0, 1579, + 0, 0, 0, 0, 1580, 1583, 0, 0, 0, 0, + 0, 0, 1578, 1589, 0, 0, 1590, 1591, 1592, 0, + 1593, 1594, 1595, 1596, 1597, 1598, 1581, 1582, 1579, 0, + 3030, 0, 0, 1580, 0, 0, 0, 0, 0, 0, + 0, 1583, 0, 1584, 0, 0, 1585, 0, 0, 0, + 0, 0, 0, 0, 0, 1581, 1582, 0, 0, 0, + 1586, 0, 0, 1587, 0, 0, 0, 0, 0, 0, + 1583, 0, 0, 0, 0, 0, 0, 0, 0, 1584, + 0, 0, 1585, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1565, 0, 1586, 1566, 0, 1587, + 0, 1567, 1568, 1569, 1570, 1571, 1572, 0, 1584, 0, + 0, 1585, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1573, 0, 1565, 0, 1586, 1566, 0, 1587, 1575, + 1567, 1568, 1569, 1570, 1571, 1572, 1576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1527, 1525, 0, 0, 0, 1528, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1532, 0, 0, 1533, - 0, 0, 0, 0, 0, 0, 0, 0, 1529, 1530, - 0, 0, 0, 1534, 0, 0, 1535, 0, 0, 0, - 0, 0, 0, 1531, 0, 0, 0, 0, 0, 0, + 1573, 0, 0, 1588, 0, 0, 0, 0, 1575, 1565, + 0, 1577, 1566, 0, 0, 1576, 1567, 1568, 1569, 1570, + 1571, 1572, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1573, 0, 0, 1588, + 1577, 0, 0, 0, 1575, 0, 0, 0, 0, 0, + 0, 1576, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1588, 0, + 0, 0, 0, 0, 0, 0, 1577, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1537, 0, 1536, 1538, 1539, 1540, 0, 1541, 1542, - 1543, 1544, 1545, 1546, 0, 0, 0, 0, 2602, 0, - 0, 1532, 0, 0, 1533, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1534, 1513, - 0, 1535, 1514, 1526, 0, 0, 1515, 1516, 1517, 1518, - 1519, 1520, 0, 0, 0, 0, 0, 0, 0, 1527, - 0, 0, 0, 0, 1528, 1536, 1521, 0, 0, 0, - 0, 0, 0, 0, 1523, 0, 0, 0, 0, 0, - 0, 1524, 0, 0, 0, 0, 1529, 1530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1531, 0, 0, 0, 1537, 1525, 0, 1538, 1539, - 1540, 0, 1541, 1542, 1543, 1544, 1545, 1546, 0, 0, - 0, 0, 2808, 0, 0, 0, 1513, 0, 0, 1514, - 1536, 0, 0, 1515, 1516, 1517, 1518, 1519, 1520, 1532, - 0, 0, 1533, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1521, 0, 0, 1534, 0, 0, 1535, - 0, 1523, 0, 0, 0, 0, 0, 1537, 1524, 0, - 1538, 1539, 1540, 0, 1541, 1542, 1543, 1544, 1545, 1546, - 0, 0, 0, 0, 2811, 0, 0, 0, 0, 0, - 0, 0, 0, 1525, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1513, 0, 0, 1514, 1526, 0, 0, - 1515, 1516, 1517, 1518, 1519, 1520, 0, 0, 0, 0, - 0, 0, 0, 1527, 0, 0, 0, 0, 1528, 0, - 1521, 0, 1537, 0, 0, 1538, 1539, 1540, 1523, 1541, - 1542, 1543, 1544, 1545, 1546, 1524, 0, 0, 1536, 2938, - 1529, 1530, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1531, 1513, 0, 0, 1514, - 1525, 0, 0, 1515, 1516, 1517, 1518, 1519, 1520, 1513, - 0, 0, 1514, 0, 0, 0, 1515, 0, 0, 1518, - 1519, 1520, 0, 1521, 1526, 0, 0, 0, 0, 0, - 0, 1523, 0, 1532, 0, 0, 1533, 0, 1524, 0, - 1527, 0, 0, 0, 1523, 1528, 0, 0, 0, 0, - 1534, 1524, 0, 1535, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1525, 0, 0, 0, 1529, 1530, 0, - 0, 0, 0, 0, 0, 0, 1525, 0, 0, 0, - 1537, 0, 1531, 1538, 1539, 1540, 0, 1541, 1542, 1543, - 1544, 1545, 1546, 0, 0, 0, 0, 2960, 0, 1513, - 0, 1526, 1514, 0, 0, 0, 1515, 1516, 1517, 1518, - 1519, 1520, 0, 0, 0, 0, 0, 1527, 0, 0, - 1532, 0, 1528, 1533, 0, 0, 1521, 0, 0, 0, - 0, 0, 0, 0, 1523, 0, 0, 1534, 0, 0, - 1535, 1524, 1536, 0, 1529, 1530, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1531, - 1513, 0, 0, 1514, 1526, 0, 1525, 1515, 1516, 1517, - 1518, 1519, 1520, 0, 0, 0, 0, 1526, 0, 0, - 1527, 0, 0, 0, 0, 1528, 0, 1521, 0, 0, - 0, 0, 0, 1527, 0, 1523, 0, 1532, 1528, 0, - 1533, 0, 1524, 0, 0, 0, 0, 1529, 1530, 0, - 0, 0, 0, 0, 1534, 0, 0, 1535, 0, 0, - 1529, 1530, 1531, 0, 0, 0, 0, 1525, 0, 1536, - 0, 0, 0, 0, 0, 1531, 0, 0, 0, 0, - 0, 0, 0, 0, 1537, 0, 0, 1538, 1539, 1540, - 0, 1541, 1542, 1543, 1544, 1545, 1546, 0, 0, 0, - 1532, 3049, 0, 1533, 0, 0, 0, 1526, 0, 0, - 0, 0, 0, 1532, 0, 0, 1533, 1534, 0, 0, - 1535, 0, 0, 1527, 0, 0, 0, 0, 1528, 0, - 1534, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1536, 0, 0, 0, - 1529, 1530, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1531, 0, 0, 1526, 0, - 0, 1537, 0, 0, 1538, 1539, 1540, 0, 1541, 1542, - 1543, 1544, 1545, 1546, 1527, 0, 0, 0, 3087, 1528, + 0, 0, 0, 0, 0, 0, 1589, 0, 0, 1590, + 1591, 1592, 1578, 1593, 1594, 1595, 1596, 1597, 1598, 0, + 0, 0, 0, 3118, 0, 0, 0, 0, 1579, 0, + 0, 0, 0, 1580, 0, 0, 0, 0, 0, 0, + 0, 1578, 1589, 0, 0, 1590, 1591, 1592, 0, 1593, + 1594, 1595, 1596, 1597, 1598, 1581, 1582, 1579, 0, 3171, + 0, 0, 1580, 0, 0, 0, 0, 0, 0, 0, + 1583, 1589, 0, 0, 1590, 1591, 1592, 1578, 1593, 1594, + 1595, 1596, 1597, 1598, 1581, 1582, 0, 0, 3193, 0, + 0, 0, 0, 1579, 0, 0, 0, 0, 1580, 1583, + 0, 0, 0, 0, 0, 0, 0, 0, 1584, 0, + 0, 1585, 0, 0, 0, 0, 0, 0, 0, 0, + 1581, 1582, 0, 0, 0, 1586, 0, 0, 1587, 0, + 0, 0, 0, 0, 0, 1583, 0, 1584, 0, 0, + 1585, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1586, 0, 0, 1587, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1532, 0, 0, 1533, 0, 0, 1536, - 0, 1529, 1530, 0, 0, 0, 0, 0, 0, 0, - 1534, 0, 1536, 1535, 0, 0, 1531, 0, 0, 0, + 0, 0, 0, 1584, 0, 0, 1585, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1537, 0, - 0, 1538, 1539, 1540, 0, 1541, 1542, 1543, 1544, 1545, - 1546, 0, 0, 0, 1532, 3100, 0, 1533, 0, 0, + 1586, 0, 0, 1587, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1534, 0, 0, 1535, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1588, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1537, 1536, 0, 1538, 1539, 1540, 0, 1541, 1542, - 1543, 1544, 1545, 1546, 1537, 0, 1699, 1538, 1539, 1540, - 0, 1541, 1542, 1543, 1544, 1545, 1546, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1588, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1536, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1588, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1537, 0, 0, 1538, 1539, 1540, - 0, 1541, 1542, 1543, 1544, 1545, 1546, 0, 0, 2932, + 0, 1589, 0, 0, 1590, 1591, 1592, 0, 1593, 1594, + 1595, 1596, 1597, 1598, 0, 0, 1754, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1589, 0, 0, 1590, 1591, 1592, 0, 1593, 1594, 1595, + 1596, 1597, 1598, 0, 0, 3003, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1244, 0, 1589, 0, 0, 1590, + 1591, 1592, 0, 1593, 1594, 1595, 1596, 1597, 1598, 0, + 0, 3156, 105, 106, 107, 108, 109, 110, 111, 112, + 1245, 113, 114, 115, 1246, 1247, 1248, 1249, 1250, 1251, + 1252, 116, 117, 1253, 118, 119, 120, 856, 122, 123, + 124, 857, 858, 859, 860, 861, 1254, 130, 131, 132, + 133, 134, 135, 1255, 1256, 136, 137, 862, 863, 140, + 1257, 141, 142, 143, 144, 864, 1258, 865, 1259, 866, + 148, 149, 150, 151, 152, 867, 154, 155, 156, 1260, + 157, 158, 159, 160, 161, 162, 1261, 868, 164, 165, + 166, 869, 870, 871, 872, 1262, 1263, 873, 172, 173, + 174, 175, 176, 177, 178, 874, 875, 181, 1264, 182, + 1265, 183, 184, 185, 186, 187, 188, 1266, 189, 190, + 191, 192, 193, 1267, 1268, 194, 195, 196, 197, 198, + 1269, 199, 200, 201, 1270, 202, 203, 204, 1271, 205, + 206, 207, 208, 876, 210, 211, 212, 213, 214, 877, + 1272, 216, 1273, 217, 218, 878, 220, 1274, 221, 1275, + 222, 879, 1276, 880, 225, 226, 881, 882, 229, 1277, + 230, 1278, 883, 884, 233, 1279, 234, 235, 236, 237, + 238, 239, 240, 885, 242, 243, 244, 245, 1280, 246, + 247, 248, 249, 250, 251, 1281, 252, 886, 887, 255, + 256, 257, 258, 259, 888, 889, 1282, 890, 1283, 263, + 891, 892, 266, 893, 268, 269, 270, 271, 272, 273, + 1284, 1285, 274, 894, 276, 895, 1286, 278, 279, 280, + 1287, 1288, 281, 282, 283, 284, 285, 896, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 897, 898, 899, 308, + 309, 310, 900, 1289, 312, 313, 901, 315, 1290, 902, + 317, 903, 319, 320, 321, 1291, 322, 323, 1292, 1293, + 324, 325, 326, 1294, 1295, 327, 904, 905, 330, 906, + 907, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 1296, 343, 344, 908, 909, 347, 348, 910, 350, + 351, 352, 1297, 353, 354, 355, 356, 357, 358, 1298, + 359, 360, 361, 911, 363, 364, 365, 366, 1299, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 1300, 380, 381, 912, 383, 384, 385, 913, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 1301, 398, 399, 400, 401, 402, 914, 404, 915, + 406, 407, 408, 916, 410, 411, 917, 413, 1302, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 918, 427, 919, 429, 1303, 430, 431, 1304, 432, + 920, 434, 435, 436, 437, 438, 1305, 921, 922, 1306, + 1307, 441, 442, 923, 444, 924, 1308, 446, 447, 925, + 449, 450, 451, 452, 453, 1309, 1310, 454, 455, 456, + 457, 458, 459, 926, 1311, 461, 462, 463, 464, 465, + 1312, 928, 1313, 468, 929, 470, 471, 472, 473, 474, + 1314, 1315, 475, 1316, 1317, 476, 477, 478, 479, 480, + 481, 930, 931, 932, 933, 934, 935, 936, 937, 938, + 939, 940, 493, 494, 495, 496, 504, 0, 0, 0, + 0, 0, 0, 0, 0, 2056, 0, 0, 0, 0, + 0, 0, 0, 0, 105, 106, 107, 108, 109, 110, + 111, 112, 0, 113, 114, 115, 0, 0, 0, 0, + 0, 0, 0, 116, 117, 0, 118, 119, 120, 0, + 122, 123, 124, 125, 126, 0, 128, 129, 0, 130, + 131, 132, 133, 134, 135, 0, 0, 136, 137, 138, + 139, 140, 0, 141, 142, 143, 144, 145, 0, 0, + 0, 147, 148, 149, 150, 151, 152, 0, 154, 155, + 156, 0, 157, 158, 159, 160, 161, 162, 0, 0, + 164, 165, 166, 0, 0, 0, 0, 0, 0, 0, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 0, 182, 0, 183, 184, 185, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 0, 0, 194, 195, 196, + 197, 198, 0, 199, 200, 201, 0, 202, 203, 204, + 0, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 214, 215, 0, 216, 0, 217, 218, 219, 220, 0, + 221, 0, 222, 0, 0, 0, 225, 226, 505, 0, + 229, 0, 230, 0, 231, 232, 233, 0, 234, 235, + 236, 237, 238, 239, 240, 0, 242, 243, 244, 245, + 0, 246, 247, 248, 249, 250, 251, 0, 252, 0, + 254, 255, 256, 257, 258, 259, 260, 261, 0, 262, + 0, 263, 0, 0, 266, 0, 268, 269, 270, 271, + 272, 273, 0, 0, 274, 0, 276, 0, 0, 278, + 279, 280, 0, 0, 281, 282, 283, 284, 285, 506, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 0, + 307, 308, 309, 310, 311, 0, 312, 313, 0, 315, + 0, 316, 317, 318, 319, 320, 321, 0, 322, 323, + 0, 0, 324, 325, 326, 0, 0, 327, 328, 0, + 330, 0, 332, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 0, 343, 344, 345, 0, 347, 348, + 349, 350, 351, 352, 0, 353, 354, 355, 356, 357, + 358, 0, 359, 360, 361, 362, 363, 364, 365, 366, + 0, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 0, 380, 381, 0, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 0, 398, 399, 400, 401, 402, 0, + 404, 405, 406, 407, 408, 0, 410, 411, 412, 413, + 0, 414, 415, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 425, 507, 427, 428, 429, 0, 430, 431, + 0, 432, 0, 434, 435, 436, 437, 438, 0, 439, + 440, 0, 0, 441, 442, 443, 444, 445, 0, 446, + 447, 448, 449, 450, 451, 452, 453, 0, 0, 454, + 455, 456, 457, 458, 459, 0, 0, 461, 462, 463, + 464, 465, 466, 467, 0, 468, 0, 470, 471, 472, + 473, 474, 0, 0, 475, 0, 0, 476, 477, 478, + 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, + 489, 490, 491, 492, 493, 494, 495, 496, 504, 0, + 0, 0, 0, 0, 0, 0, 0, 2564, 0, 0, + 0, 0, 0, 0, 0, 0, 105, 106, 107, 108, + 109, 110, 111, 112, 0, 113, 114, 115, 0, 0, + 0, 0, 0, 0, 0, 116, 117, 0, 118, 119, + 120, 0, 122, 123, 124, 125, 126, 0, 128, 129, + 0, 130, 131, 132, 133, 134, 135, 0, 0, 136, + 137, 138, 139, 140, 0, 141, 142, 143, 144, 145, + 0, 0, 0, 147, 148, 149, 150, 151, 152, 0, + 154, 155, 156, 0, 157, 158, 159, 160, 161, 162, + 0, 0, 164, 165, 166, 0, 0, 0, 0, 0, + 0, 0, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 0, 182, 0, 183, 184, 185, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 0, 0, 194, + 195, 196, 197, 198, 0, 199, 200, 201, 0, 202, + 203, 204, 0, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 0, 216, 0, 217, 218, 219, + 220, 0, 221, 0, 222, 0, 0, 0, 225, 226, + 505, 0, 229, 0, 230, 0, 231, 232, 233, 0, + 234, 235, 236, 237, 238, 239, 240, 0, 242, 243, + 244, 245, 0, 246, 247, 248, 249, 250, 251, 0, + 252, 0, 254, 255, 256, 257, 258, 259, 260, 261, + 0, 262, 0, 263, 0, 0, 266, 0, 268, 269, + 270, 271, 272, 273, 0, 0, 274, 0, 276, 0, + 0, 278, 279, 280, 0, 0, 281, 282, 283, 284, + 285, 506, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 0, 307, 308, 309, 310, 311, 0, 312, 313, + 0, 315, 0, 316, 317, 318, 319, 320, 321, 0, + 322, 323, 0, 0, 324, 325, 326, 0, 0, 327, + 328, 0, 330, 0, 332, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 0, 343, 344, 345, 0, + 347, 348, 349, 350, 351, 352, 0, 353, 354, 355, + 356, 357, 358, 0, 359, 360, 361, 362, 363, 364, + 365, 366, 0, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 0, 380, 381, 0, + 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 0, 398, 399, 400, 401, + 402, 0, 404, 405, 406, 407, 408, 0, 410, 411, + 412, 413, 0, 414, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 425, 507, 427, 428, 429, 0, + 430, 431, 0, 432, 0, 434, 435, 436, 437, 438, + 0, 439, 440, 0, 0, 441, 442, 443, 444, 445, + 0, 446, 447, 448, 449, 450, 451, 452, 453, 0, + 0, 454, 455, 456, 457, 458, 459, 0, 0, 461, + 462, 463, 464, 465, 466, 467, 0, 468, 0, 470, + 471, 472, 473, 474, 0, 0, 475, 0, 0, 476, + 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, + 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, + 855, 1427, 515, 0, 0, 0, 1016, 0, 0, 2567, + 0, 0, 0, 0, 0, 0, 0, 0, 105, 106, + 107, 108, 109, 110, 111, 112, 0, 113, 114, 115, + 0, 0, 0, 0, 0, 0, 0, 116, 117, 0, + 118, 119, 120, 856, 122, 123, 124, 857, 858, 859, + 860, 861, 0, 130, 131, 132, 133, 134, 135, 0, + 0, 136, 137, 862, 863, 140, 0, 141, 142, 143, + 144, 864, 0, 865, 0, 866, 148, 149, 150, 151, + 152, 867, 154, 155, 156, 0, 157, 158, 159, 160, + 161, 162, 0, 868, 164, 165, 166, 869, 870, 871, + 872, 0, 0, 873, 172, 173, 174, 175, 176, 177, + 178, 874, 875, 181, 1624, 182, 0, 183, 184, 185, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 0, + 0, 194, 195, 196, 197, 198, 0, 199, 200, 201, + 0, 202, 203, 204, 0, 205, 206, 207, 208, 876, + 210, 211, 212, 213, 214, 877, 1428, 216, 0, 217, + 218, 878, 220, 0, 221, 0, 222, 879, 0, 880, + 225, 226, 881, 882, 229, 0, 230, 0, 883, 884, + 233, 0, 234, 235, 236, 237, 238, 239, 240, 885, + 242, 243, 244, 245, 0, 246, 247, 248, 249, 250, + 251, 0, 252, 886, 887, 255, 256, 257, 258, 259, + 888, 889, 0, 890, 0, 263, 891, 892, 266, 893, + 268, 269, 270, 271, 272, 273, 0, 0, 274, 894, + 276, 895, 0, 278, 279, 280, 0, 0, 281, 282, + 283, 284, 285, 896, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 897, 898, 899, 308, 309, 310, 900, 0, + 312, 313, 901, 315, 0, 902, 317, 903, 319, 320, + 321, 0, 322, 323, 1429, 0, 324, 325, 326, 0, + 0, 327, 904, 905, 330, 906, 907, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 0, 343, 344, + 908, 909, 347, 348, 910, 350, 351, 352, 0, 353, + 354, 355, 356, 357, 358, 0, 359, 360, 361, 911, + 363, 364, 365, 366, 0, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 0, 380, + 381, 912, 383, 384, 385, 913, 387, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 0, 398, 399, + 400, 401, 402, 914, 404, 915, 406, 407, 408, 916, + 410, 411, 917, 413, 0, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 918, 427, 919, + 429, 0, 430, 431, 0, 432, 920, 434, 435, 436, + 437, 438, 0, 921, 922, 0, 0, 441, 442, 923, + 444, 924, 1430, 446, 447, 925, 449, 450, 451, 452, + 453, 0, 0, 454, 455, 456, 457, 458, 459, 926, + 0, 461, 462, 463, 464, 465, 1312, 928, 0, 468, + 929, 470, 471, 472, 473, 474, 0, 0, 475, 0, + 0, 476, 477, 478, 479, 480, 481, 930, 931, 932, + 933, 934, 935, 936, 937, 938, 939, 940, 493, 494, + 495, 496, 855, 1427, 515, 0, 0, 0, 1016, 1431, + 1432, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 105, 106, 107, 108, 109, 110, 111, 112, 0, 113, + 114, 115, 0, 0, 0, 0, 0, 0, 0, 116, + 117, 0, 118, 119, 120, 856, 122, 123, 124, 857, + 858, 859, 860, 861, 0, 130, 131, 132, 133, 134, + 135, 0, 0, 136, 137, 862, 863, 140, 0, 141, + 142, 143, 144, 864, 0, 865, 0, 866, 148, 149, + 150, 151, 152, 867, 154, 155, 156, 0, 157, 158, + 159, 160, 161, 162, 0, 868, 164, 165, 166, 869, + 870, 871, 872, 0, 0, 873, 172, 173, 174, 175, + 176, 177, 178, 874, 875, 181, 1626, 182, 0, 183, + 184, 185, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 0, 0, 194, 195, 196, 197, 198, 0, 199, + 200, 201, 0, 202, 203, 204, 0, 205, 206, 207, + 208, 876, 210, 211, 212, 213, 214, 877, 1428, 216, + 0, 217, 218, 878, 220, 0, 221, 0, 222, 879, + 0, 880, 225, 226, 881, 882, 229, 0, 230, 0, + 883, 884, 233, 0, 234, 235, 236, 237, 238, 239, + 240, 885, 242, 243, 244, 245, 0, 246, 247, 248, + 249, 250, 251, 0, 252, 886, 887, 255, 256, 257, + 258, 259, 888, 889, 0, 890, 0, 263, 891, 892, + 266, 893, 268, 269, 270, 271, 272, 273, 0, 0, + 274, 894, 276, 895, 0, 278, 279, 280, 0, 0, + 281, 282, 283, 284, 285, 896, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 897, 898, 899, 308, 309, 310, + 900, 0, 312, 313, 901, 315, 0, 902, 317, 903, + 319, 320, 321, 0, 322, 323, 1429, 0, 324, 325, + 326, 0, 0, 327, 904, 905, 330, 906, 907, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 0, + 343, 344, 908, 909, 347, 348, 910, 350, 351, 352, + 0, 353, 354, 355, 356, 357, 358, 0, 359, 360, + 361, 911, 363, 364, 365, 366, 0, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 0, 380, 381, 912, 383, 384, 385, 913, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 0, + 398, 399, 400, 401, 402, 914, 404, 915, 406, 407, + 408, 916, 410, 411, 917, 413, 0, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 918, + 427, 919, 429, 0, 430, 431, 0, 432, 920, 434, + 435, 436, 437, 438, 0, 921, 922, 0, 0, 441, + 442, 923, 444, 924, 1430, 446, 447, 925, 449, 450, + 451, 452, 453, 0, 0, 454, 455, 456, 457, 458, + 459, 926, 0, 461, 462, 463, 464, 465, 1312, 928, + 0, 468, 929, 470, 471, 472, 473, 474, 0, 0, + 475, 0, 0, 476, 477, 478, 479, 480, 481, 930, + 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, + 493, 494, 495, 496, 855, 1427, 515, 0, 0, 0, + 1016, 1431, 1432, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 105, 106, 107, 108, 109, 110, 111, 112, + 0, 113, 114, 115, 0, 0, 0, 0, 0, 0, + 0, 116, 117, 0, 118, 119, 120, 856, 122, 123, + 124, 857, 858, 859, 860, 861, 0, 130, 131, 132, + 133, 134, 135, 0, 0, 136, 137, 862, 863, 140, + 0, 141, 142, 143, 144, 864, 0, 865, 0, 866, + 148, 149, 150, 151, 152, 867, 154, 155, 156, 0, + 157, 158, 159, 160, 161, 162, 0, 868, 164, 165, + 166, 869, 870, 871, 872, 0, 0, 873, 172, 173, + 174, 175, 176, 177, 178, 874, 875, 181, 0, 182, + 0, 183, 184, 185, 186, 187, 188, 0, 189, 190, + 191, 192, 193, 0, 0, 194, 195, 196, 197, 198, + 0, 199, 200, 201, 0, 202, 203, 204, 0, 205, + 206, 207, 208, 876, 210, 211, 212, 213, 214, 877, + 1428, 216, 0, 217, 218, 878, 220, 0, 221, 0, + 222, 879, 0, 880, 225, 226, 881, 882, 229, 0, + 230, 0, 883, 884, 233, 0, 234, 235, 236, 237, + 238, 239, 240, 885, 242, 243, 244, 245, 0, 246, + 247, 248, 249, 250, 251, 0, 252, 886, 887, 255, + 256, 257, 258, 259, 888, 889, 0, 890, 0, 263, + 891, 892, 266, 893, 268, 269, 270, 271, 272, 273, + 0, 0, 274, 894, 276, 895, 0, 278, 279, 280, + 0, 0, 281, 282, 283, 284, 285, 896, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 897, 898, 899, 308, + 309, 310, 900, 0, 312, 313, 901, 315, 0, 902, + 317, 903, 319, 320, 321, 0, 322, 323, 1429, 0, + 324, 325, 326, 0, 0, 327, 904, 905, 330, 906, + 907, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 0, 343, 344, 908, 909, 347, 348, 910, 350, + 351, 352, 0, 353, 354, 355, 356, 357, 358, 0, + 359, 360, 361, 911, 363, 364, 365, 366, 0, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 0, 380, 381, 912, 383, 384, 385, 913, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 0, 398, 399, 400, 401, 402, 914, 404, 915, + 406, 407, 408, 916, 410, 411, 917, 413, 0, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 918, 427, 919, 429, 0, 430, 431, 0, 432, + 920, 434, 435, 436, 437, 438, 0, 921, 922, 0, + 0, 441, 442, 923, 444, 924, 1430, 446, 447, 925, + 449, 450, 451, 452, 453, 0, 0, 454, 455, 456, + 457, 458, 459, 926, 0, 461, 462, 463, 464, 465, + 1312, 928, 0, 468, 929, 470, 471, 472, 473, 474, + 0, 0, 475, 0, 0, 476, 477, 478, 479, 480, + 481, 930, 931, 932, 933, 934, 935, 936, 937, 938, + 939, 940, 493, 494, 495, 496, 0, 0, 1565, 0, + 0, 1566, 0, 1431, 1432, 1567, 1568, 1569, 1570, 1571, + 1572, 1565, 0, 0, 1566, 0, 0, 0, 1567, 1568, + 1569, 1570, 1571, 1572, 0, 1573, 0, 0, 0, 2079, + 0, 0, 0, 1575, 0, 0, 0, 0, 1573, 0, + 1576, 0, 0, 0, 0, 0, 1575, 1565, 0, 0, + 1566, 0, 0, 1576, 1567, 1568, 1569, 1570, 1571, 1572, + 1565, 0, 0, 1566, 0, 1577, 0, 1567, 1568, 1569, + 1570, 1571, 1572, 0, 1573, 0, 0, 0, 1577, 0, + 0, 0, 1575, 0, 0, 0, 0, 1573, 0, 1576, + 1853, 0, 0, 0, 0, 1575, 1565, 0, 0, 1566, + 0, 0, 1576, 1567, 1568, 1569, 1570, 1571, 1572, 0, + 0, 0, 0, 0, 1577, 0, 2080, 0, 0, 0, + 0, 0, 0, 1573, 0, 0, 0, 1577, 0, 0, + 0, 1575, 0, 0, 0, 0, 0, 0, 1576, 0, + 0, 1565, 0, 0, 1566, 0, 0, 0, 1567, 1568, + 1569, 1570, 1571, 1572, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1577, 0, 0, 1578, 0, 1573, 1892, + 0, 1898, 0, 0, 1893, 0, 1575, 0, 0, 1578, + 0, 0, 1579, 1576, 0, 0, 0, 1580, 0, 0, + 0, 0, 0, 0, 0, 1579, 0, 0, 0, 0, + 1580, 0, 0, 0, 3254, 0, 0, 0, 1577, 1581, + 1582, 0, 0, 0, 0, 1578, 0, 0, 0, 0, + 0, 0, 1581, 1582, 1583, 0, 0, 0, 1578, 0, + 0, 1579, 0, 0, 0, 0, 1580, 1583, 0, 0, + 0, 0, 0, 0, 1579, 0, 0, 0, 0, 1580, + 0, 0, 0, 0, 0, 0, 0, 0, 1581, 1582, + 0, 0, 1584, 0, 1578, 1585, 0, 0, 0, 0, + 0, 1581, 1582, 1583, 0, 1584, 0, 0, 1585, 1586, + 1579, 0, 1587, 0, 0, 1580, 1583, 0, 0, 0, + 0, 0, 1586, 0, 0, 1587, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1581, 1582, 1578, + 0, 1584, 0, 0, 1585, 0, 0, 0, 0, 0, + 0, 0, 1583, 0, 1584, 1579, 0, 1585, 1586, 0, + 1580, 1587, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1586, 0, 0, 1587, 0, 0, 0, 0, 0, + 0, 0, 1581, 1582, 0, 3255, 0, 0, 0, 0, + 1584, 0, 0, 1585, 0, 0, 0, 1583, 0, 0, + 0, 0, 1588, 0, 0, 0, 0, 1586, 0, 0, + 1587, 0, 0, 0, 0, 1588, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1864, 0, + 0, 0, 0, 0, 0, 1584, 0, 0, 1585, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1588, 1586, 0, 0, 1587, 0, 0, 0, 0, + 0, 0, 0, 2084, 1588, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1202, 0, 1537, 0, 0, 1538, 1539, - 1540, 0, 1541, 1542, 1543, 1544, 1545, 1546, 0, 0, - 3081, 96, 97, 98, 99, 100, 101, 102, 103, 1203, - 104, 105, 106, 1204, 1205, 1206, 1207, 1208, 1209, 1210, - 107, 108, 1211, 109, 110, 111, 824, 113, 114, 115, - 825, 826, 827, 828, 829, 1212, 121, 122, 123, 124, - 125, 126, 1213, 1214, 127, 128, 830, 831, 131, 1215, - 132, 133, 134, 135, 832, 1216, 833, 1217, 834, 139, - 140, 141, 142, 143, 835, 145, 146, 147, 1218, 148, - 149, 150, 151, 152, 153, 1219, 836, 155, 156, 157, - 837, 838, 839, 840, 1220, 1221, 841, 163, 164, 165, - 166, 167, 168, 169, 842, 843, 172, 1222, 173, 1223, - 174, 175, 176, 177, 178, 179, 1224, 180, 181, 182, - 183, 184, 1225, 1226, 185, 186, 187, 188, 189, 1227, - 190, 191, 192, 1228, 193, 194, 195, 1229, 196, 197, - 198, 199, 844, 201, 202, 203, 204, 205, 845, 1230, - 207, 1231, 208, 209, 846, 211, 1232, 212, 1233, 213, - 847, 1234, 848, 216, 217, 849, 850, 220, 1235, 221, - 1236, 851, 852, 224, 1237, 225, 226, 227, 228, 229, - 230, 231, 853, 233, 234, 235, 236, 1238, 237, 238, - 239, 240, 241, 242, 1239, 243, 854, 855, 246, 247, - 248, 249, 250, 856, 857, 1240, 858, 1241, 254, 859, - 860, 257, 861, 259, 260, 261, 262, 263, 264, 1242, - 1243, 265, 862, 267, 863, 1244, 269, 270, 271, 1245, - 1246, 272, 273, 274, 275, 276, 864, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, 292, 293, 294, 295, 865, 866, 867, 299, 300, - 301, 868, 1247, 303, 304, 869, 306, 1248, 870, 308, - 871, 310, 311, 312, 1249, 313, 314, 1250, 1251, 315, - 316, 317, 1252, 1253, 318, 872, 873, 321, 874, 875, - 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, - 1254, 334, 335, 876, 337, 338, 877, 340, 341, 342, - 1255, 343, 344, 345, 346, 347, 348, 1256, 349, 350, - 351, 878, 353, 354, 355, 356, 1257, 357, 358, 359, - 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, - 1258, 370, 371, 879, 373, 374, 375, 880, 377, 378, - 379, 380, 381, 382, 383, 384, 385, 386, 387, 1259, - 388, 389, 390, 391, 392, 881, 394, 882, 396, 397, - 398, 883, 400, 401, 884, 403, 1260, 404, 405, 406, - 407, 408, 409, 410, 411, 412, 413, 414, 415, 885, - 417, 886, 419, 1261, 420, 421, 1262, 422, 887, 424, - 425, 426, 427, 428, 1263, 888, 889, 1264, 1265, 431, - 432, 890, 434, 891, 1266, 436, 437, 892, 439, 440, - 441, 442, 443, 1267, 1268, 444, 445, 446, 447, 448, - 893, 1269, 450, 451, 452, 453, 454, 1270, 895, 1271, - 457, 896, 459, 460, 461, 462, 463, 1272, 1273, 464, - 1274, 1275, 465, 466, 467, 468, 469, 470, 897, 898, - 899, 900, 901, 902, 903, 904, 905, 906, 907, 482, - 483, 484, 485, 508, 0, 0, 0, 0, 0, 0, - 0, 0, 1993, 0, 0, 0, 0, 0, 0, 0, - 0, 96, 97, 98, 99, 100, 101, 102, 103, 0, - 104, 105, 106, 0, 0, 0, 0, 0, 0, 0, - 107, 108, 0, 109, 110, 111, 0, 113, 114, 115, - 116, 117, 0, 119, 120, 0, 121, 122, 123, 124, - 125, 126, 0, 0, 127, 128, 129, 130, 131, 0, - 132, 133, 134, 135, 136, 0, 0, 0, 138, 139, - 140, 141, 142, 143, 0, 145, 146, 147, 0, 148, - 149, 150, 151, 152, 153, 0, 0, 155, 156, 157, - 0, 0, 0, 0, 0, 0, 0, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 0, 173, 0, - 174, 175, 176, 177, 178, 179, 0, 180, 181, 182, - 183, 184, 0, 0, 185, 186, 187, 188, 189, 0, - 190, 191, 192, 0, 193, 194, 195, 0, 196, 197, - 198, 199, 200, 201, 202, 203, 204, 205, 206, 0, - 207, 0, 208, 209, 210, 211, 0, 212, 0, 213, - 0, 0, 0, 216, 217, 511, 0, 220, 0, 221, - 0, 222, 223, 224, 0, 225, 226, 227, 228, 229, - 230, 231, 0, 233, 234, 235, 236, 0, 237, 238, - 239, 240, 241, 242, 0, 243, 0, 245, 246, 247, - 248, 249, 250, 251, 252, 0, 253, 0, 254, 0, - 0, 257, 0, 259, 260, 261, 262, 263, 264, 0, - 0, 265, 0, 267, 0, 0, 269, 270, 271, 0, - 0, 272, 273, 274, 275, 276, 512, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, 292, 293, 294, 295, 296, 0, 298, 299, 300, - 301, 302, 0, 303, 304, 0, 306, 0, 307, 308, - 309, 310, 311, 312, 0, 313, 314, 0, 0, 315, - 316, 317, 0, 0, 318, 319, 0, 321, 0, 323, - 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, - 0, 334, 335, 336, 337, 338, 339, 340, 341, 342, - 0, 343, 344, 345, 346, 347, 348, 0, 349, 350, - 351, 352, 353, 354, 355, 356, 0, 357, 358, 359, - 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, - 0, 370, 371, 0, 373, 374, 375, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, 386, 387, 0, - 388, 389, 390, 391, 392, 0, 394, 395, 396, 397, - 398, 0, 400, 401, 402, 403, 0, 404, 405, 406, - 407, 408, 409, 410, 411, 412, 413, 414, 415, 514, - 417, 418, 419, 0, 420, 421, 0, 422, 0, 424, - 425, 426, 427, 428, 0, 429, 430, 0, 0, 431, - 432, 433, 434, 435, 0, 436, 437, 438, 439, 440, - 441, 442, 443, 0, 0, 444, 445, 446, 447, 448, - 0, 0, 450, 451, 452, 453, 454, 455, 456, 0, - 457, 0, 459, 460, 461, 462, 463, 0, 0, 464, - 0, 0, 465, 466, 467, 468, 469, 470, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 483, 484, 485, 823, 1377, 624, 0, 0, 0, 980, - 0, 0, 2502, 0, 0, 0, 0, 0, 0, 0, - 0, 96, 97, 98, 99, 100, 101, 102, 103, 0, - 104, 105, 106, 0, 0, 0, 0, 0, 0, 0, - 107, 108, 0, 109, 110, 111, 824, 113, 114, 115, - 825, 826, 827, 828, 829, 0, 121, 122, 123, 124, - 125, 126, 0, 0, 127, 128, 830, 831, 131, 0, - 132, 133, 134, 135, 832, 0, 833, 0, 834, 139, - 140, 141, 142, 143, 835, 145, 146, 147, 0, 148, - 149, 150, 151, 152, 153, 0, 836, 155, 156, 157, - 837, 838, 839, 840, 0, 0, 841, 163, 164, 165, - 166, 167, 168, 169, 842, 843, 172, 1572, 173, 0, - 174, 175, 176, 177, 178, 179, 0, 180, 181, 182, - 183, 184, 0, 0, 185, 186, 187, 188, 189, 0, - 190, 191, 192, 0, 193, 194, 195, 0, 196, 197, - 198, 199, 844, 201, 202, 203, 204, 205, 845, 1378, - 207, 0, 208, 209, 846, 211, 0, 212, 0, 213, - 847, 0, 848, 216, 217, 849, 850, 220, 0, 221, - 0, 851, 852, 224, 0, 225, 226, 227, 228, 229, - 230, 231, 853, 233, 234, 235, 236, 0, 237, 238, - 239, 240, 241, 242, 0, 243, 854, 855, 246, 247, - 248, 249, 250, 856, 857, 0, 858, 0, 254, 859, - 860, 257, 861, 259, 260, 261, 262, 263, 264, 0, - 0, 265, 862, 267, 863, 0, 269, 270, 271, 0, - 0, 272, 273, 274, 275, 276, 864, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, 292, 293, 294, 295, 865, 866, 867, 299, 300, - 301, 868, 0, 303, 304, 869, 306, 0, 870, 308, - 871, 310, 311, 312, 0, 313, 314, 1379, 0, 315, - 316, 317, 0, 0, 318, 872, 873, 321, 874, 875, - 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, - 0, 334, 335, 876, 337, 338, 877, 340, 341, 342, - 0, 343, 344, 345, 346, 347, 348, 0, 349, 350, - 351, 878, 353, 354, 355, 356, 0, 357, 358, 359, - 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, - 0, 370, 371, 879, 373, 374, 375, 880, 377, 378, - 379, 380, 381, 382, 383, 384, 385, 386, 387, 0, - 388, 389, 390, 391, 392, 881, 394, 882, 396, 397, - 398, 883, 400, 401, 884, 403, 0, 404, 405, 406, - 407, 408, 409, 410, 411, 412, 413, 414, 415, 885, - 417, 886, 419, 0, 420, 421, 0, 422, 887, 424, - 425, 426, 427, 428, 0, 888, 889, 0, 0, 431, - 432, 890, 434, 891, 1380, 436, 437, 892, 439, 440, - 441, 442, 443, 0, 0, 444, 445, 446, 447, 448, - 893, 0, 450, 451, 452, 453, 454, 1270, 895, 0, - 457, 896, 459, 460, 461, 462, 463, 0, 0, 464, - 0, 0, 465, 466, 467, 468, 469, 470, 897, 898, - 899, 900, 901, 902, 903, 904, 905, 906, 907, 482, - 483, 484, 485, 823, 1377, 624, 0, 0, 0, 980, - 1381, 1382, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 96, 97, 98, 99, 100, 101, 102, 103, 0, - 104, 105, 106, 0, 0, 0, 0, 0, 0, 0, - 107, 108, 0, 109, 110, 111, 824, 113, 114, 115, - 825, 826, 827, 828, 829, 0, 121, 122, 123, 124, - 125, 126, 0, 0, 127, 128, 830, 831, 131, 0, - 132, 133, 134, 135, 832, 0, 833, 0, 834, 139, - 140, 141, 142, 143, 835, 145, 146, 147, 0, 148, - 149, 150, 151, 152, 153, 0, 836, 155, 156, 157, - 837, 838, 839, 840, 0, 0, 841, 163, 164, 165, - 166, 167, 168, 169, 842, 843, 172, 1574, 173, 0, - 174, 175, 176, 177, 178, 179, 0, 180, 181, 182, - 183, 184, 0, 0, 185, 186, 187, 188, 189, 0, - 190, 191, 192, 0, 193, 194, 195, 0, 196, 197, - 198, 199, 844, 201, 202, 203, 204, 205, 845, 1378, - 207, 0, 208, 209, 846, 211, 0, 212, 0, 213, - 847, 0, 848, 216, 217, 849, 850, 220, 0, 221, - 0, 851, 852, 224, 0, 225, 226, 227, 228, 229, - 230, 231, 853, 233, 234, 235, 236, 0, 237, 238, - 239, 240, 241, 242, 0, 243, 854, 855, 246, 247, - 248, 249, 250, 856, 857, 0, 858, 0, 254, 859, - 860, 257, 861, 259, 260, 261, 262, 263, 264, 0, - 0, 265, 862, 267, 863, 0, 269, 270, 271, 0, - 0, 272, 273, 274, 275, 276, 864, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, 292, 293, 294, 295, 865, 866, 867, 299, 300, - 301, 868, 0, 303, 304, 869, 306, 0, 870, 308, - 871, 310, 311, 312, 0, 313, 314, 1379, 0, 315, - 316, 317, 0, 0, 318, 872, 873, 321, 874, 875, - 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, - 0, 334, 335, 876, 337, 338, 877, 340, 341, 342, - 0, 343, 344, 345, 346, 347, 348, 0, 349, 350, - 351, 878, 353, 354, 355, 356, 0, 357, 358, 359, - 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, - 0, 370, 371, 879, 373, 374, 375, 880, 377, 378, - 379, 380, 381, 382, 383, 384, 385, 386, 387, 0, - 388, 389, 390, 391, 392, 881, 394, 882, 396, 397, - 398, 883, 400, 401, 884, 403, 0, 404, 405, 406, - 407, 408, 409, 410, 411, 412, 413, 414, 415, 885, - 417, 886, 419, 0, 420, 421, 0, 422, 887, 424, - 425, 426, 427, 428, 0, 888, 889, 0, 0, 431, - 432, 890, 434, 891, 1380, 436, 437, 892, 439, 440, - 441, 442, 443, 0, 0, 444, 445, 446, 447, 448, - 893, 0, 450, 451, 452, 453, 454, 1270, 895, 0, - 457, 896, 459, 460, 461, 462, 463, 0, 0, 464, - 0, 0, 465, 466, 467, 468, 469, 470, 897, 898, - 899, 900, 901, 902, 903, 904, 905, 906, 907, 482, - 483, 484, 485, 823, 1377, 624, 0, 0, 0, 980, - 1381, 1382, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 96, 97, 98, 99, 100, 101, 102, 103, 0, - 104, 105, 106, 0, 0, 0, 0, 0, 0, 0, - 107, 108, 0, 109, 110, 111, 824, 113, 114, 115, - 825, 826, 827, 828, 829, 0, 121, 122, 123, 124, - 125, 126, 0, 0, 127, 128, 830, 831, 131, 0, - 132, 133, 134, 135, 832, 0, 833, 0, 834, 139, - 140, 141, 142, 143, 835, 145, 146, 147, 0, 148, - 149, 150, 151, 152, 153, 0, 836, 155, 156, 157, - 837, 838, 839, 840, 0, 0, 841, 163, 164, 165, - 166, 167, 168, 169, 842, 843, 172, 0, 173, 0, - 174, 175, 176, 177, 178, 179, 0, 180, 181, 182, - 183, 184, 0, 0, 185, 186, 187, 188, 189, 0, - 190, 191, 192, 0, 193, 194, 195, 0, 196, 197, - 198, 199, 844, 201, 202, 203, 204, 205, 845, 1378, - 207, 0, 208, 209, 846, 211, 0, 212, 0, 213, - 847, 0, 848, 216, 217, 849, 850, 220, 0, 221, - 0, 851, 852, 224, 0, 225, 226, 227, 228, 229, - 230, 231, 853, 233, 234, 235, 236, 0, 237, 238, - 239, 240, 241, 242, 0, 243, 854, 855, 246, 247, - 248, 249, 250, 856, 857, 0, 858, 0, 254, 859, - 860, 257, 861, 259, 260, 261, 262, 263, 264, 0, - 0, 265, 862, 267, 863, 0, 269, 270, 271, 0, - 0, 272, 273, 274, 275, 276, 864, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, 292, 293, 294, 295, 865, 866, 867, 299, 300, - 301, 868, 0, 303, 304, 869, 306, 0, 870, 308, - 871, 310, 311, 312, 0, 313, 314, 1379, 0, 315, - 316, 317, 0, 0, 318, 872, 873, 321, 874, 875, - 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, - 0, 334, 335, 876, 337, 338, 877, 340, 341, 342, - 0, 343, 344, 345, 346, 347, 348, 0, 349, 350, - 351, 878, 353, 354, 355, 356, 0, 357, 358, 359, - 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, - 0, 370, 371, 879, 373, 374, 375, 880, 377, 378, - 379, 380, 381, 382, 383, 384, 385, 386, 387, 0, - 388, 389, 390, 391, 392, 881, 394, 882, 396, 397, - 398, 883, 400, 401, 884, 403, 0, 404, 405, 406, - 407, 408, 409, 410, 411, 412, 413, 414, 415, 885, - 417, 886, 419, 0, 420, 421, 0, 422, 887, 424, - 425, 426, 427, 428, 0, 888, 889, 0, 0, 431, - 432, 890, 434, 891, 1380, 436, 437, 892, 439, 440, - 441, 442, 443, 0, 0, 444, 445, 446, 447, 448, - 893, 0, 450, 451, 452, 453, 454, 1270, 895, 0, - 457, 896, 459, 460, 461, 462, 463, 0, 0, 464, - 0, 0, 465, 466, 467, 468, 469, 470, 897, 898, - 899, 900, 901, 902, 903, 904, 905, 906, 907, 482, - 483, 484, 485, 0, 0, 1513, 0, 0, 1514, 0, - 1381, 1382, 1515, 1516, 1517, 1518, 1519, 1520, 1513, 0, - 0, 1514, 0, 0, 0, 1515, 1516, 1517, 1518, 1519, - 1520, 0, 1521, 0, 0, 0, 2020, 0, 0, 0, - 1523, 0, 0, 0, 0, 1521, 0, 1524, 0, 0, - 0, 0, 0, 1523, 1513, 0, 0, 1514, 0, 0, - 1524, 1515, 1516, 1517, 1518, 1519, 1520, 1513, 0, 0, - 1514, 0, 1525, 0, 1515, 1516, 1517, 1518, 1519, 1520, - 0, 1521, 0, 0, 0, 1525, 0, 0, 0, 1523, - 0, 0, 0, 0, 1521, 0, 1524, 1791, 0, 0, - 0, 0, 1523, 1513, 0, 0, 1514, 0, 0, 1524, - 1515, 1516, 1517, 1518, 1519, 1520, 0, 0, 0, 0, - 0, 1525, 0, 2021, 0, 0, 0, 0, 0, 0, - 1521, 0, 0, 0, 1525, 0, 0, 0, 1523, 0, - 0, 0, 0, 0, 0, 1524, 0, 0, 1513, 0, - 0, 1514, 0, 0, 0, 1515, 1516, 1517, 1518, 1519, - 1520, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1525, 0, 0, 1526, 0, 1521, 1830, 0, 1836, 0, - 0, 1831, 0, 1523, 0, 0, 1526, 0, 0, 1527, - 1524, 0, 0, 0, 1528, 0, 0, 0, 0, 0, - 0, 0, 1527, 0, 0, 0, 0, 1528, 0, 0, - 0, 3174, 0, 0, 0, 1525, 1529, 1530, 0, 0, - 0, 0, 1526, 0, 0, 0, 0, 0, 0, 1529, - 1530, 1531, 0, 0, 0, 1526, 0, 0, 1527, 0, - 0, 0, 0, 1528, 1531, 0, 0, 0, 0, 0, - 0, 1527, 0, 0, 0, 0, 1528, 0, 0, 0, - 0, 0, 0, 0, 0, 1529, 1530, 0, 0, 1532, - 0, 1526, 1533, 0, 0, 0, 0, 0, 1529, 1530, - 1531, 0, 1532, 0, 0, 1533, 1534, 1527, 0, 1535, - 0, 0, 1528, 1531, 0, 0, 0, 0, 0, 1534, - 0, 0, 1535, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1529, 1530, 1526, 0, 1532, 0, - 0, 1533, 0, 0, 0, 0, 0, 0, 0, 1531, - 0, 1532, 1527, 0, 1533, 1534, 0, 1528, 1535, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1534, 0, - 0, 1535, 0, 0, 0, 0, 0, 0, 0, 1529, - 1530, 3175, 0, 0, 0, 0, 0, 1532, 0, 0, - 1533, 0, 0, 0, 1531, 0, 0, 0, 1536, 0, - 0, 0, 0, 0, 1534, 0, 0, 1535, 0, 0, - 0, 1536, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1802, 0, 0, 0, 0, - 0, 0, 1532, 0, 0, 1533, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1536, 0, 1534, - 0, 0, 1535, 0, 0, 0, 0, 0, 2025, 0, - 1536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1536, 0, 0, 0, - 1537, 0, 0, 1538, 1539, 1540, 0, 1541, 1542, 1543, - 1544, 1545, 1546, 1537, 0, 0, 1538, 1539, 1540, 0, - 1541, 1542, 1543, 1544, 1545, 1546, 0, 0, 0, 0, + 1588, 0, 0, 0, 0, 1589, 0, 0, 1590, 1591, + 1592, 0, 1593, 1594, 1595, 1596, 1597, 1598, 1589, 0, + 0, 1590, 1591, 1592, 0, 1593, 1594, 1595, 1596, 1597, + 1598, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1588, 0, 0, 0, 0, + 0, 0, 0, 0, 1589, 0, 0, 1590, 1591, 1592, + 0, 1593, 1594, 1595, 1596, 1597, 1598, 1589, 0, 0, + 1590, 1591, 1592, 0, 1593, 1594, 1595, 1596, 1597, 1598, + 0, 0, 1565, 0, 0, 1566, 0, 0, 0, 1567, + 1568, 1569, 1570, 1571, 1572, 0, 0, 0, 0, 0, + 0, 0, 0, 1589, 0, 0, 1590, 1591, 1592, 1573, + 1593, 1594, 1595, 1596, 1597, 1598, 0, 1575, 0, 0, + 0, 0, 0, 0, 1576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1536, 0, 0, 0, 0, 0, 0, 0, 1537, - 0, 0, 1538, 1539, 1540, 0, 1541, 1542, 1543, 1544, - 1545, 1546, 1537, 0, 0, 1538, 1539, 1540, 0, 1541, - 1542, 1543, 1544, 1545, 1546, 0, 0, 1513, 0, 0, - 1514, 0, 0, 0, 1515, 1516, 1517, 1518, 1519, 1520, - 0, 0, 0, 0, 0, 0, 0, 0, 1537, 0, - 0, 1538, 1539, 1540, 1521, 1541, 1542, 1543, 1544, 1545, - 1546, 0, 1523, 0, 0, 0, 0, 0, 0, 1524, + 0, 0, 0, 0, 0, 0, 0, 0, 1589, 1577, + 0, 1590, 1591, 1592, 0, 1593, 1594, 1595, 1596, 1597, + 1598, 1565, 0, 0, 1566, 0, 0, 0, 1567, 1568, + 1569, 1570, 1571, 1572, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1573, 0, + 0, 1905, 0, 0, 0, 0, 1575, 0, 0, 0, + 0, 0, 0, 1576, 0, 0, 1565, 0, 0, 1566, + 0, 0, 0, 1567, 1568, 1569, 1570, 1571, 1572, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1577, 0, + 0, 0, 0, 1573, 0, 0, 0, 0, 0, 0, + 0, 1575, 0, 0, 0, 1903, 0, 0, 1576, 0, + 1578, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1579, 0, 0, 0, + 0, 1580, 0, 1577, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 1581, 1582, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1583, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1537, 1525, 0, 1538, 1539, 1540, 0, - 1541, 1542, 1543, 1544, 1545, 1546, 1513, 0, 0, 1514, - 0, 0, 0, 1515, 1516, 1517, 1518, 1519, 1520, 0, + 0, 0, 0, 0, 0, 1565, 0, 0, 1566, 1578, + 0, 0, 1567, 1568, 1569, 1570, 1571, 1572, 0, 0, + 0, 0, 0, 0, 0, 1579, 1584, 0, 0, 1585, + 1580, 0, 1573, 0, 0, 0, 0, 0, 0, 0, + 1575, 0, 0, 1586, 1981, 0, 1587, 1576, 0, 0, + 0, 0, 1581, 1582, 1578, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1583, 0, 0, + 1579, 0, 1577, 0, 0, 1580, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1521, 0, 1513, 1843, 0, 1514, 0, - 0, 1523, 1515, 1516, 1517, 1518, 1519, 1520, 1524, 0, + 0, 0, 0, 0, 0, 0, 0, 1581, 1582, 0, + 0, 0, 0, 0, 0, 1584, 0, 0, 1585, 0, + 0, 0, 1583, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1586, 0, 0, 1587, 0, 0, 0, 0, + 1565, 0, 0, 1566, 0, 0, 1588, 1567, 1568, 1569, + 1570, 1571, 1572, 0, 0, 0, 0, 0, 0, 0, + 1584, 0, 0, 1585, 0, 0, 0, 1573, 0, 0, + 2611, 0, 0, 0, 0, 1575, 0, 1586, 0, 0, + 1587, 0, 1576, 1578, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1579, + 0, 0, 1565, 0, 1580, 1566, 0, 1577, 0, 1567, + 1568, 1569, 1570, 1571, 1572, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1588, 1581, 1582, 0, 1573, + 0, 0, 0, 0, 0, 0, 0, 1575, 0, 0, + 0, 1583, 0, 0, 1576, 0, 0, 0, 0, 1589, + 0, 0, 1590, 1591, 1592, 0, 1593, 1594, 1595, 1596, + 1597, 1598, 0, 0, 0, 0, 0, 0, 0, 1577, + 1588, 0, 0, 0, 0, 0, 0, 0, 0, 1584, + 0, 0, 1585, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1586, 0, 0, 1587, + 0, 0, 0, 0, 0, 0, 0, 0, 1578, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1521, 0, 0, 0, 0, 0, 0, 0, - 1523, 0, 0, 1525, 0, 0, 0, 1524, 0, 0, + 0, 0, 0, 0, 1579, 0, 0, 0, 1589, 1580, + 0, 1590, 1591, 1592, 0, 1593, 1594, 1595, 1596, 1597, + 1598, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1581, 1582, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1583, 0, 0, 0, + 1578, 0, 0, 1589, 0, 0, 1590, 1591, 1592, 0, + 1593, 1594, 1595, 1596, 1597, 1598, 1579, 0, 0, 1588, + 1565, 1580, 0, 1566, 0, 0, 0, 1567, 1568, 1569, + 1570, 1571, 1572, 0, 1584, 0, 0, 1585, 0, 0, + 0, 0, 0, 1581, 1582, 0, 0, 1573, 0, 0, + 0, 1586, 2601, 0, 1587, 1575, 0, 0, 1583, 0, + 0, 0, 1576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1841, 0, 0, 0, 0, 1526, 0, 0, 0, 0, - 0, 0, 1525, 0, 0, 0, 0, 0, 0, 0, - 0, 1527, 0, 0, 0, 0, 1528, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1577, 0, 0, + 0, 0, 0, 0, 0, 0, 1584, 0, 0, 1585, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1529, 1530, + 0, 0, 0, 1586, 0, 0, 1587, 0, 0, 0, + 0, 0, 1589, 0, 0, 1590, 1591, 1592, 0, 1593, + 1594, 1595, 1596, 1597, 1598, 0, 0, 0, 1565, 0, + 0, 1566, 0, 0, 1588, 1567, 0, 0, 1570, 1571, + 1572, 0, 0, 0, 0, 0, 1565, 0, 0, 1566, + 0, 0, 0, 1567, 0, 1573, 1570, 1571, 1572, 0, + 0, 0, 0, 1575, 0, 0, 0, 0, 0, 0, + 1576, 0, 0, 0, 0, 0, 0, 0, 1578, 0, + 0, 1575, 0, 0, 0, 0, 0, 0, 1576, 0, + 0, 0, 0, 0, 1579, 1577, 1588, 0, 0, 1580, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1531, 1513, 0, 0, 1514, 0, 0, - 0, 1515, 1516, 1517, 1518, 1519, 1520, 0, 0, 0, - 0, 0, 0, 0, 1526, 0, 0, 0, 0, 0, - 0, 1521, 0, 0, 0, 0, 0, 0, 0, 1523, - 1527, 1532, 0, 1919, 1533, 1528, 1524, 0, 0, 0, - 0, 0, 0, 1526, 0, 0, 0, 0, 1534, 0, - 0, 1535, 0, 0, 0, 0, 0, 1529, 1530, 1527, - 0, 1525, 0, 0, 1528, 0, 0, 0, 0, 0, - 0, 0, 1531, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1529, 1530, 0, 0, + 0, 0, 0, 1577, 0, 0, 0, 0, 0, 0, + 0, 1581, 1582, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1583, 1589, 0, 0, + 1590, 1591, 1592, 0, 1593, 1594, 1595, 1596, 1597, 1598, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1531, 0, 0, 0, 0, 0, 0, 0, 0, - 1532, 0, 0, 1533, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1513, 0, 1534, 1514, 0, - 1535, 0, 1515, 1516, 1517, 1518, 1519, 1520, 0, 1532, - 1536, 0, 1533, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1521, 0, 1513, 2547, 1534, 1514, 0, 1535, - 1523, 1515, 1526, 0, 1518, 1519, 1520, 1524, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1527, 0, - 0, 0, 0, 1528, 0, 0, 0, 0, 0, 1523, - 0, 0, 1525, 0, 0, 0, 1524, 0, 0, 0, - 0, 1513, 0, 0, 1514, 1529, 1530, 0, 1515, 1516, - 1517, 1518, 1519, 1520, 0, 0, 0, 0, 0, 1536, - 1531, 1525, 0, 0, 0, 0, 0, 0, 1521, 0, - 0, 0, 0, 0, 0, 0, 1523, 0, 0, 0, - 0, 0, 1537, 1524, 0, 1538, 1539, 1540, 1536, 1541, - 1542, 1543, 1544, 1545, 1546, 0, 0, 0, 1532, 0, - 0, 1533, 0, 0, 0, 0, 0, 0, 1525, 0, - 0, 0, 0, 0, 0, 1534, 0, 1513, 1535, 0, - 1514, 0, 0, 0, 1515, 1516, 1517, 1518, 1519, 1520, - 0, 0, 0, 1526, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1521, 0, 0, 0, 0, 1527, - 0, 0, 1523, 0, 1528, 0, 0, 0, 0, 1524, - 0, 1537, 1526, 0, 1538, 1539, 1540, 0, 1541, 1542, - 1543, 1544, 1545, 1546, 0, 0, 1529, 1530, 1527, 0, - 0, 0, 0, 1528, 1525, 0, 0, 0, 0, 0, - 1537, 1531, 0, 1538, 1539, 1540, 0, 1541, 1542, 1543, - 1544, 1545, 1546, 0, 0, -1873, -1873, 1536, 0, 1526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1531, 0, 0, 0, 0, 1527, 0, 0, 0, 1532, - 1528, 0, 1533, 0, 0, 0, 0, 0, 0, 0, - 2537, 0, 0, 0, 0, 0, 1534, 0, 0, 1535, - 0, 0, 1529, 1530, 0, 0, 0, 0, 0, 0, - 0, -1873, 0, 0, 0, 0, 0, 1531, 0, 0, - 0, 0, 0, 0, 0, 1534, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1526, 0, 0, 0, 0, + 0, 0, 0, 0, 1584, 0, 0, 1585, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1527, 0, 0, 0, 1532, 1528, 0, 1533, 1537, - 0, 0, 1538, 1539, 1540, 0, 1541, 1542, 1543, 1544, - 1545, 1546, 1534, 0, 0, 1535, 0, 0, 1529, 1530, - 0, 0, 0, 0, 0, 0, 0, 0, 1536, 0, - 0, 0, 0, 1531, 0, 0, 0, 0, 0, 0, + 0, 1586, 0, 0, 1587, 0, 1578, 0, 0, 1589, + 0, 0, 1590, 1591, 1592, 0, 1593, 1594, 1595, 1596, + 1597, 1598, 1579, 0, 1578, 0, 0, 1580, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1536, 0, 0, + 1579, 0, 0, 0, 0, 1580, 0, 0, 0, 1581, + 1582, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1583, 0, 0, 1581, 1582, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1532, 0, 0, 1533, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1534, 0, - 0, 1535, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1536, 0, 0, 0, 0, 0, + 0, 0, 1583, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1588, 0, 0, 0, 0, 0, + 0, 0, 1584, 0, 0, 1585, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1586, + 1584, 0, 1587, 1585, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1586, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1537, 0, 0, 1538, 1539, 1540, 0, 1541, 1542, 1543, - 1544, 1545, 1546, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1537, - 0, 0, 1538, 1539, 1540, 0, 1541, 1542, 1543, 1544, - 1545, 1546, 0, 0, 0, 0, 0, 0, 0, 0, - 1536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1537, 0, 0, 1538, - 1539, 1540, 0, 1541, 1542, 1543, 1544, 1545, 1546, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1589, 0, 0, + 1590, 1591, 1592, 0, 1593, 1594, 1595, 1596, 2101, 1598, + 0, 0, 1588, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1588, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1202, 0, 1938, - 0, 0, 1537, 0, 0, 1538, 1539, 1540, 0, 1541, - 1542, 1543, 1544, 2042, 1546, 96, 97, 98, 99, 100, - 101, 102, 103, 1203, 104, 105, 106, 1204, 1205, 1206, - 1207, 1208, 1209, 1210, 107, 108, 1211, 109, 110, 111, - 824, 113, 114, 115, 825, 826, 827, 828, 829, 1212, - 121, 122, 123, 124, 125, 126, 1213, 1214, 127, 128, - 830, 831, 131, 1215, 132, 133, 134, 135, 832, 1216, - 833, 1217, 834, 139, 140, 141, 142, 143, 835, 145, - 146, 147, 1218, 148, 149, 150, 151, 152, 153, 1219, - 836, 155, 156, 157, 837, 838, 839, 840, 1220, 1221, - 841, 163, 164, 165, 166, 167, 168, 169, 842, 843, - 172, 1222, 173, 1223, 174, 175, 176, 177, 178, 179, - 1224, 180, 181, 182, 183, 184, 1225, 1226, 185, 186, - 187, 188, 189, 1227, 190, 191, 192, 1228, 193, 194, - 195, 1229, 196, 197, 198, 199, 844, 201, 202, 203, - 204, 205, 845, 1230, 207, 1231, 208, 209, 846, 211, - 1232, 212, 1233, 213, 847, 1234, 848, 216, 217, 849, - 850, 220, 1235, 221, 1236, 851, 852, 224, 1237, 225, - 226, 227, 228, 229, 230, 231, 853, 233, 234, 235, - 236, 1238, 237, 238, 239, 240, 241, 242, 1239, 243, - 854, 855, 246, 247, 248, 249, 250, 856, 857, 1240, - 858, 1241, 254, 859, 860, 257, 861, 259, 260, 261, - 262, 263, 264, 1242, 1243, 265, 862, 267, 863, 1244, - 269, 270, 271, 1245, 1246, 272, 273, 274, 275, 276, - 864, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 865, - 866, 867, 299, 300, 301, 868, 1247, 303, 304, 869, - 306, 1248, 870, 308, 871, 310, 311, 312, 1249, 313, - 314, 1250, 1251, 315, 316, 317, 1252, 1253, 318, 872, - 873, 321, 874, 875, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 1254, 334, 335, 876, 337, 338, - 877, 340, 341, 342, 1255, 343, 344, 345, 346, 347, - 348, 1256, 349, 350, 351, 878, 353, 354, 355, 356, - 1257, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 1258, 370, 371, 879, 373, 374, - 375, 880, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 1259, 388, 389, 390, 391, 392, 881, - 394, 882, 396, 397, 398, 883, 400, 401, 884, 403, - 1260, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 885, 417, 886, 419, 1261, 420, 421, - 1262, 422, 887, 424, 425, 426, 427, 428, 1263, 888, - 889, 1264, 1265, 431, 432, 890, 434, 891, 1266, 436, - 437, 892, 439, 440, 441, 442, 443, 1267, 1268, 444, - 445, 446, 447, 448, 893, 1269, 450, 451, 452, 453, - 454, 1270, 895, 1271, 457, 896, 459, 460, 461, 462, - 463, 1272, 1273, 464, 1274, 1275, 465, 466, 467, 468, - 469, 470, 897, 898, 899, 900, 901, 902, 903, 904, - 905, 906, 907, 482, 483, 484, 485, 1202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 1203, 104, 105, 106, 1204, 1205, 1206, - 1207, 1208, 1209, 1210, 107, 108, 1211, 109, 110, 111, - 824, 113, 114, 115, 825, 826, 827, 828, 829, 1212, - 121, 122, 123, 124, 125, 126, 1213, 1214, 127, 128, - 830, 831, 131, 1215, 132, 133, 134, 135, 832, 1216, - 833, 1217, 834, 139, 140, 141, 142, 143, 835, 145, - 146, 147, 1218, 148, 149, 150, 151, 152, 153, 1219, - 836, 155, 156, 157, 837, 838, 839, 840, 1220, 1221, - 841, 163, 164, 165, 166, 167, 168, 169, 842, 843, - 172, 1222, 173, 1223, 174, 175, 176, 177, 178, 179, - 1224, 180, 181, 182, 183, 184, 1225, 1226, 185, 186, - 187, 188, 189, 1227, 190, 191, 192, 1228, 193, 194, - 195, 1229, 196, 197, 198, 199, 844, 201, 202, 203, - 204, 205, 845, 1230, 207, 1231, 208, 209, 846, 211, - 1232, 212, 1233, 213, 847, 1234, 848, 216, 217, 849, - 850, 220, 1235, 221, 1236, 851, 852, 224, 1237, 225, - 226, 227, 228, 229, 230, 231, 853, 233, 234, 235, - 236, 1238, 237, 238, 239, 240, 241, 242, 1239, 243, - 854, 855, 246, 247, 248, 249, 250, 856, 857, 1240, - 858, 1241, 254, 859, 860, 257, 861, 259, 260, 261, - 262, 263, 264, 1242, 1243, 265, 862, 267, 863, 1244, - 269, 270, 271, 1245, 1246, 272, 273, 274, 275, 276, - 864, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 865, - 866, 867, 299, 300, 301, 868, 1247, 303, 304, 869, - 306, 1248, 870, 308, 871, 310, 311, 312, 1249, 313, - 314, 1250, 1251, 315, 316, 317, 1252, 1253, 318, 872, - 873, 321, 874, 875, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 1254, 334, 335, 876, 337, 338, - 877, 340, 341, 342, 1255, 343, 344, 345, 346, 347, - 348, 1256, 349, 350, 351, 878, 353, 354, 355, 356, - 1257, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 1258, 370, 371, 879, 373, 374, - 375, 880, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 1259, 388, 389, 390, 391, 392, 881, - 394, 882, 396, 397, 398, 883, 400, 401, 884, 403, - 1260, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 885, 417, 886, 419, 1261, 420, 421, - 1262, 422, 887, 424, 425, 426, 427, 428, 1263, 888, - 889, 1264, 1265, 431, 432, 890, 434, 891, 1266, 436, - 437, 892, 439, 440, 441, 442, 443, 1267, 1268, 444, - 445, 446, 447, 448, 893, 1269, 450, 451, 452, 453, - 454, 1270, 895, 1271, 457, 896, 459, 460, 461, 462, - 463, 1272, 1273, 464, 1274, 1275, 465, 466, 467, 468, - 469, 470, 897, 898, 899, 900, 901, 902, 903, 904, - 905, 906, 907, 482, 483, 484, 485, 1202, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 2078, - 101, 102, 103, 1203, 104, 105, 106, 1204, 1205, 1206, - 1207, 1208, 1209, 1210, 107, 108, 1211, 109, 110, 111, - 824, 113, 114, 115, 825, 826, 827, 828, 829, 1212, - 121, 122, 123, 124, 125, 126, 1213, 1214, 127, 128, - 830, 831, 131, 1215, 132, 133, 134, 135, 832, 1216, - 833, 1217, 834, 139, 140, 141, 142, 143, 835, 145, - 146, 147, 1218, 148, 149, 150, 151, 152, 153, 1219, - 836, 155, 156, 157, 837, 838, 839, 840, 1220, 1221, - 841, 163, 164, 165, 166, 167, 168, 169, 842, 843, - 172, 1222, 173, 1223, 174, 175, 176, 177, 178, 179, - 1224, 180, 181, 182, 183, 184, 1225, 1226, 185, 186, - 187, 2079, 189, 1227, 190, 191, 192, 1228, 193, 194, - 195, 1229, 196, 197, 198, 199, 844, 201, 202, 203, - 204, 205, 845, 1230, 207, 1231, 208, 209, 846, 211, - 1232, 212, 1233, 213, 847, 1234, 848, 216, 217, 849, - 850, 220, 1235, 221, 1236, 851, 852, 224, 1237, 225, - 226, 227, 228, 229, 230, 231, 853, 233, 234, 235, - 236, 1238, 237, 238, 239, 240, 241, 242, 1239, 243, - 854, 855, 246, 247, 248, 249, 250, 856, 857, 1240, - 858, 1241, 254, 859, 860, 257, 861, 259, 260, 261, - 262, 263, 264, 1242, 1243, 265, 862, 267, 863, 1244, - 269, 270, 271, 1245, 1246, 272, 273, 274, 275, 276, - 864, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 865, - 866, 867, 299, 300, 301, 868, 1247, 303, 304, 869, - 306, 1248, 870, 308, 871, 310, 311, 312, 1249, 313, - 314, 1250, 1251, 315, 316, 317, 1252, 1253, 318, 872, - 873, 321, 874, 875, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 1254, 334, 335, 876, 337, 338, - 877, 340, 341, 342, 1255, 343, 344, 345, 346, 347, - 348, 1256, 349, 350, 351, 878, 353, 354, 355, 356, - 1257, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 1258, 370, 371, 879, 373, 374, - 375, 880, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 1259, 388, 389, 390, 391, 392, 881, - 2080, 882, 396, 397, 398, 883, 400, 401, 884, 403, - 1260, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 885, 417, 886, 419, 1261, 420, 421, - 1262, 422, 887, 424, 425, 426, 427, 428, 1263, 888, - 889, 1264, 1265, 431, 432, 890, 434, 891, 1266, 436, - 437, 892, 439, 440, 441, 442, 443, 1267, 1268, 444, - 445, 446, 447, 448, 893, 1269, 450, 451, 452, 453, - 454, 1270, 895, 1271, 457, 896, 459, 460, 461, 462, - 463, 1272, 1273, 464, 1274, 1275, 465, 466, 467, 468, - 469, 470, 897, 898, 899, 900, 901, 902, 903, 904, - 905, 906, 907, 482, 483, 484, 485, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 583, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 584, 0, - 585, 0, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 154, 155, 156, 157, 586, 587, 588, 589, 590, 591, - 592, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 593, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 214, 0, 215, 216, 217, 218, - 219, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 244, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 266, 267, 268, 0, - 269, 270, 271, 595, 596, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 0, 303, 304, 305, - 306, 0, 597, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 320, 321, 322, 599, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 600, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 602, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 416, 417, 603, 419, 0, 420, 421, - 0, 422, 423, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 604, 434, 605, 0, 436, - 437, 606, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 607, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 458, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 823, 0, 624, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 824, 113, 114, 115, 825, 826, 827, 828, 829, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 830, 831, 131, 0, 132, 133, 134, 135, 832, 0, - 833, 0, 834, 139, 140, 141, 142, 143, 835, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 836, 155, 156, 157, 837, 838, 839, 840, 0, 0, - 841, 163, 164, 165, 166, 167, 168, 169, 842, 843, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 844, 201, 202, 203, - 204, 205, 845, 1378, 207, 0, 208, 209, 846, 211, - 0, 212, 0, 213, 847, 0, 848, 216, 217, 849, - 850, 220, 0, 221, 0, 851, 852, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 853, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 854, 855, 246, 247, 248, 249, 250, 856, 857, 0, - 858, 0, 254, 859, 860, 257, 861, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 862, 267, 863, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 864, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 865, - 866, 867, 299, 300, 301, 868, 0, 303, 304, 869, - 306, 0, 870, 308, 871, 310, 311, 312, 0, 313, - 314, 1379, 0, 315, 316, 317, 0, 0, 318, 872, - 873, 321, 874, 875, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 876, 337, 338, - 877, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 878, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 879, 373, 374, - 375, 880, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 881, - 394, 882, 396, 397, 398, 883, 400, 401, 884, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 885, 417, 886, 419, 0, 420, 421, - 0, 422, 887, 424, 425, 426, 427, 428, 0, 888, - 889, 0, 0, 431, 432, 890, 434, 891, 1380, 436, - 437, 892, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 893, 0, 450, 451, 452, 453, - 454, 1270, 895, 0, 457, 896, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 897, 898, 899, 900, 901, 902, 903, 904, - 905, 906, 907, 482, 483, 484, 485, 823, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 3, 4, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 824, 113, 114, 115, 825, 826, 827, 828, 829, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 830, 831, 131, 0, 132, 133, 134, 135, 832, 0, - 833, 0, 834, 139, 140, 141, 142, 143, 835, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 836, 155, 156, 157, 837, 838, 839, 840, 0, 0, - 841, 163, 164, 165, 166, 167, 168, 169, 842, 843, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 844, 201, 202, 203, - 204, 205, 845, 0, 207, 0, 208, 209, 846, 211, - 0, 212, 0, 213, 847, 0, 848, 216, 217, 849, - 850, 220, 0, 221, 0, 851, 852, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 853, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 854, 855, 246, 247, 248, 249, 250, 856, 857, 0, - 858, 0, 254, 859, 860, 257, 861, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 862, 267, 863, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 864, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 865, - 866, 867, 299, 300, 301, 868, 0, 303, 304, 869, - 306, 0, 870, 308, 871, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 872, - 873, 321, 874, 875, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 876, 337, 338, - 877, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 878, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 879, 373, 374, - 375, 880, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 881, - 394, 882, 396, 397, 398, 883, 400, 401, 884, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 885, 417, 886, 419, 0, 420, 421, - 0, 422, 887, 424, 425, 426, 427, 428, 0, 888, - 889, 0, 0, 431, 432, 890, 434, 891, 0, 436, - 437, 892, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 893, 0, 450, 451, 452, 453, - 454, 1270, 895, 0, 457, 896, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 897, 898, 899, 900, 901, 902, 903, 904, - 905, 906, 907, 482, 483, 484, 485, 95, 0, 0, + 0, 0, 0, 0, 0, 1589, 0, 0, 1590, 1591, + 1592, 0, 1593, 1594, 1595, 1596, 1597, 1598, 1244, 0, + 2000, 0, 0, 1589, 0, 0, 1590, 1591, 1592, 0, + 1593, 1594, 1595, 1596, 1597, 1598, 105, 106, 107, 108, + 109, 110, 111, 112, 1245, 113, 114, 115, 1246, 1247, + 1248, 1249, 1250, 1251, 1252, 116, 117, 1253, 118, 119, + 120, 856, 122, 123, 124, 857, 858, 859, 860, 861, + 1254, 130, 131, 132, 133, 134, 135, 1255, 1256, 136, + 137, 862, 863, 140, 1257, 141, 142, 143, 144, 864, + 1258, 865, 1259, 866, 148, 149, 150, 151, 152, 867, + 154, 155, 156, 1260, 157, 158, 159, 160, 161, 162, + 1261, 868, 164, 165, 166, 869, 870, 871, 872, 1262, + 1263, 873, 172, 173, 174, 175, 176, 177, 178, 874, + 875, 181, 1264, 182, 1265, 183, 184, 185, 186, 187, + 188, 1266, 189, 190, 191, 192, 193, 1267, 1268, 194, + 195, 196, 197, 198, 1269, 199, 200, 201, 1270, 202, + 203, 204, 1271, 205, 206, 207, 208, 876, 210, 211, + 212, 213, 214, 877, 1272, 216, 1273, 217, 218, 878, + 220, 1274, 221, 1275, 222, 879, 1276, 880, 225, 226, + 881, 882, 229, 1277, 230, 1278, 883, 884, 233, 1279, + 234, 235, 236, 237, 238, 239, 240, 885, 242, 243, + 244, 245, 1280, 246, 247, 248, 249, 250, 251, 1281, + 252, 886, 887, 255, 256, 257, 258, 259, 888, 889, + 1282, 890, 1283, 263, 891, 892, 266, 893, 268, 269, + 270, 271, 272, 273, 1284, 1285, 274, 894, 276, 895, + 1286, 278, 279, 280, 1287, 1288, 281, 282, 283, 284, + 285, 896, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 897, 898, 899, 308, 309, 310, 900, 1289, 312, 313, + 901, 315, 1290, 902, 317, 903, 319, 320, 321, 1291, + 322, 323, 1292, 1293, 324, 325, 326, 1294, 1295, 327, + 904, 905, 330, 906, 907, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 1296, 343, 344, 908, 909, + 347, 348, 910, 350, 351, 352, 1297, 353, 354, 355, + 356, 357, 358, 1298, 359, 360, 361, 911, 363, 364, + 365, 366, 1299, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 1300, 380, 381, 912, + 383, 384, 385, 913, 387, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 1301, 398, 399, 400, 401, + 402, 914, 404, 915, 406, 407, 408, 916, 410, 411, + 917, 413, 1302, 414, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 425, 918, 427, 919, 429, 1303, + 430, 431, 1304, 432, 920, 434, 435, 436, 437, 438, + 1305, 921, 922, 1306, 1307, 441, 442, 923, 444, 924, + 1308, 446, 447, 925, 449, 450, 451, 452, 453, 1309, + 1310, 454, 455, 456, 457, 458, 459, 926, 1311, 461, + 462, 463, 464, 465, 1312, 928, 1313, 468, 929, 470, + 471, 472, 473, 474, 1314, 1315, 475, 1316, 1317, 476, + 477, 478, 479, 480, 481, 930, 931, 932, 933, 934, + 935, 936, 937, 938, 939, 940, 493, 494, 495, 496, + 1244, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 105, 106, + 107, 108, 109, 110, 111, 112, 1245, 113, 114, 115, + 1246, 1247, 1248, 1249, 1250, 1251, 1252, 116, 117, 1253, + 118, 119, 120, 856, 122, 123, 124, 857, 858, 859, + 860, 861, 1254, 130, 131, 132, 133, 134, 135, 1255, + 1256, 136, 137, 862, 863, 140, 1257, 141, 142, 143, + 144, 864, 1258, 865, 1259, 866, 148, 149, 150, 151, + 152, 867, 154, 155, 156, 1260, 157, 158, 159, 160, + 161, 162, 1261, 868, 164, 165, 166, 869, 870, 871, + 872, 1262, 1263, 873, 172, 173, 174, 175, 176, 177, + 178, 874, 875, 181, 1264, 182, 1265, 183, 184, 185, + 186, 187, 188, 1266, 189, 190, 191, 192, 193, 1267, + 1268, 194, 195, 196, 197, 198, 1269, 199, 200, 201, + 1270, 202, 203, 204, 1271, 205, 206, 207, 208, 876, + 210, 211, 212, 213, 214, 877, 1272, 216, 1273, 217, + 218, 878, 220, 1274, 221, 1275, 222, 879, 1276, 880, + 225, 226, 881, 882, 229, 1277, 230, 1278, 883, 884, + 233, 1279, 234, 235, 236, 237, 238, 239, 240, 885, + 242, 243, 244, 245, 1280, 246, 247, 248, 249, 250, + 251, 1281, 252, 886, 887, 255, 256, 257, 258, 259, + 888, 889, 1282, 890, 1283, 263, 891, 892, 266, 893, + 268, 269, 270, 271, 272, 273, 1284, 1285, 274, 894, + 276, 895, 1286, 278, 279, 280, 1287, 1288, 281, 282, + 283, 284, 285, 896, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 897, 898, 899, 308, 309, 310, 900, 1289, + 312, 313, 901, 315, 1290, 902, 317, 903, 319, 320, + 321, 1291, 322, 323, 1292, 1293, 324, 325, 326, 1294, + 1295, 327, 904, 905, 330, 906, 907, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 1296, 343, 344, + 908, 909, 347, 348, 910, 350, 351, 352, 1297, 353, + 354, 355, 356, 357, 358, 1298, 359, 360, 361, 911, + 363, 364, 365, 366, 1299, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 1300, 380, + 381, 912, 383, 384, 385, 913, 387, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 1301, 398, 399, + 400, 401, 402, 914, 404, 915, 406, 407, 408, 916, + 410, 411, 917, 413, 1302, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 918, 427, 919, + 429, 1303, 430, 431, 1304, 432, 920, 434, 435, 436, + 437, 438, 1305, 921, 922, 1306, 1307, 441, 442, 923, + 444, 924, 1308, 446, 447, 925, 449, 450, 451, 452, + 453, 1309, 1310, 454, 455, 456, 457, 458, 459, 926, + 1311, 461, 462, 463, 464, 465, 1312, 928, 1313, 468, + 929, 470, 471, 472, 473, 474, 1314, 1315, 475, 1316, + 1317, 476, 477, 478, 479, 480, 481, 930, 931, 932, + 933, 934, 935, 936, 937, 938, 939, 940, 493, 494, + 495, 496, 1244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 137, 0, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 154, 155, 156, 157, 158, 159, 160, 161, 0, 0, - 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 214, 0, 215, 216, 217, 218, - 219, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 244, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 266, 267, 268, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 0, 303, 304, 305, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 393, - 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 416, 417, 418, 419, 0, 420, 421, - 0, 422, 423, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 449, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 458, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 0, + 105, 106, 107, 108, 2137, 110, 111, 112, 1245, 113, + 114, 115, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 116, + 117, 1253, 118, 119, 120, 856, 122, 123, 124, 857, + 858, 859, 860, 861, 1254, 130, 131, 132, 133, 134, + 135, 1255, 1256, 136, 137, 862, 863, 140, 1257, 141, + 142, 143, 144, 864, 1258, 865, 1259, 866, 148, 149, + 150, 151, 152, 867, 154, 155, 156, 1260, 157, 158, + 159, 160, 161, 162, 1261, 868, 164, 165, 166, 869, + 870, 871, 872, 1262, 1263, 873, 172, 173, 174, 175, + 176, 177, 178, 874, 875, 181, 1264, 182, 1265, 183, + 184, 185, 186, 187, 188, 1266, 189, 190, 191, 192, + 193, 1267, 1268, 194, 195, 196, 2138, 198, 1269, 199, + 200, 201, 1270, 202, 203, 204, 1271, 205, 206, 207, + 208, 876, 210, 211, 212, 213, 214, 877, 1272, 216, + 1273, 217, 218, 878, 220, 1274, 221, 1275, 222, 879, + 1276, 880, 225, 226, 881, 882, 229, 1277, 230, 1278, + 883, 884, 233, 1279, 234, 235, 236, 237, 238, 239, + 240, 885, 242, 243, 244, 245, 1280, 246, 247, 248, + 249, 250, 251, 1281, 252, 886, 887, 255, 256, 257, + 258, 259, 888, 889, 1282, 890, 1283, 263, 891, 892, + 266, 893, 268, 269, 270, 271, 272, 273, 1284, 1285, + 274, 894, 276, 895, 1286, 278, 279, 280, 1287, 1288, + 281, 282, 283, 284, 285, 896, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 897, 898, 899, 308, 309, 310, + 900, 1289, 312, 313, 901, 315, 1290, 902, 317, 903, + 319, 320, 321, 1291, 322, 323, 1292, 1293, 324, 325, + 326, 1294, 1295, 327, 904, 905, 330, 906, 907, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 1296, + 343, 344, 908, 909, 347, 348, 910, 350, 351, 352, + 1297, 353, 354, 355, 356, 357, 358, 1298, 359, 360, + 361, 911, 363, 364, 365, 366, 1299, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 1300, 380, 381, 912, 383, 384, 385, 913, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 1301, + 398, 399, 400, 401, 402, 914, 2139, 915, 406, 407, + 408, 916, 410, 411, 917, 413, 1302, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 918, + 427, 919, 429, 1303, 430, 431, 1304, 432, 920, 434, + 435, 436, 437, 438, 1305, 921, 922, 1306, 1307, 441, + 442, 923, 444, 924, 1308, 446, 447, 925, 449, 450, + 451, 452, 453, 1309, 1310, 454, 455, 456, 457, 458, + 459, 926, 1311, 461, 462, 463, 464, 465, 1312, 928, + 1313, 468, 929, 470, 471, 472, 473, 474, 1314, 1315, + 475, 1316, 1317, 476, 477, 478, 479, 480, 481, 930, + 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, + 493, 494, 495, 496, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 1637, 132, 133, 134, 135, 136, 0, - 0, 1638, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 1639, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 1640, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 1641, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 1642, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 1643, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 0, + 0, 0, 105, 106, 107, 108, 109, 110, 111, 112, + 0, 113, 114, 115, 0, 0, 0, 0, 0, 0, + 0, 116, 117, 0, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 0, 130, 131, 132, + 133, 134, 135, 0, 606, 136, 137, 138, 139, 140, + 0, 141, 142, 143, 144, 607, 0, 608, 0, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 0, + 157, 158, 159, 160, 161, 162, 0, 163, 164, 165, + 166, 609, 610, 611, 612, 613, 614, 615, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 0, 182, + 0, 183, 184, 185, 186, 187, 188, 0, 189, 190, + 191, 192, 193, 0, 0, 194, 195, 196, 197, 198, + 0, 199, 200, 201, 0, 202, 203, 204, 0, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 616, + 0, 216, 0, 217, 218, 219, 220, 0, 221, 0, + 222, 223, 0, 224, 225, 226, 227, 228, 229, 0, + 230, 0, 231, 232, 233, 0, 234, 235, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 0, 246, + 247, 248, 249, 250, 251, 0, 252, 253, 254, 255, + 256, 257, 258, 259, 260, 261, 0, 262, 0, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 0, 0, 274, 275, 276, 277, 0, 278, 279, 280, + 618, 619, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 0, 312, 313, 314, 315, 0, 620, + 317, 318, 319, 320, 321, 0, 322, 323, 0, 0, + 324, 325, 326, 0, 0, 327, 328, 329, 330, 331, + 622, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 0, 343, 344, 623, 346, 347, 348, 349, 350, + 351, 352, 0, 353, 354, 355, 356, 357, 358, 0, + 359, 360, 361, 362, 363, 364, 365, 366, 0, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 0, 380, 381, 382, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 0, 398, 399, 400, 401, 402, 625, 404, 405, + 406, 407, 408, 409, 410, 411, 412, 413, 0, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 426, 427, 626, 429, 0, 430, 431, 0, 432, + 433, 434, 435, 436, 437, 438, 0, 439, 440, 0, + 0, 441, 442, 627, 444, 628, 0, 446, 447, 629, + 449, 450, 451, 452, 453, 0, 0, 454, 455, 456, + 457, 458, 459, 630, 0, 461, 462, 463, 464, 465, + 466, 467, 0, 468, 469, 470, 471, 472, 473, 474, + 0, 0, 475, 0, 0, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, + 491, 492, 493, 494, 495, 496, 855, 0, 515, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 1637, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 1639, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 1640, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 2150, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 0, 0, 0, 0, 105, 106, 107, 108, 109, 110, + 111, 112, 0, 113, 114, 115, 0, 0, 0, 0, + 0, 0, 0, 116, 117, 0, 118, 119, 120, 856, + 122, 123, 124, 857, 858, 859, 860, 861, 0, 130, + 131, 132, 133, 134, 135, 0, 0, 136, 137, 862, + 863, 140, 0, 141, 142, 143, 144, 864, 0, 865, + 0, 866, 148, 149, 150, 151, 152, 867, 154, 155, + 156, 0, 157, 158, 159, 160, 161, 162, 0, 868, + 164, 165, 166, 869, 870, 871, 872, 0, 0, 873, + 172, 173, 174, 175, 176, 177, 178, 874, 875, 181, + 0, 182, 0, 183, 184, 185, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 0, 0, 194, 195, 196, + 197, 198, 0, 199, 200, 201, 0, 202, 203, 204, + 0, 205, 206, 207, 208, 876, 210, 211, 212, 213, + 214, 877, 1428, 216, 0, 217, 218, 878, 220, 0, + 221, 0, 222, 879, 0, 880, 225, 226, 881, 882, + 229, 0, 230, 0, 883, 884, 233, 0, 234, 235, + 236, 237, 238, 239, 240, 885, 242, 243, 244, 245, + 0, 246, 247, 248, 249, 250, 251, 0, 252, 886, + 887, 255, 256, 257, 258, 259, 888, 889, 0, 890, + 0, 263, 891, 892, 266, 893, 268, 269, 270, 271, + 272, 273, 0, 0, 274, 894, 276, 895, 0, 278, + 279, 280, 0, 0, 281, 282, 283, 284, 285, 896, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 1642, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 1643, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 735, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, -680, 0, 107, 108, 0, 109, 110, 111, - 736, 113, 114, 115, 0, 737, 738, 739, 740, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 741, 742, 131, 0, 132, 133, 134, 135, 0, 0, - 743, 0, 744, 139, 140, 141, 142, 143, 745, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 746, 155, 156, 157, 747, 748, 749, 750, 0, 0, - 751, 163, 164, 165, 166, 167, 168, 169, 752, 753, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 754, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 0, 201, 202, 203, - 204, 205, 0, 0, 207, 0, 208, 209, 755, 211, - 0, 212, 0, 213, 756, 0, 757, 216, 217, -680, - 758, 220, 0, 221, 0, 0, 0, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 760, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 761, 0, 246, 247, 248, 249, 250, 762, 763, 0, - 764, 0, 254, 765, 766, 257, 767, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 768, 267, 769, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 770, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 771, - 772, 773, 299, 300, 301, 0, 0, 303, 304, 774, - 306, 0, 0, 308, 775, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 0, - 776, 321, 777, 0, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 0, 337, 338, - 0, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 778, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 779, 373, 374, - 375, 780, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 781, - 394, 782, 396, 397, 398, 783, 400, 401, 784, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 785, 417, 0, 419, 0, 420, 421, - 0, 422, 786, 424, 425, 426, 427, 428, 0, 787, - 788, 0, 0, 431, 432, 0, 434, 0, 0, 436, - 437, 789, 439, 440, 441, 442, 443, 790, 0, 444, - 445, 446, 447, 448, 791, 0, 450, 451, 452, 453, - 454, 0, 792, 0, 457, 793, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 508, 0, 509, 0, 0, 0, 0, 0, - 0, 0, 0, 482, 483, 484, 485, 0, 0, 0, - 96, 97, 98, 99, 100, 101, 102, 103, 0, 104, - 105, 106, 3, 4, 0, 0, 0, 0, 0, 107, - 108, 0, 109, 110, 111, 0, 113, 114, 115, 116, - 117, 0, 119, 120, 0, 121, 122, 123, 124, 125, - 126, 0, 0, 127, 128, 129, 130, 131, 0, 132, - 133, 134, 135, 136, 0, 0, 0, 138, 139, 140, - 141, 142, 143, 0, 145, 146, 147, 0, 148, 149, - 150, 151, 152, 153, 0, 0, 155, 156, 157, 0, - 0, 0, 0, 0, 0, 0, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 0, 173, 0, 174, - 175, 176, 177, 178, 179, 0, 180, 181, 182, 183, - 184, 0, 0, 185, 186, 187, 188, 189, 0, 190, - 191, 192, 0, 193, 194, 195, 0, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 0, 207, - 0, 208, 209, 210, 211, 0, 212, 0, 213, 0, - 0, 0, 216, 217, 511, 0, 220, 0, 221, 0, - 222, 223, 224, 0, 225, 226, 227, 228, 229, 230, - 231, 0, 233, 234, 235, 236, 0, 237, 238, 239, - 240, 241, 242, 0, 243, 0, 245, 246, 247, 248, - 249, 250, 251, 252, 0, 253, 0, 254, 0, 0, - 257, 0, 259, 260, 261, 262, 263, 264, 0, 0, - 265, 0, 267, 0, 0, 269, 270, 271, 0, 0, - 272, 273, 274, 275, 276, 512, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, 293, 294, 295, 296, 0, 298, 299, 300, 301, - 302, 0, 303, 304, 0, 306, 0, 307, 308, 309, - 310, 311, 312, 0, 313, 314, 0, 0, 315, 316, - 317, 0, 0, 318, 319, 0, 321, 0, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 0, - 334, 335, 336, 337, 338, 339, 340, 341, 342, 0, - 343, 344, 345, 346, 347, 348, 0, 349, 350, 351, - 352, 353, 354, 355, 356, 0, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, 369, 0, - 370, 371, 0, 373, 374, 375, 376, 377, 378, 379, - 380, 381, 382, 383, 384, 385, 386, 387, 0, 388, - 389, 390, 391, 392, 0, 394, 395, 396, 397, 398, - 0, 400, 401, 402, 403, 0, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 514, 417, - 418, 419, 0, 420, 421, 0, 422, 0, 424, 425, - 426, 427, 428, 0, 429, 430, 0, 0, 431, 432, - 433, 434, 435, 0, 436, 437, 438, 439, 440, 441, - 442, 443, 0, 0, 444, 445, 446, 447, 448, 0, - 0, 450, 451, 452, 453, 454, 455, 456, 0, 457, - 0, 459, 460, 461, 462, 463, 0, 0, 464, 0, - 0, 465, 466, 467, 468, 469, 470, 471, 472, 473, - 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, - 484, 485, 508, 0, 509, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 96, 97, 98, 99, 100, 101, 102, 103, 510, 104, - 105, 106, 0, 0, 0, 0, 0, 0, 0, 107, - 108, 0, 109, 110, 111, 0, 113, 114, 115, 116, - 117, 0, 119, 120, 0, 121, 122, 123, 124, 125, - 126, 0, 0, 127, 128, 129, 130, 131, 0, 132, - 133, 134, 135, 136, 0, 0, 0, 138, 139, 140, - 141, 142, 143, 0, 145, 146, 147, 0, 148, 149, - 150, 151, 152, 153, 0, 0, 155, 156, 157, 0, - 0, 0, 0, 0, 0, 0, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 0, 173, 0, 174, - 175, 176, 177, 178, 179, 0, 180, 181, 182, 183, - 184, 0, 0, 185, 186, 187, 188, 189, 0, 190, - 191, 192, 0, 193, 194, 195, 0, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 0, 207, - 0, 208, 209, 210, 211, 0, 212, 0, 213, 0, - 0, 0, 216, 217, 511, 0, 220, 0, 221, 0, - 222, 223, 224, 0, 225, 226, 227, 228, 229, 230, - 231, 0, 233, 234, 235, 236, 0, 237, 238, 239, - 240, 241, 242, 0, 243, 0, 245, 246, 247, 248, - 249, 250, 251, 252, 0, 253, 0, 254, 0, 0, - 257, 0, 259, 260, 261, 262, 263, 264, 0, 0, - 265, 0, 267, 0, 0, 269, 270, 271, 0, 0, - 272, 273, 274, 275, 276, 512, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, 293, 294, 295, 296, 0, 298, 299, 300, 301, - 302, 0, 303, 304, 0, 306, 0, 307, 308, 309, - 310, 311, 312, 0, 313, 314, 0, 0, 315, 316, - 317, 0, 0, 318, 319, 0, 321, 0, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 0, - 334, 335, 336, 337, 338, 339, 513, 341, 342, 0, - 343, 344, 345, 346, 347, 348, 0, 349, 350, 351, - 352, 353, 354, 355, 356, 0, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, 369, 0, - 370, 371, 0, 373, 374, 375, 376, 377, 378, 379, - 380, 381, 382, 383, 384, 385, 386, 387, 0, 388, - 389, 390, 391, 392, 0, 394, 395, 396, 397, 398, - 0, 400, 401, 402, 403, 0, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 514, 417, - 418, 419, 0, 420, 421, 0, 422, 0, 424, 425, - 426, 427, 428, 0, 429, 430, 0, 0, 431, 432, - 433, 434, 435, 0, 436, 437, 438, 439, 440, 441, - 442, 443, 0, 0, 444, 445, 446, 447, 448, 0, - 0, 450, 451, 452, 453, 454, 455, 456, 0, 457, - 0, 459, 460, 461, 462, 463, 0, 0, 464, 0, - 0, 465, 466, 467, 468, 469, 470, 471, 472, 473, - 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, - 484, 485, 508, 0, 509, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 96, 97, 98, 99, 100, 101, 102, 103, 0, 104, - 105, 106, 0, 0, 0, 0, 0, 0, 0, 107, - 108, 0, 109, 110, 111, 0, 113, 114, 115, 116, - 117, 0, 119, 120, 0, 121, 122, 123, 124, 125, - 126, 0, 0, 127, 128, 129, 130, 131, 0, 132, - 133, 134, 135, 136, 0, 0, 0, 138, 139, 140, - 141, 142, 143, 0, 145, 146, 147, 0, 148, 149, - 150, 151, 152, 153, 0, 0, 155, 156, 157, 0, - 0, 0, 0, 0, 0, 0, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 0, 173, 0, 174, - 175, 176, 177, 178, 179, 0, 180, 181, 182, 183, - 184, 0, 0, 185, 186, 187, 188, 189, 0, 190, - 191, 192, 0, 193, 194, 195, 0, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 0, 207, - 0, 208, 209, 210, 211, 0, 212, 0, 213, 0, - 0, 0, 216, 217, 511, 0, 220, 0, 221, 0, - 222, 223, 224, 0, 225, 226, 227, 228, 229, 230, - 231, 0, 233, 234, 235, 236, 0, 237, 238, 239, - 240, 241, 242, 0, 243, 0, 245, 246, 247, 248, - 249, 250, 251, 252, 0, 253, 0, 254, 0, 0, - 257, 0, 259, 260, 261, 262, 263, 264, 0, 0, - 265, 0, 267, 0, 0, 269, 270, 271, 0, 0, - 272, 273, 274, 275, 276, 512, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, 293, 294, 295, 296, 0, 298, 299, 300, 301, - 302, 0, 303, 304, 0, 306, 0, 307, 308, 309, - 310, 311, 312, 0, 313, 314, 0, 598, 315, 316, - 317, 0, 0, 318, 319, 0, 321, 0, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 0, - 334, 335, 336, 337, 338, 339, 340, 341, 342, 0, - 343, 344, 345, 346, 347, 348, 0, 349, 350, 351, - 352, 353, 354, 355, 356, 0, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, 369, 0, - 370, 371, 0, 373, 374, 375, 376, 377, 378, 379, - 380, 381, 382, 383, 384, 385, 386, 387, 0, 388, - 389, 390, 391, 392, 0, 394, 395, 396, 397, 398, - 0, 400, 401, 402, 403, 0, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 514, 417, - 418, 419, 0, 420, 421, 0, 422, 0, 424, 425, - 426, 427, 428, 0, 429, 430, 0, 0, 431, 432, - 433, 434, 435, 0, 436, 437, 438, 439, 440, 441, - 442, 443, 0, 0, 444, 445, 446, 447, 448, 0, - 0, 450, 451, 452, 453, 454, 455, 456, 0, 457, - 0, 459, 460, 461, 462, 463, 0, 0, 464, 0, - 0, 465, 466, 467, 468, 469, 470, 471, 472, 473, - 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, - 484, 485, 508, 0, 509, 0, 0, 0, 0, 0, + 297, 298, 299, 300, 301, 302, 303, 304, 897, 898, + 899, 308, 309, 310, 900, 0, 312, 313, 901, 315, + 0, 902, 317, 903, 319, 320, 321, 0, 322, 323, + 1429, 0, 324, 325, 326, 0, 0, 327, 904, 905, + 330, 906, 907, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 0, 343, 344, 908, 909, 347, 348, + 910, 350, 351, 352, 0, 353, 354, 355, 356, 357, + 358, 0, 359, 360, 361, 911, 363, 364, 365, 366, + 0, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 0, 380, 381, 912, 383, 384, + 385, 913, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 0, 398, 399, 400, 401, 402, 914, + 404, 915, 406, 407, 408, 916, 410, 411, 917, 413, + 0, 414, 415, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 425, 918, 427, 919, 429, 0, 430, 431, + 0, 432, 920, 434, 435, 436, 437, 438, 0, 921, + 922, 0, 0, 441, 442, 923, 444, 924, 1430, 446, + 447, 925, 449, 450, 451, 452, 453, 0, 0, 454, + 455, 456, 457, 458, 459, 926, 0, 461, 462, 463, + 464, 465, 1312, 928, 0, 468, 929, 470, 471, 472, + 473, 474, 0, 0, 475, 0, 0, 476, 477, 478, + 479, 480, 481, 930, 931, 932, 933, 934, 935, 936, + 937, 938, 939, 940, 493, 494, 495, 496, 855, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 96, 97, 98, 99, 100, 101, 102, 103, 0, 104, - 105, 106, 0, 0, 0, 0, 0, 0, 0, 107, - 108, 0, 109, 110, 111, 0, 113, 114, 115, 116, - 117, 0, 119, 120, 0, 121, 122, 123, 124, 125, - 126, 0, 0, 127, 128, 129, 130, 131, 0, 132, - 133, 134, 135, 136, 0, 0, 0, 138, 139, 140, - 141, 142, 143, 0, 145, 146, 147, 0, 148, 149, - 150, 151, 152, 153, 0, 0, 155, 156, 157, 0, - 0, 0, 0, 0, 0, 0, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 0, 173, 0, 174, - 175, 176, 177, 178, 179, 0, 180, 181, 182, 183, - 184, 0, 0, 185, 186, 187, 188, 189, 0, 190, - 191, 192, 0, 193, 194, 195, 0, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 0, 207, - 0, 208, 209, 210, 211, 0, 212, 0, 213, 0, - 0, 0, 216, 217, 511, 0, 220, 0, 221, 0, - 222, 223, 224, 0, 225, 226, 227, 228, 229, 698, - 231, 0, 233, 234, 235, 236, 0, 237, 238, 239, - 240, 241, 242, 0, 243, 0, 245, 246, 247, 248, - 249, 250, 251, 252, 0, 253, 0, 254, 0, 0, - 257, 0, 259, 260, 261, 262, 263, 264, 0, 0, - 265, 0, 267, 0, 0, 269, 270, 271, 0, 0, - 272, 273, 274, 275, 276, 512, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, 293, 294, 295, 296, 0, 298, 299, 300, 301, - 302, 0, 303, 304, 0, 306, 0, 307, 308, 309, - 310, 311, 312, 0, 313, 314, 0, 598, 315, 316, - 317, 0, 0, 318, 319, 0, 321, 0, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 0, - 334, 335, 336, 337, 338, 339, 340, 341, 342, 0, - 343, 344, 345, 346, 347, 348, 0, 349, 350, 351, - 352, 353, 354, 355, 356, 0, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, 369, 0, - 370, 371, 0, 373, 374, 375, 376, 377, 378, 379, - 380, 381, 382, 383, 384, 385, 386, 387, 0, 388, - 389, 390, 391, 392, 0, 394, 395, 396, 397, 398, - 0, 400, 401, 402, 403, 0, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 514, 417, - 418, 419, 0, 420, 421, 0, 422, 0, 424, 425, - 426, 427, 428, 0, 429, 430, 0, 0, 431, 432, - 433, 434, 435, 0, 436, 437, 438, 439, 440, 441, - 442, 443, 0, 0, 444, 445, 446, 447, 448, 0, - 0, 450, 451, 452, 453, 454, 455, 456, 0, 457, - 0, 459, 460, 461, 462, 463, 0, 0, 464, 0, - 0, 465, 466, 467, 468, 469, 470, 471, 472, 473, - 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, - 484, 485, 508, 0, 509, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 105, 106, 107, 108, + 109, 110, 111, 112, 0, 113, 114, 115, 3, 4, + 0, 0, 0, 0, 0, 116, 117, 0, 118, 119, + 120, 856, 122, 123, 124, 857, 858, 859, 860, 861, + 0, 130, 131, 132, 133, 134, 135, 0, 0, 136, + 137, 862, 863, 140, 0, 141, 142, 143, 144, 864, + 0, 865, 0, 866, 148, 149, 150, 151, 152, 867, + 154, 155, 156, 0, 157, 158, 159, 160, 161, 162, + 0, 868, 164, 165, 166, 869, 870, 871, 872, 0, + 0, 873, 172, 173, 174, 175, 176, 177, 178, 874, + 875, 181, 0, 182, 0, 183, 184, 185, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 0, 0, 194, + 195, 196, 197, 198, 0, 199, 200, 201, 0, 202, + 203, 204, 0, 205, 206, 207, 208, 876, 210, 211, + 212, 213, 214, 877, 0, 216, 0, 217, 218, 878, + 220, 0, 221, 0, 222, 879, 0, 880, 225, 226, + 881, 882, 229, 0, 230, 0, 883, 884, 233, 0, + 234, 235, 236, 237, 238, 239, 240, 885, 242, 243, + 244, 245, 0, 246, 247, 248, 249, 250, 251, 0, + 252, 886, 887, 255, 256, 257, 258, 259, 888, 889, + 0, 890, 0, 263, 891, 892, 266, 893, 268, 269, + 270, 271, 272, 273, 0, 0, 274, 894, 276, 895, + 0, 278, 279, 280, 0, 0, 281, 282, 283, 284, + 285, 896, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 897, 898, 899, 308, 309, 310, 900, 0, 312, 313, + 901, 315, 0, 902, 317, 903, 319, 320, 321, 0, + 322, 323, 0, 0, 324, 325, 326, 0, 0, 327, + 904, 905, 330, 906, 907, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 0, 343, 344, 908, 909, + 347, 348, 910, 350, 351, 352, 0, 353, 354, 355, + 356, 357, 358, 0, 359, 360, 361, 911, 363, 364, + 365, 366, 0, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 0, 380, 381, 912, + 383, 384, 385, 913, 387, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 0, 398, 399, 400, 401, + 402, 914, 404, 915, 406, 407, 408, 916, 410, 411, + 917, 413, 0, 414, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 425, 918, 427, 919, 429, 0, + 430, 431, 0, 432, 920, 434, 435, 436, 437, 438, + 0, 921, 922, 0, 0, 441, 442, 923, 444, 924, + 0, 446, 447, 925, 449, 450, 451, 452, 453, 0, + 0, 454, 455, 456, 457, 458, 459, 926, 0, 461, + 462, 463, 464, 465, 1312, 928, 0, 468, 929, 470, + 471, 472, 473, 474, 0, 0, 475, 0, 0, 476, + 477, 478, 479, 480, 481, 930, 931, 932, 933, 934, + 935, 936, 937, 938, 939, 940, 493, 494, 495, 496, + 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 105, 106, + 107, 108, 109, 110, 111, 112, 0, 113, 114, 115, + 0, 0, 0, 0, 0, 0, 0, 116, 117, 0, + 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, + 128, 129, 0, 130, 131, 132, 133, 134, 135, 0, + 0, 136, 137, 138, 139, 140, 0, 141, 142, 143, + 144, 145, 0, 146, 0, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 0, 157, 158, 159, 160, + 161, 162, 0, 163, 164, 165, 166, 167, 168, 169, + 170, 0, 0, 171, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 0, 182, 0, 183, 184, 185, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 0, + 0, 194, 195, 196, 197, 198, 0, 199, 200, 201, + 0, 202, 203, 204, 0, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 0, 216, 0, 217, + 218, 219, 220, 0, 221, 0, 222, 223, 0, 224, + 225, 226, 227, 228, 229, 0, 230, 0, 231, 232, + 233, 0, 234, 235, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 0, 246, 247, 248, 249, 250, + 251, 0, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 0, 262, 0, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 0, 0, 274, 275, + 276, 277, 0, 278, 279, 280, 0, 0, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, 310, 311, 0, + 312, 313, 314, 315, 0, 316, 317, 318, 319, 320, + 321, 0, 322, 323, 0, 0, 324, 325, 326, 0, + 0, 327, 328, 329, 330, 331, 332, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 0, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 0, 353, + 354, 355, 356, 357, 358, 0, 359, 360, 361, 362, + 363, 364, 365, 366, 0, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 0, 380, + 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 0, 398, 399, + 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, + 410, 411, 412, 413, 0, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, + 429, 0, 430, 431, 0, 432, 433, 434, 435, 436, + 437, 438, 0, 439, 440, 0, 0, 441, 442, 443, + 444, 445, 0, 446, 447, 448, 449, 450, 451, 452, + 453, 0, 0, 454, 455, 456, 457, 458, 459, 460, + 0, 461, 462, 463, 464, 465, 466, 467, 0, 468, + 469, 470, 471, 472, 473, 474, 0, 0, 475, 0, + 0, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, + 495, 496, 504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 96, 97, 98, 99, 100, 101, 102, 103, 726, 104, - 105, 106, 0, 0, 0, 0, 0, 0, 0, 107, - 108, 0, 109, 110, 111, 0, 113, 114, 115, 116, - 117, 0, 119, 120, 0, 121, 122, 123, 124, 125, - 126, 0, 0, 127, 128, 129, 130, 131, 0, 132, - 133, 134, 135, 136, 0, 0, 0, 138, 139, 140, - 141, 142, 143, 0, 145, 146, 147, 0, 148, 149, - 150, 151, 152, 153, 0, 0, 155, 156, 157, 0, - 0, 0, 0, 0, 0, 0, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 0, 173, 0, 174, - 175, 176, 177, 178, 179, 0, 180, 181, 182, 183, - 184, 0, 0, 185, 186, 187, 188, 189, 0, 190, - 191, 192, 0, 193, 194, 195, 0, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 0, 207, - 0, 208, 209, 210, 211, 0, 212, 0, 213, 0, - 0, 0, 216, 217, 511, 0, 220, 0, 221, 0, - 222, 223, 224, 0, 225, 226, 227, 228, 229, 230, - 231, 0, 233, 234, 235, 236, 0, 237, 238, 239, - 240, 241, 242, 0, 243, 0, 245, 246, 247, 248, - 249, 250, 251, 252, 0, 253, 0, 254, 0, 0, - 257, 0, 259, 260, 261, 262, 263, 264, 0, 0, - 265, 0, 267, 0, 0, 269, 270, 271, 0, 0, - 272, 273, 274, 275, 276, 512, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, 293, 294, 295, 296, 0, 298, 299, 300, 301, - 302, 0, 303, 304, 0, 306, 0, 307, 308, 309, - 310, 311, 312, 0, 313, 314, 0, 0, 315, 316, - 317, 0, 0, 318, 319, 0, 321, 0, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 0, + 105, 106, 107, 108, 109, 110, 111, 112, 0, 113, + 114, 115, 0, 0, 0, 0, 0, 0, 0, 116, + 117, 0, 118, 119, 120, 0, 122, 123, 124, 125, + 126, 0, 128, 129, 0, 130, 131, 132, 133, 134, + 135, 0, 0, 136, 137, 138, 139, 140, 1690, 141, + 142, 143, 144, 145, 0, 0, 1691, 147, 148, 149, + 150, 151, 152, 0, 154, 155, 156, 1692, 157, 158, + 159, 160, 161, 162, 0, 0, 164, 165, 166, 0, + 0, 0, 0, 0, 0, 0, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 0, 182, 0, 183, + 184, 185, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 0, 0, 194, 195, 196, 197, 198, 0, 199, + 200, 201, 0, 202, 203, 204, 0, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 0, 216, + 0, 217, 218, 219, 220, 0, 221, 1693, 222, 0, + 0, 0, 225, 226, 505, 0, 229, 0, 230, 0, + 231, 232, 233, 0, 234, 235, 236, 237, 238, 1694, + 240, 0, 242, 243, 244, 245, 0, 246, 247, 248, + 249, 250, 251, 0, 252, 0, 254, 255, 256, 257, + 258, 259, 260, 261, 0, 262, 0, 263, 0, 0, + 266, 0, 268, 269, 270, 271, 272, 273, 0, 0, + 274, 0, 276, 0, 0, 278, 279, 280, 0, 0, + 281, 282, 283, 284, 285, 506, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, 0, 307, 308, 309, 310, + 311, 0, 312, 313, 0, 315, 0, 316, 317, 318, + 319, 320, 321, 0, 322, 323, 0, 0, 324, 325, + 326, 0, 0, 327, 328, 0, 330, 0, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 0, - 343, 344, 345, 346, 347, 348, 0, 349, 350, 351, - 352, 353, 354, 355, 356, 0, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, 369, 0, - 370, 371, 0, 373, 374, 375, 376, 377, 378, 379, - 380, 381, 382, 383, 384, 385, 386, 387, 0, 388, - 389, 390, 391, 392, 0, 394, 395, 396, 397, 398, - 0, 400, 401, 402, 403, 0, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 514, 417, - 418, 419, 0, 420, 421, 0, 422, 0, 424, 425, - 426, 427, 428, 0, 429, 430, 0, 0, 431, 432, - 433, 434, 435, 0, 436, 437, 438, 439, 440, 441, - 442, 443, 0, 0, 444, 445, 446, 447, 448, 0, - 0, 450, 451, 452, 453, 454, 455, 456, 0, 457, - 0, 459, 460, 461, 462, 463, 0, 0, 464, 0, - 0, 465, 466, 467, 468, 469, 470, 471, 472, 473, - 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, - 484, 485, 735, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 96, 97, 98, 99, 100, 101, 102, 103, 0, 104, - 105, 106, 0, 0, 0, 0, 0, 0, 0, 107, - 108, 0, 109, 110, 111, 736, 113, 114, 115, 0, - 737, 738, 739, 740, 0, 121, 122, 123, 124, 125, - 126, 0, 0, 127, 128, 741, 742, 131, 0, 132, - 133, 134, 135, 0, 0, 743, 0, 744, 139, 140, - 141, 142, 143, 745, 145, 146, 147, 0, 148, 149, - 150, 151, 152, 153, 0, 746, 155, 156, 157, 747, - 748, 749, 750, 0, 0, 751, 163, 164, 165, 166, - 167, 168, 169, 752, 753, 172, 0, 173, 0, 174, - 175, 176, 177, 178, 179, 0, 180, 181, 182, 183, - 184, 0, 0, 185, 186, 754, 188, 189, 0, 190, - 191, 192, 0, 193, 194, 195, 0, 196, 197, 198, - 199, 0, 201, 202, 203, 204, 205, 0, 0, 207, - 0, 208, 209, 755, 211, 0, 212, 0, 213, 756, - 0, 757, 216, 217, 0, 758, 220, 0, 221, 0, - 0, 0, 224, 0, 225, 226, 227, 228, 229, 759, - 231, 760, 233, 234, 235, 236, 0, 237, 238, 239, - 240, 241, 242, 0, 243, 761, 0, 246, 247, 248, - 249, 250, 762, 763, 0, 764, 0, 254, 765, 766, - 257, 767, 259, 260, 261, 262, 263, 264, 0, 0, - 265, 768, 267, 769, 0, 269, 270, 271, 0, 0, - 272, 273, 274, 275, 276, 770, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, 293, 294, 295, 771, 772, 773, 299, 300, 301, - 0, 0, 303, 304, 774, 306, 0, 0, 308, 775, - 310, 311, 312, 0, 313, 314, 0, 0, 315, 316, - 317, 0, 0, 318, 0, 776, 321, 777, 0, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 0, - 334, 335, 0, 337, 338, 0, 340, 341, 342, 0, - 343, 344, 345, 346, 347, 348, 0, 349, 350, 351, - 778, 353, 354, 355, 356, 0, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, 369, 0, - 370, 371, 779, 373, 374, 375, 780, 377, 378, 379, - 380, 381, 382, 383, 384, 385, 386, 387, 0, 388, - 389, 390, 391, 392, 781, 394, 782, 396, 397, 398, - 783, 400, 401, 784, 403, 0, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 785, 417, - 0, 419, 0, 420, 421, 0, 422, 786, 424, 425, - 426, 427, 428, 0, 787, 788, 0, 0, 431, 432, - 0, 434, 0, 0, 436, 437, 789, 439, 440, 441, - 442, 443, 790, 0, 444, 445, 446, 447, 448, 791, - 0, 450, 451, 452, 453, 454, 0, 792, 0, 457, - 793, 459, 460, 461, 462, 463, 0, 0, 464, 0, - 0, 465, 466, 467, 468, 469, 470, 735, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 482, 483, - 484, 485, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 736, 113, 114, 115, 0, 737, 738, 739, 740, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 741, 742, 131, 0, 132, 133, 134, 135, 0, 0, - 743, 0, 744, 139, 140, 141, 142, 143, 745, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 746, 155, 156, 157, 747, 748, 749, 750, 0, 0, - 751, 163, 164, 165, 166, 167, 168, 169, 752, 753, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 754, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 0, 201, 202, 203, - 204, 205, 0, 0, 207, 0, 208, 209, 755, 211, - 0, 212, 0, 213, 756, 0, 757, 216, 217, 0, - 758, 220, 0, 221, 0, 0, 0, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 760, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 761, 0, 246, 247, 248, 249, 250, 762, 763, 0, - 764, 0, 254, 765, 766, 257, 767, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 768, 267, 769, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 770, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 771, - 772, 773, 299, 300, 301, 0, 0, 303, 304, 774, - 306, 0, 0, 308, 775, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 0, - 776, 321, 777, 0, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 0, 337, 338, - 0, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 778, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 779, 373, 374, - 375, 780, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 781, - 394, 782, 396, 397, 398, 783, 400, 401, 784, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 785, 417, 0, 419, 0, 420, 421, - 0, 422, 786, 424, 425, 426, 427, 428, 0, 787, - 788, 0, 0, 431, 432, 0, 434, 0, 0, 436, - 437, 789, 439, 440, 441, 442, 443, 790, 0, 444, - 445, 446, 447, 448, 791, 0, 450, 451, 452, 453, - 454, 0, 792, 0, 457, 793, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 735, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 482, 483, 484, 485, 0, 0, 0, - 96, 97, 98, 99, 100, 101, 102, 103, 0, 104, - 105, 106, 0, 0, 0, 0, 0, 0, 0, 107, - 108, 0, 109, 110, 111, 736, 113, 114, 115, 0, - 737, 738, 739, 740, 0, 121, 122, 123, 124, 125, - 126, 0, 0, 127, 128, 741, 742, 131, 0, 132, - 133, 134, 135, 0, 0, 743, 0, 744, 139, 140, - 141, 142, 143, 745, 145, 146, 147, 0, 148, 149, - 150, 151, 152, 153, 0, 746, 155, 156, 157, 747, - 748, 749, 750, 0, 0, 751, 163, 164, 165, 166, - 167, 168, 169, 752, 753, 172, 0, 173, 0, 174, - 175, 176, 177, 178, 179, 0, 180, 181, 182, 183, - 184, 0, 0, 185, 186, 754, 188, 189, 0, 190, - 191, 192, 0, 1720, 194, 195, 0, 196, 197, 198, - 199, 0, 201, 202, 203, 204, 205, 0, 0, 207, - 0, 208, 209, 755, 211, 0, 212, 0, 213, 756, - 0, 757, 216, 217, 0, 758, 220, 0, 221, 0, - 0, 0, 224, 0, 225, 226, 227, 228, 229, 230, - 231, 760, 233, 234, 235, 236, 0, 237, 238, 239, - 240, 241, 242, 0, 243, 761, 0, 246, 247, 248, - 249, 250, 762, 763, 0, 764, 0, 254, 765, 766, - 257, 767, 259, 260, 261, 262, 263, 264, 0, 0, - 265, 768, 267, 769, 0, 269, 270, 271, 0, 0, - 272, 273, 274, 275, 276, 770, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, 293, 294, 295, 771, 772, 773, 299, 300, 301, - 0, 0, 303, 304, 774, 306, 0, 0, 308, 775, - 310, 311, 312, 0, 313, 314, 0, 0, 315, 316, - 317, 0, 0, 318, 0, 776, 321, 777, 0, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 0, - 334, 335, 0, 337, 338, 0, 340, 341, 342, 0, - 343, 344, 345, 346, 347, 348, 0, 349, 350, 351, - 778, 353, 354, 355, 356, 0, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, 369, 0, - 370, 371, 779, 373, 374, 375, 780, 377, 378, 379, - 380, 381, 382, 383, 384, 385, 386, 387, 0, 388, - 389, 390, 391, 392, 781, 394, 782, 396, 397, 398, - 783, 400, 401, 784, 403, 0, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 785, 417, - 0, 419, 0, 420, 421, 0, 422, 786, 424, 425, - 426, 427, 428, 0, 787, 788, 0, 0, 431, 432, - 0, 434, 0, 0, 436, 437, 789, 439, 440, 441, - 442, 443, 790, 0, 444, 445, 446, 447, 448, 791, - 0, 450, 451, 452, 453, 454, 0, 792, 0, 457, - 793, 459, 460, 461, 462, 463, 0, 0, 464, 0, - 0, 465, 466, 467, 468, 469, 470, 508, 1846, 0, - 0, 0, 0, 1847, 0, 0, 0, 0, 482, 483, - 484, 485, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 509, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 1855, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 1856, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 1857, 422, 0, 424, 1858, 426, 1859, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 1860, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 509, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 624, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 0, + 343, 344, 345, 0, 347, 348, 349, 350, 351, 352, + 1695, 353, 354, 355, 356, 357, 358, 0, 359, 360, + 361, 362, 363, 364, 365, 366, 0, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 0, 380, 381, 0, 383, 384, 385, 386, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 0, + 398, 399, 400, 401, 402, 0, 404, 405, 406, 407, + 408, 0, 410, 411, 412, 413, 0, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 507, + 427, 428, 429, 0, 430, 431, 0, 432, 0, 434, + 435, 436, 437, 438, 0, 439, 440, 0, 0, 441, + 442, 443, 444, 445, 0, 446, 447, 448, 449, 450, + 451, 452, 453, 0, 1696, 454, 455, 456, 457, 458, + 459, 0, 0, 461, 462, 463, 464, 465, 466, 467, + 0, 468, 0, 470, 471, 472, 473, 474, 0, 0, + 475, 0, 0, 476, 477, 478, 479, 480, 481, 482, + 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, + 493, 494, 495, 496, 504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 631, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 632, - 430, 0, 0, 633, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 509, + 0, 0, 105, 106, 107, 108, 109, 110, 111, 112, + 0, 113, 114, 115, 0, 0, 0, 0, 0, 0, + 0, 116, 117, 0, 118, 119, 120, 0, 122, 123, + 124, 125, 126, 0, 128, 129, 0, 130, 131, 132, + 133, 134, 135, 0, 0, 136, 137, 138, 139, 140, + 1690, 141, 142, 143, 144, 145, 0, 0, 0, 147, + 148, 149, 150, 151, 152, 0, 154, 155, 156, 1692, + 157, 158, 159, 160, 161, 162, 0, 0, 164, 165, + 166, 0, 0, 0, 0, 0, 0, 0, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 0, 182, + 0, 183, 184, 185, 186, 187, 188, 0, 189, 190, + 191, 192, 193, 0, 0, 194, 195, 196, 197, 198, + 0, 199, 200, 201, 0, 202, 203, 204, 0, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 0, 216, 0, 217, 218, 219, 220, 0, 221, 1693, + 222, 0, 0, 0, 225, 226, 505, 0, 229, 0, + 230, 0, 231, 232, 233, 0, 234, 235, 236, 237, + 238, 239, 240, 0, 242, 243, 244, 245, 0, 246, + 247, 248, 249, 250, 251, 0, 252, 0, 254, 255, + 256, 257, 258, 259, 260, 261, 0, 262, 0, 263, + 0, 0, 266, 0, 268, 269, 270, 271, 272, 273, + 0, 0, 274, 0, 276, 2210, 0, 278, 279, 280, + 0, 0, 281, 282, 283, 284, 285, 506, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 0, 307, 308, + 309, 310, 311, 0, 312, 313, 0, 315, 0, 316, + 317, 318, 319, 320, 321, 0, 322, 323, 0, 0, + 324, 325, 326, 0, 0, 327, 328, 0, 330, 0, + 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 0, 343, 344, 345, 0, 347, 348, 349, 350, + 351, 352, 1695, 353, 354, 355, 356, 357, 358, 0, + 359, 360, 361, 362, 363, 364, 365, 366, 0, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 0, 380, 381, 0, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 0, 398, 399, 400, 401, 402, 0, 404, 405, + 406, 407, 408, 0, 410, 411, 412, 413, 0, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 507, 427, 428, 429, 0, 430, 431, 0, 432, + 0, 434, 435, 436, 437, 438, 0, 439, 440, 0, + 0, 441, 442, 443, 444, 445, 0, 446, 447, 448, + 449, 450, 451, 452, 453, 0, 1696, 454, 455, 456, + 457, 458, 459, 0, 0, 461, 462, 463, 464, 465, + 466, 467, 0, 468, 0, 470, 471, 472, 473, 474, + 0, 0, 475, 0, 0, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, + 491, 492, 493, 494, 495, 496, 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 0, 0, 0, 0, 105, 106, 107, 108, 109, 110, + 111, 112, 0, 113, 114, 115, 0, 0, 0, 0, + 0, -700, 0, 116, 117, 0, 118, 119, 120, 767, + 122, 123, 124, 0, 768, 769, 770, 771, 0, 130, + 131, 132, 133, 134, 135, 0, 0, 136, 137, 772, + 773, 140, 0, 141, 142, 143, 144, 0, 0, 774, + 0, 775, 148, 149, 150, 151, 152, 776, 154, 155, + 156, 0, 157, 158, 159, 160, 161, 162, 0, 777, + 164, 165, 166, 778, 779, 780, 781, 0, 0, 782, + 172, 173, 174, 175, 176, 177, 178, 783, 784, 181, + 0, 182, 0, 183, 184, 185, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 0, 0, 194, 195, 785, + 197, 198, 0, 199, 200, 201, 0, 202, 203, 204, + 0, 205, 206, 207, 208, 0, 210, 211, 212, 213, + 214, 0, 0, 216, 0, 217, 218, 786, 220, 0, + 221, 0, 222, 787, 0, 788, 225, 226, -700, 789, + 229, 0, 230, 0, 0, 0, 233, 0, 234, 235, + 236, 237, 238, 239, 240, 791, 242, 243, 244, 245, + 0, 246, 247, 248, 249, 250, 251, 0, 252, 792, + 0, 255, 256, 257, 258, 259, 793, 794, 0, 795, + 0, 263, 796, 797, 266, 798, 268, 269, 270, 271, + 272, 273, 0, 0, 274, 799, 276, 800, 0, 278, + 279, 280, 0, 0, 281, 282, 283, 284, 285, 801, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 664, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 509, + 297, 298, 299, 300, 301, 302, 303, 304, 802, 803, + 804, 308, 309, 310, 0, 0, 312, 313, 805, 315, + 0, 0, 317, 806, 319, 320, 321, 0, 322, 323, + 0, 0, 324, 325, 326, 0, 0, 327, 0, 807, + 330, 808, 0, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 0, 343, 344, 0, 809, 347, 348, + 0, 350, 351, 352, 0, 353, 354, 355, 356, 357, + 358, 0, 359, 360, 361, 810, 363, 364, 365, 366, + 0, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 0, 380, 381, 811, 383, 384, + 385, 812, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 0, 398, 399, 400, 401, 402, 813, + 404, 814, 406, 407, 408, 815, 410, 411, 816, 413, + 0, 414, 415, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 425, 817, 427, 0, 429, 0, 430, 431, + 0, 432, 818, 434, 435, 436, 437, 438, 0, 819, + 820, 0, 0, 441, 442, 0, 444, 0, 0, 446, + 447, 821, 449, 450, 451, 452, 453, 822, 0, 454, + 455, 456, 457, 458, 459, 823, 0, 461, 462, 463, + 464, 465, 0, 824, 0, 468, 825, 470, 471, 472, + 473, 474, 0, 0, 475, 0, 0, 476, 477, 478, + 479, 480, 481, 766, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 493, 494, 495, 496, 0, 0, + 0, 105, 106, 107, 108, 109, 110, 111, 112, 0, + 113, 114, 115, 0, 0, 0, 0, 0, 0, 0, + 116, 117, 0, 118, 119, 120, 767, 122, 123, 124, + 0, 768, 769, 770, 771, 0, 130, 131, 132, 133, + 134, 135, 0, 0, 136, 137, 772, 773, 140, 0, + 141, 142, 143, 144, 0, 0, 774, 0, 775, 148, + 149, 150, 151, 152, 776, 154, 155, 156, 0, 157, + 158, 159, 160, 161, 162, 0, 777, 164, 165, 166, + 778, 779, 780, 781, 0, 0, 782, 172, 173, 174, + 175, 176, 177, 178, 783, 784, 181, 0, 182, 0, + 183, 184, 185, 186, 187, 188, 0, 189, 190, 191, + 192, 193, 0, 0, 194, 195, 785, 197, 198, 0, + 199, 200, 201, 0, 202, 203, 204, 0, 205, 206, + 207, 208, 0, 210, 211, 212, 213, 214, 0, 0, + 216, 0, 217, 218, 786, 220, 0, 221, 0, 222, + 787, 0, 788, 225, 226, 0, 789, 229, 0, 230, + 0, 0, 0, 233, 0, 234, 235, 236, 237, 238, + 790, 240, 791, 242, 243, 244, 245, 0, 246, 247, + 248, 249, 250, 251, 0, 252, 792, 0, 255, 256, + 257, 258, 259, 793, 794, 0, 795, 0, 263, 796, + 797, 266, 798, 268, 269, 270, 271, 272, 273, 0, + 0, 274, 799, 276, 800, 0, 278, 279, 280, 0, + 0, 281, 282, 283, 284, 285, 801, 287, 288, 289, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 802, 803, 804, 308, 309, + 310, 0, 0, 312, 313, 805, 315, 0, 0, 317, + 806, 319, 320, 321, 0, 322, 323, 0, 0, 324, + 325, 326, 0, 0, 327, 0, 807, 330, 808, 0, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 0, 343, 344, 0, 809, 347, 348, 0, 350, 351, + 352, 0, 353, 354, 355, 356, 357, 358, 0, 359, + 360, 361, 810, 363, 364, 365, 366, 0, 367, 368, + 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, + 379, 0, 380, 381, 811, 383, 384, 385, 812, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + 0, 398, 399, 400, 401, 402, 813, 404, 814, 406, + 407, 408, 815, 410, 411, 816, 413, 0, 414, 415, + 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, + 817, 427, 0, 429, 0, 430, 431, 0, 432, 818, + 434, 435, 436, 437, 438, 0, 819, 820, 0, 0, + 441, 442, 0, 444, 0, 0, 446, 447, 821, 449, + 450, 451, 452, 453, 822, 0, 454, 455, 456, 457, + 458, 459, 823, 0, 461, 462, 463, 464, 465, 0, + 824, 0, 468, 825, 470, 471, 472, 473, 474, 0, + 0, 475, 0, 0, 476, 477, 478, 479, 480, 481, + 766, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 493, 494, 495, 496, 0, 0, 0, 105, 106, + 107, 108, 109, 110, 111, 112, 0, 113, 114, 115, + 0, 0, 0, 0, 0, 0, 0, 116, 117, 0, + 118, 119, 120, 767, 122, 123, 124, 0, 768, 769, + 770, 771, 0, 130, 131, 132, 133, 134, 135, 0, + 0, 136, 137, 772, 773, 140, 0, 141, 142, 143, + 144, 0, 0, 774, 0, 775, 148, 149, 150, 151, + 152, 776, 154, 155, 156, 0, 157, 158, 159, 160, + 161, 162, 0, 777, 164, 165, 166, 778, 779, 780, + 781, 0, 0, 782, 172, 173, 174, 175, 176, 177, + 178, 783, 784, 181, 0, 182, 0, 183, 184, 185, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 0, + 0, 194, 195, 785, 197, 198, 0, 199, 200, 201, + 0, 202, 203, 204, 0, 205, 206, 207, 208, 0, + 210, 211, 212, 213, 214, 0, 0, 216, 0, 217, + 218, 786, 220, 0, 221, 0, 222, 787, 0, 788, + 225, 226, 0, 789, 229, 0, 230, 0, 0, 0, + 233, 0, 234, 235, 236, 237, 238, 239, 240, 791, + 242, 243, 244, 245, 0, 246, 247, 248, 249, 250, + 251, 0, 252, 792, 0, 255, 256, 257, 258, 259, + 793, 794, 0, 795, 0, 263, 796, 797, 266, 798, + 268, 269, 270, 271, 272, 273, 0, 0, 274, 799, + 276, 800, 0, 278, 279, 280, 0, 0, 281, 282, + 283, 284, 285, 801, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 802, 803, 804, 308, 309, 310, 0, 0, + 312, 313, 805, 315, 0, 0, 317, 806, 319, 320, + 321, 0, 322, 323, 0, 0, 324, 325, 326, 0, + 0, 327, 0, 807, 330, 808, 0, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 0, 343, 344, + 0, 809, 347, 348, 0, 350, 351, 352, 0, 353, + 354, 355, 356, 357, 358, 0, 359, 360, 361, 810, + 363, 364, 365, 366, 0, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 0, 380, + 381, 811, 383, 384, 385, 812, 387, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 0, 398, 399, + 400, 401, 402, 813, 404, 814, 406, 407, 408, 815, + 410, 411, 816, 413, 0, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 817, 427, 0, + 429, 0, 430, 431, 0, 432, 818, 434, 435, 436, + 437, 438, 0, 819, 820, 0, 0, 441, 442, 0, + 444, 0, 0, 446, 447, 821, 449, 450, 451, 452, + 453, 822, 0, 454, 455, 456, 457, 458, 459, 823, + 0, 461, 462, 463, 464, 465, 0, 824, 0, 468, + 825, 470, 471, 472, 473, 474, 0, 0, 475, 0, + 0, 476, 477, 478, 479, 480, 481, 766, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 493, 494, + 495, 496, 0, 0, 0, 105, 106, 107, 108, 109, + 110, 111, 112, 0, 113, 114, 115, 0, 0, 0, + 0, 0, 0, 0, 116, 117, 0, 118, 119, 120, + 767, 122, 123, 124, 0, 768, 769, 770, 771, 0, + 130, 131, 132, 133, 134, 135, 0, 0, 136, 137, + 772, 773, 140, 0, 141, 142, 143, 144, 0, 0, + 774, 0, 775, 148, 149, 150, 151, 152, 776, 154, + 155, 156, 0, 157, 158, 159, 160, 161, 162, 0, + 777, 164, 165, 166, 778, 779, 780, 781, 0, 0, + 782, 172, 173, 174, 175, 176, 177, 178, 783, 784, + 181, 0, 182, 0, 183, 184, 185, 186, 187, 188, + 0, 189, 190, 191, 192, 193, 0, 0, 194, 195, + 785, 197, 198, 0, 199, 200, 201, 0, 1776, 203, + 204, 0, 205, 206, 207, 208, 0, 210, 211, 212, + 213, 214, 0, 0, 216, 0, 217, 218, 786, 220, + 0, 221, 0, 222, 787, 0, 788, 225, 226, 0, + 789, 229, 0, 230, 0, 0, 0, 233, 0, 234, + 235, 236, 237, 238, 239, 240, 791, 242, 243, 244, + 245, 0, 246, 247, 248, 249, 250, 251, 0, 252, + 792, 0, 255, 256, 257, 258, 259, 793, 794, 0, + 795, 0, 263, 796, 797, 266, 798, 268, 269, 270, + 271, 272, 273, 0, 0, 274, 799, 276, 800, 0, + 278, 279, 280, 0, 0, 281, 282, 283, 284, 285, + 801, 287, 288, 289, 290, 291, 292, 293, 294, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 802, + 803, 804, 308, 309, 310, 0, 0, 312, 313, 805, + 315, 0, 0, 317, 806, 319, 320, 321, 0, 322, + 323, 0, 0, 324, 325, 326, 0, 0, 327, 0, + 807, 330, 808, 0, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342, 0, 343, 344, 0, 809, 347, + 348, 0, 350, 351, 352, 0, 353, 354, 355, 356, + 357, 358, 0, 359, 360, 361, 810, 363, 364, 365, + 366, 0, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 0, 380, 381, 811, 383, + 384, 385, 812, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 0, 398, 399, 400, 401, 402, + 813, 404, 814, 406, 407, 408, 815, 410, 411, 816, + 413, 0, 414, 415, 416, 417, 418, 419, 420, 421, + 422, 423, 424, 425, 817, 427, 0, 429, 0, 430, + 431, 0, 432, 818, 434, 435, 436, 437, 438, 0, + 819, 820, 0, 0, 441, 442, 0, 444, 0, 0, + 446, 447, 821, 449, 450, 451, 452, 453, 822, 0, + 454, 455, 456, 457, 458, 459, 823, 0, 461, 462, + 463, 464, 465, 0, 824, 0, 468, 825, 470, 471, + 472, 473, 474, 0, 0, 475, 0, 0, 476, 477, + 478, 479, 480, 481, 504, 0, 530, 0, 0, 0, + 0, 0, 0, 0, 0, 493, 494, 495, 496, 0, + 0, 0, 105, 106, 107, 108, 109, 110, 111, 112, + 0, 113, 114, 115, 3, 4, 0, 0, 0, 0, + 0, 116, 117, 0, 118, 119, 120, 0, 122, 123, + 124, 125, 126, 0, 128, 129, 0, 130, 131, 132, + 133, 134, 135, 0, 0, 136, 137, 138, 139, 140, + 0, 141, 142, 143, 144, 145, 0, 0, 0, 147, + 148, 149, 150, 151, 152, 0, 154, 155, 156, 0, + 157, 158, 159, 160, 161, 162, 0, 0, 164, 165, + 166, 0, 0, 0, 0, 0, 0, 0, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 0, 182, + 0, 183, 184, 185, 186, 187, 188, 0, 189, 190, + 191, 192, 193, 0, 0, 194, 195, 196, 197, 198, + 0, 199, 200, 201, 0, 202, 203, 204, 0, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 0, 216, 0, 217, 218, 219, 220, 0, 221, 0, + 222, 0, 0, 0, 225, 226, 505, 0, 229, 0, + 230, 0, 231, 232, 233, 0, 234, 235, 236, 237, + 238, 239, 240, 0, 242, 243, 244, 245, 0, 246, + 247, 248, 249, 250, 251, 0, 252, 0, 254, 255, + 256, 257, 258, 259, 260, 261, 0, 262, 0, 263, + 0, 0, 266, 0, 268, 269, 270, 271, 272, 273, + 0, 0, 274, 0, 276, 0, 0, 278, 279, 280, + 0, 0, 281, 282, 283, 284, 285, 506, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 0, 307, 308, + 309, 310, 311, 0, 312, 313, 0, 315, 0, 316, + 317, 318, 319, 320, 321, 0, 322, 323, 0, 0, + 324, 325, 326, 0, 0, 327, 328, 0, 330, 0, + 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 0, 343, 344, 345, 0, 347, 348, 349, 350, + 351, 352, 0, 353, 354, 355, 356, 357, 358, 0, + 359, 360, 361, 362, 363, 364, 365, 366, 0, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 0, 380, 381, 0, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 0, 398, 399, 400, 401, 402, 0, 404, 405, + 406, 407, 408, 0, 410, 411, 412, 413, 0, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 507, 427, 428, 429, 0, 430, 431, 0, 432, + 0, 434, 435, 436, 437, 438, 0, 439, 440, 0, + 0, 441, 442, 443, 444, 445, 0, 446, 447, 448, + 449, 450, 451, 452, 453, 0, 0, 454, 455, 456, + 457, 458, 459, 0, 0, 461, 462, 463, 464, 465, + 466, 467, 0, 468, 0, 470, 471, 472, 473, 474, + 0, 0, 475, 0, 0, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, + 491, 492, 493, 494, 495, 496, 504, 0, 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 693, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 0, 0, 0, 0, 105, 106, 107, 108, 109, 110, + 111, 112, 531, 113, 114, 115, 0, 0, 0, 0, + 0, 0, 0, 116, 117, 0, 118, 119, 120, 0, + 122, 123, 124, 125, 126, 0, 128, 129, 0, 130, + 131, 132, 133, 134, 135, 0, 0, 136, 137, 138, + 139, 140, 0, 141, 142, 143, 144, 145, 0, 0, + 0, 147, 148, 149, 150, 151, 152, 0, 154, 155, + 156, 0, 157, 158, 159, 160, 161, 162, 0, 0, + 164, 165, 166, 0, 0, 0, 0, 0, 0, 0, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 0, 182, 0, 183, 184, 185, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 0, 0, 194, 195, 196, + 197, 198, 0, 199, 200, 201, 0, 202, 203, 204, + 0, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 214, 215, 0, 216, 0, 217, 218, 219, 220, 0, + 221, 0, 222, 0, 0, 0, 225, 226, 505, 0, + 229, 0, 230, 0, 231, 232, 233, 0, 234, 235, + 236, 237, 238, 239, 240, 0, 242, 243, 244, 245, + 0, 246, 247, 248, 249, 250, 251, 0, 252, 0, + 254, 255, 256, 257, 258, 259, 260, 261, 0, 262, + 0, 263, 0, 0, 266, 0, 268, 269, 270, 271, + 272, 273, 0, 0, 274, 0, 276, 0, 0, 278, + 279, 280, 0, 0, 281, 282, 283, 284, 285, 506, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 509, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 0, + 307, 308, 309, 310, 311, 0, 312, 313, 0, 315, + 0, 316, 317, 318, 319, 320, 321, 0, 322, 323, + 0, 0, 324, 325, 326, 0, 0, 327, 328, 0, + 330, 0, 332, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 0, 343, 344, 345, 0, 347, 348, + 349, 532, 351, 352, 0, 353, 354, 355, 356, 357, + 358, 0, 359, 360, 361, 362, 363, 364, 365, 366, + 0, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 0, 380, 381, 0, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 0, 398, 399, 400, 401, 402, 0, + 404, 405, 406, 407, 408, 0, 410, 411, 412, 413, + 0, 414, 415, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 425, 507, 427, 428, 429, 0, 430, 431, + 0, 432, 0, 434, 435, 436, 437, 438, 0, 439, + 440, 0, 0, 441, 442, 443, 444, 445, 0, 446, + 447, 448, 449, 450, 451, 452, 453, 0, 0, 454, + 455, 456, 457, 458, 459, 0, 0, 461, 462, 463, + 464, 465, 466, 467, 0, 468, 0, 470, 471, 472, + 473, 474, 0, 0, 475, 0, 0, 476, 477, 478, + 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, + 489, 490, 491, 492, 493, 494, 495, 496, 504, 0, + 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 105, 106, 107, 108, + 109, 110, 111, 112, 0, 113, 114, 115, 0, 0, + 0, 0, 0, 0, 0, 116, 117, 0, 118, 119, + 120, 0, 122, 123, 124, 125, 126, 0, 128, 129, + 0, 130, 131, 132, 133, 134, 135, 0, 0, 136, + 137, 138, 139, 140, 0, 141, 142, 143, 144, 145, + 0, 0, 0, 147, 148, 149, 150, 151, 152, 0, + 154, 155, 156, 0, 157, 158, 159, 160, 161, 162, + 0, 0, 164, 165, 166, 0, 0, 0, 0, 0, + 0, 0, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 0, 182, 0, 183, 184, 185, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 0, 0, 194, + 195, 196, 197, 198, 0, 199, 200, 201, 0, 202, + 203, 204, 0, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 0, 216, 0, 217, 218, 219, + 220, 0, 221, 0, 222, 0, 0, 0, 225, 226, + 505, 0, 229, 0, 230, 0, 231, 232, 233, 0, + 234, 235, 236, 237, 238, 239, 240, 0, 242, 243, + 244, 245, 0, 246, 247, 248, 249, 250, 251, 0, + 252, 0, 254, 255, 256, 257, 258, 259, 260, 261, + 0, 262, 0, 263, 0, 0, 266, 0, 268, 269, + 270, 271, 272, 273, 0, 0, 274, 0, 276, 0, + 0, 278, 279, 280, 0, 0, 281, 282, 283, 284, + 285, 506, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 0, 307, 308, 309, 310, 311, 0, 312, 313, + 0, 315, 0, 316, 317, 318, 319, 320, 321, 0, + 322, 323, 0, 621, 324, 325, 326, 0, 0, 327, + 328, 0, 330, 0, 332, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 0, 343, 344, 345, 0, + 347, 348, 349, 350, 351, 352, 0, 353, 354, 355, + 356, 357, 358, 0, 359, 360, 361, 362, 363, 364, + 365, 366, 0, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 0, 380, 381, 0, + 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 0, 398, 399, 400, 401, + 402, 0, 404, 405, 406, 407, 408, 0, 410, 411, + 412, 413, 0, 414, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 425, 507, 427, 428, 429, 0, + 430, 431, 0, 432, 0, 434, 435, 436, 437, 438, + 0, 439, 440, 0, 0, 441, 442, 443, 444, 445, + 0, 446, 447, 448, 449, 450, 451, 452, 453, 0, + 0, 454, 455, 456, 457, 458, 459, 0, 0, 461, + 462, 463, 464, 465, 466, 467, 0, 468, 0, 470, + 471, 472, 473, 474, 0, 0, 475, 0, 0, 476, + 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, + 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, + 504, 0, 530, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 105, 106, + 107, 108, 109, 110, 111, 112, 0, 113, 114, 115, + 0, 0, 0, 0, 0, 0, 0, 116, 117, 0, + 118, 119, 120, 0, 122, 123, 124, 125, 126, 0, + 128, 129, 0, 130, 131, 132, 133, 134, 135, 0, + 0, 136, 137, 138, 139, 140, 0, 141, 142, 143, + 144, 145, 0, 0, 0, 147, 148, 149, 150, 151, + 152, 0, 154, 155, 156, 0, 157, 158, 159, 160, + 161, 162, 0, 0, 164, 165, 166, 0, 0, 0, + 0, 0, 0, 0, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 0, 182, 0, 183, 184, 185, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 0, + 0, 194, 195, 196, 197, 198, 0, 199, 200, 201, + 0, 202, 203, 204, 0, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 0, 216, 0, 217, + 218, 219, 220, 0, 221, 0, 222, 0, 0, 0, + 225, 226, 505, 0, 229, 0, 230, 0, 231, 232, + 233, 0, 234, 235, 236, 237, 238, 721, 240, 0, + 242, 243, 244, 245, 0, 246, 247, 248, 249, 250, + 251, 0, 252, 0, 254, 255, 256, 257, 258, 259, + 260, 261, 0, 262, 0, 263, 0, 0, 266, 0, + 268, 269, 270, 271, 272, 273, 0, 0, 274, 0, + 276, 0, 0, 278, 279, 280, 0, 0, 281, 282, + 283, 284, 285, 506, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 0, 307, 308, 309, 310, 311, 0, + 312, 313, 0, 315, 0, 316, 317, 318, 319, 320, + 321, 0, 322, 323, 0, 621, 324, 325, 326, 0, + 0, 327, 328, 0, 330, 0, 332, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 0, 343, 344, + 345, 0, 347, 348, 349, 350, 351, 352, 0, 353, + 354, 355, 356, 357, 358, 0, 359, 360, 361, 362, + 363, 364, 365, 366, 0, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 0, 380, + 381, 0, 383, 384, 385, 386, 387, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 0, 398, 399, + 400, 401, 402, 0, 404, 405, 406, 407, 408, 0, + 410, 411, 412, 413, 0, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 507, 427, 428, + 429, 0, 430, 431, 0, 432, 0, 434, 435, 436, + 437, 438, 0, 439, 440, 0, 0, 441, 442, 443, + 444, 445, 0, 446, 447, 448, 449, 450, 451, 452, + 453, 0, 0, 454, 455, 456, 457, 458, 459, 0, + 0, 461, 462, 463, 464, 465, 466, 467, 0, 468, + 0, 470, 471, 472, 473, 474, 0, 0, 475, 0, + 0, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, + 495, 496, 504, 0, 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 696, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 509, + 105, 106, 107, 108, 109, 110, 111, 112, 752, 113, + 114, 115, 0, 0, 0, 0, 0, 0, 0, 116, + 117, 0, 118, 119, 120, 0, 122, 123, 124, 125, + 126, 0, 128, 129, 0, 130, 131, 132, 133, 134, + 135, 0, 0, 136, 137, 138, 139, 140, 0, 141, + 142, 143, 144, 145, 0, 0, 0, 147, 148, 149, + 150, 151, 152, 0, 154, 155, 156, 0, 157, 158, + 159, 160, 161, 162, 0, 0, 164, 165, 166, 0, + 0, 0, 0, 0, 0, 0, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 0, 182, 0, 183, + 184, 185, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 0, 0, 194, 195, 196, 197, 198, 0, 199, + 200, 201, 0, 202, 203, 204, 0, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 0, 216, + 0, 217, 218, 219, 220, 0, 221, 0, 222, 0, + 0, 0, 225, 226, 505, 0, 229, 0, 230, 0, + 231, 232, 233, 0, 234, 235, 236, 237, 238, 239, + 240, 0, 242, 243, 244, 245, 0, 246, 247, 248, + 249, 250, 251, 0, 252, 0, 254, 255, 256, 257, + 258, 259, 260, 261, 0, 262, 0, 263, 0, 0, + 266, 0, 268, 269, 270, 271, 272, 273, 0, 0, + 274, 0, 276, 0, 0, 278, 279, 280, 0, 0, + 281, 282, 283, 284, 285, 506, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, 0, 307, 308, 309, 310, + 311, 0, 312, 313, 0, 315, 0, 316, 317, 318, + 319, 320, 321, 0, 322, 323, 0, 0, 324, 325, + 326, 0, 0, 327, 328, 0, 330, 0, 332, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 0, + 343, 344, 345, 0, 347, 348, 349, 350, 351, 352, + 0, 353, 354, 355, 356, 357, 358, 0, 359, 360, + 361, 362, 363, 364, 365, 366, 0, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 0, 380, 381, 0, 383, 384, 385, 386, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 0, + 398, 399, 400, 401, 402, 0, 404, 405, 406, 407, + 408, 0, 410, 411, 412, 413, 0, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 507, + 427, 428, 429, 0, 430, 431, 0, 432, 0, 434, + 435, 436, 437, 438, 0, 439, 440, 0, 0, 441, + 442, 443, 444, 445, 0, 446, 447, 448, 449, 450, + 451, 452, 453, 0, 0, 454, 455, 456, 457, 458, + 459, 0, 0, 461, 462, 463, 464, 465, 466, 467, + 0, 468, 0, 470, 471, 472, 473, 474, 0, 0, + 475, 0, 0, 476, 477, 478, 479, 480, 481, 482, + 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, + 493, 494, 495, 496, 504, 1908, 0, 0, 0, 0, + 1909, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 105, 106, 107, 108, 109, 110, 111, 112, + 0, 113, 114, 115, 0, 0, 0, 0, 0, 0, + 0, 116, 117, 0, 118, 119, 120, 0, 122, 123, + 124, 125, 126, 0, 128, 129, 0, 130, 131, 132, + 133, 134, 135, 0, 0, 136, 137, 138, 139, 140, + 0, 141, 142, 143, 144, 145, 0, 0, 0, 147, + 148, 149, 150, 151, 152, 0, 154, 155, 156, 0, + 157, 158, 159, 160, 161, 162, 0, 0, 164, 165, + 166, 0, 0, 0, 0, 0, 0, 0, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 0, 182, + 0, 183, 184, 185, 186, 187, 188, 0, 189, 190, + 191, 192, 193, 0, 0, 194, 195, 196, 197, 198, + 0, 199, 200, 201, 0, 202, 203, 204, 0, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 0, 216, 0, 217, 218, 219, 220, 0, 221, 0, + 222, 0, 0, 0, 225, 226, 505, 0, 229, 0, + 230, 0, 231, 232, 233, 0, 234, 235, 236, 237, + 238, 239, 240, 0, 242, 243, 244, 245, 0, 246, + 247, 248, 249, 250, 251, 0, 252, 0, 254, 255, + 256, 257, 258, 259, 260, 261, 0, 262, 0, 263, + 0, 0, 266, 0, 268, 269, 270, 271, 272, 273, + 0, 0, 274, 0, 276, 0, 0, 278, 279, 280, + 0, 0, 281, 282, 283, 284, 285, 506, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 0, 307, 308, + 309, 310, 311, 0, 312, 313, 0, 315, 0, 316, + 317, 318, 319, 320, 321, 0, 322, 323, 0, 0, + 324, 325, 326, 0, 0, 327, 328, 0, 330, 0, + 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 0, 343, 344, 345, 0, 347, 348, 349, 350, + 351, 352, 0, 353, 354, 355, 356, 357, 358, 0, + 359, 360, 361, 362, 363, 364, 365, 366, 0, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 0, 380, 381, 0, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 0, 398, 399, 400, 401, 402, 0, 404, 405, + 406, 407, 408, 0, 410, 411, 412, 413, 0, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 507, 427, 428, 429, 0, 430, 431, 0, 432, + 0, 434, 435, 436, 437, 438, 0, 439, 440, 0, + 0, 441, 442, 443, 444, 445, 0, 446, 447, 448, + 449, 450, 451, 452, 453, 0, 0, 454, 455, 456, + 457, 458, 459, 0, 0, 461, 462, 463, 464, 465, + 466, 467, 0, 468, 0, 470, 471, 472, 473, 474, + 0, 0, 475, 0, 0, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, + 491, 492, 493, 494, 495, 496, 504, 0, 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 700, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 0, 0, 0, 0, 105, 106, 107, 108, 109, 110, + 111, 112, 0, 113, 114, 115, 0, 0, 0, 0, + 0, 0, 0, 116, 117, 0, 118, 119, 120, 0, + 122, 123, 124, 125, 126, 0, 128, 129, 0, 130, + 131, 132, 133, 134, 135, 0, 0, 136, 137, 138, + 139, 140, 0, 141, 142, 143, 144, 145, 0, 0, + 0, 147, 148, 149, 150, 151, 152, 0, 154, 155, + 156, 0, 157, 158, 159, 160, 161, 162, 0, 0, + 164, 165, 166, 0, 0, 0, 0, 0, 0, 0, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 0, 182, 0, 183, 184, 185, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 0, 0, 194, 195, 196, + 197, 198, 0, 199, 200, 201, 0, 202, 203, 204, + 0, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 214, 215, 0, 216, 0, 217, 218, 219, 220, 0, + 221, 0, 222, 0, 0, 0, 225, 226, 505, 0, + 1917, 0, 230, 0, 231, 232, 233, 0, 234, 235, + 236, 237, 238, 239, 240, 0, 242, 243, 244, 245, + 0, 246, 247, 248, 249, 250, 251, 0, 252, 0, + 254, 255, 256, 257, 258, 259, 260, 261, 0, 262, + 0, 263, 0, 0, 266, 0, 268, 269, 270, 271, + 272, 273, 0, 0, 274, 0, 276, 0, 0, 278, + 279, 1918, 0, 0, 281, 282, 283, 284, 285, 506, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 509, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 0, + 307, 308, 309, 310, 311, 0, 312, 313, 0, 315, + 0, 316, 317, 318, 319, 320, 321, 0, 322, 323, + 0, 0, 324, 325, 326, 0, 0, 327, 328, 0, + 330, 0, 332, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 0, 343, 344, 345, 0, 347, 348, + 349, 350, 351, 352, 0, 353, 354, 355, 356, 357, + 358, 0, 359, 360, 361, 362, 363, 364, 365, 366, + 0, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 0, 380, 381, 0, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 0, 398, 399, 400, 401, 402, 0, + 404, 405, 406, 407, 408, 0, 410, 411, 412, 413, + 0, 414, 415, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 425, 507, 427, 428, 429, 0, 430, 431, + 1919, 432, 0, 434, 1920, 436, 1921, 438, 0, 439, + 440, 0, 0, 441, 442, 443, 444, 445, 0, 446, + 447, 448, 449, 450, 451, 452, 453, 0, 0, 454, + 455, 1922, 457, 458, 459, 0, 0, 461, 462, 463, + 464, 465, 466, 467, 0, 468, 0, 470, 471, 472, + 473, 474, 0, 0, 475, 0, 0, 476, 477, 478, + 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, + 489, 490, 491, 492, 493, 494, 495, 496, 504, 0, + 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 105, 106, 107, 108, + 109, 110, 111, 112, 0, 113, 114, 115, 0, 0, + 0, 0, 0, 0, 0, 116, 117, 0, 118, 119, + 120, 0, 122, 123, 124, 125, 126, 0, 128, 129, + 0, 130, 131, 132, 133, 134, 135, 0, 0, 136, + 137, 138, 139, 140, 0, 141, 142, 143, 144, 145, + 0, 0, 0, 147, 148, 149, 150, 151, 152, 0, + 154, 155, 156, 0, 157, 158, 159, 160, 161, 162, + 0, 0, 164, 165, 166, 0, 0, 0, 0, 0, + 0, 0, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 0, 182, 0, 183, 184, 185, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 0, 0, 194, + 195, 196, 197, 198, 0, 199, 200, 201, 0, 202, + 203, 204, 0, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 0, 216, 0, 217, 218, 219, + 220, 0, 221, 0, 222, 0, 0, 0, 225, 226, + 505, 0, 229, 0, 230, 0, 231, 232, 233, 0, + 234, 235, 236, 237, 238, 239, 240, 0, 242, 243, + 244, 245, 0, 246, 247, 248, 249, 250, 251, 0, + 252, 0, 254, 255, 256, 257, 258, 259, 260, 261, + 0, 262, 0, 263, 0, 0, 266, 0, 268, 269, + 270, 271, 272, 273, 0, 0, 274, 0, 276, 0, + 0, 278, 279, 280, 0, 0, 281, 282, 283, 284, + 285, 506, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 0, 307, 308, 309, 310, 311, 0, 312, 313, + 0, 315, 0, 316, 317, 318, 319, 320, 321, 0, + 322, 323, 0, 0, 324, 325, 326, 0, 0, 327, + 328, 0, 330, 0, 332, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 0, 343, 344, 345, 0, + 347, 348, 349, 350, 351, 352, 0, 353, 354, 355, + 356, 357, 358, 0, 359, 360, 361, 362, 363, 364, + 365, 366, 0, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 0, 380, 381, 0, + 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 0, 398, 399, 400, 401, + 402, 0, 404, 405, 406, 407, 408, 0, 410, 411, + 412, 413, 0, 414, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 425, 507, 427, 428, 429, 0, + 430, 431, 0, 432, 0, 434, 435, 436, 437, 438, + 0, 439, 440, 0, 0, 441, 442, 443, 444, 445, + 0, 446, 447, 448, 449, 450, 451, 452, 453, 0, + 0, 454, 455, 456, 457, 458, 459, 0, 0, 461, + 462, 463, 464, 465, 466, 467, 0, 468, 0, 470, + 471, 472, 473, 474, 0, 0, 475, 0, 0, 476, + 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, + 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, + 504, 0, 515, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 105, 106, + 107, 108, 109, 110, 111, 112, 0, 113, 114, 115, + 0, 0, 0, 0, 0, 0, 0, 116, 117, 0, + 118, 119, 120, 0, 122, 123, 124, 125, 126, 0, + 128, 129, 0, 130, 131, 132, 133, 134, 135, 0, + 0, 136, 137, 138, 139, 140, 0, 141, 142, 143, + 144, 145, 0, 0, 0, 147, 148, 149, 150, 151, + 152, 0, 154, 155, 156, 0, 157, 158, 159, 160, + 161, 162, 0, 0, 164, 165, 166, 0, 0, 0, + 0, 0, 0, 0, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 0, 182, 0, 183, 184, 185, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 0, + 0, 194, 195, 196, 197, 198, 0, 199, 200, 201, + 0, 202, 203, 204, 0, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 0, 216, 0, 217, + 218, 219, 220, 0, 221, 0, 222, 0, 0, 0, + 225, 226, 505, 0, 229, 0, 230, 0, 231, 232, + 233, 0, 234, 235, 236, 237, 238, 239, 240, 0, + 242, 243, 244, 245, 0, 246, 247, 248, 249, 250, + 251, 0, 252, 0, 254, 255, 256, 257, 258, 259, + 260, 261, 0, 262, 0, 263, 0, 0, 266, 0, + 268, 269, 270, 271, 272, 273, 0, 0, 274, 0, + 276, 0, 0, 278, 279, 280, 0, 0, 281, 282, + 283, 284, 285, 506, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 0, 307, 308, 309, 310, 311, 0, + 312, 313, 0, 315, 0, 316, 317, 318, 319, 320, + 321, 0, 322, 323, 0, 0, 324, 325, 326, 0, + 0, 327, 328, 0, 330, 0, 332, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 0, 343, 344, + 345, 0, 347, 348, 349, 350, 351, 352, 0, 353, + 354, 355, 356, 357, 358, 0, 359, 360, 361, 362, + 363, 364, 365, 366, 0, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 0, 380, + 381, 0, 383, 384, 385, 386, 387, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 0, 398, 399, + 400, 401, 402, 0, 404, 405, 406, 407, 408, 0, + 410, 411, 412, 413, 0, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 507, 427, 428, + 429, 0, 430, 431, 0, 432, 0, 434, 435, 436, + 437, 438, 0, 439, 440, 0, 0, 441, 442, 443, + 444, 445, 0, 446, 447, 448, 449, 450, 451, 452, + 453, 0, 0, 454, 455, 456, 457, 458, 459, 0, + 0, 461, 462, 463, 464, 465, 466, 467, 0, 468, + 0, 470, 471, 472, 473, 474, 0, 0, 475, 0, + 0, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, + 495, 496, 504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 815, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 509, + 105, 106, 107, 108, 109, 110, 111, 112, 653, 113, + 114, 115, 0, 0, 0, 0, 0, 0, 0, 116, + 117, 0, 118, 119, 120, 0, 122, 123, 124, 125, + 126, 0, 128, 129, 0, 130, 131, 132, 133, 134, + 135, 0, 0, 136, 137, 138, 139, 140, 0, 141, + 142, 143, 144, 145, 0, 0, 0, 147, 148, 149, + 150, 151, 152, 0, 154, 155, 156, 0, 157, 158, + 159, 160, 161, 162, 0, 0, 164, 165, 166, 0, + 0, 0, 0, 0, 0, 0, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 0, 182, 0, 183, + 184, 185, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 0, 0, 194, 195, 196, 197, 198, 0, 199, + 200, 201, 0, 202, 203, 204, 0, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 0, 216, + 0, 217, 218, 219, 220, 0, 221, 0, 222, 0, + 0, 0, 225, 226, 505, 0, 229, 0, 230, 0, + 231, 232, 233, 0, 234, 235, 236, 237, 238, 239, + 240, 0, 242, 243, 244, 245, 0, 246, 247, 248, + 249, 250, 251, 0, 252, 0, 254, 255, 256, 257, + 258, 259, 260, 261, 0, 262, 0, 263, 0, 0, + 266, 0, 268, 269, 270, 271, 272, 273, 0, 0, + 274, 0, 276, 0, 0, 278, 279, 280, 0, 0, + 281, 282, 283, 284, 285, 506, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, 0, 307, 308, 309, 310, + 311, 0, 312, 313, 0, 315, 0, 316, 317, 318, + 319, 320, 321, 0, 322, 323, 0, 0, 324, 325, + 326, 0, 0, 327, 328, 0, 330, 0, 332, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 0, + 343, 344, 345, 0, 347, 348, 349, 350, 351, 352, + 0, 353, 354, 355, 356, 357, 358, 0, 359, 360, + 361, 362, 363, 364, 365, 366, 0, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 0, 380, 381, 0, 383, 384, 385, 386, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 0, + 398, 399, 400, 401, 402, 0, 404, 405, 406, 407, + 408, 0, 410, 411, 412, 413, 0, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 507, + 427, 428, 429, 0, 430, 431, 0, 432, 0, 434, + 435, 436, 437, 438, 0, 654, 440, 0, 0, 655, + 442, 443, 444, 445, 0, 446, 447, 448, 449, 450, + 451, 452, 453, 0, 0, 454, 455, 456, 457, 458, + 459, 0, 0, 461, 462, 463, 464, 465, 466, 467, + 0, 468, 0, 470, 471, 472, 473, 474, 0, 0, + 475, 0, 0, 476, 477, 478, 479, 480, 481, 482, + 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, + 493, 494, 495, 496, 504, 0, 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 818, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 0, + 0, 0, 105, 106, 107, 108, 109, 110, 111, 112, + 0, 113, 114, 115, 0, 0, 0, 0, 0, 0, + 0, 116, 117, 0, 118, 119, 120, 0, 122, 123, + 124, 125, 126, 0, 128, 129, 0, 130, 131, 132, + 133, 134, 135, 0, 0, 136, 137, 138, 139, 140, + 0, 141, 142, 143, 144, 145, 0, 0, 0, 147, + 148, 149, 150, 151, 152, 0, 154, 155, 156, 0, + 157, 158, 159, 160, 161, 162, 0, 0, 164, 165, + 166, 0, 0, 0, 0, 0, 0, 0, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 0, 182, + 0, 183, 184, 185, 186, 187, 188, 0, 189, 190, + 191, 192, 193, 0, 0, 194, 195, 196, 197, 198, + 0, 199, 200, 201, 0, 202, 203, 204, 0, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 0, 216, 0, 217, 218, 219, 220, 0, 221, 0, + 222, 0, 0, 0, 225, 226, 505, 0, 229, 0, + 230, 0, 231, 232, 233, 0, 234, 235, 236, 237, + 238, 239, 240, 0, 242, 243, 244, 245, 0, 246, + 247, 248, 249, 250, 251, 0, 252, 0, 254, 255, + 256, 257, 258, 259, 260, 261, 0, 262, 0, 263, + 0, 0, 266, 0, 268, 269, 270, 271, 272, 273, + 0, 0, 274, 0, 276, 0, 0, 278, 279, 280, + 0, 0, 281, 282, 283, 284, 285, 506, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 0, 307, 308, + 309, 310, 311, 0, 312, 313, 0, 315, 0, 316, + 317, 318, 319, 320, 321, 0, 322, 323, 0, 0, + 324, 325, 326, 0, 0, 327, 328, 0, 330, 0, + 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 0, 343, 344, 345, 0, 347, 348, 349, 350, + 351, 352, 0, 353, 354, 355, 356, 357, 358, 0, + 359, 360, 361, 362, 363, 364, 687, 366, 0, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 0, 380, 381, 0, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 0, 398, 399, 400, 401, 402, 0, 404, 405, + 406, 407, 408, 0, 410, 411, 412, 413, 0, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 507, 427, 428, 429, 0, 430, 431, 0, 432, + 0, 434, 435, 436, 437, 438, 0, 439, 440, 0, + 0, 441, 442, 443, 444, 445, 0, 446, 447, 448, + 449, 450, 451, 452, 453, 0, 0, 454, 455, 456, + 457, 458, 459, 0, 0, 461, 462, 463, 464, 465, + 466, 467, 0, 468, 0, 470, 471, 472, 473, 474, + 0, 0, 475, 0, 0, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, + 491, 492, 493, 494, 495, 496, 504, 0, 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 942, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 0, 0, 0, 0, 105, 106, 107, 108, 109, 110, + 111, 112, 0, 113, 114, 115, 0, 0, 0, 0, + 0, 0, 0, 116, 117, 0, 118, 119, 120, 0, + 122, 123, 124, 125, 126, 0, 128, 129, 0, 130, + 131, 132, 133, 134, 135, 0, 0, 136, 137, 138, + 139, 140, 0, 141, 142, 143, 144, 145, 0, 0, + 0, 147, 148, 149, 150, 151, 152, 0, 154, 155, + 156, 0, 157, 158, 159, 160, 161, 162, 0, 0, + 164, 165, 166, 0, 0, 0, 0, 0, 0, 0, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 0, 182, 0, 183, 184, 185, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 0, 0, 194, 195, 196, + 197, 198, 0, 199, 200, 201, 0, 202, 203, 204, + 0, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 214, 215, 0, 216, 0, 217, 218, 219, 220, 0, + 221, 0, 222, 0, 0, 0, 225, 226, 505, 0, + 229, 0, 230, 0, 231, 232, 233, 0, 234, 235, + 236, 237, 238, 716, 240, 0, 242, 243, 244, 245, + 0, 246, 247, 248, 249, 250, 251, 0, 252, 0, + 254, 255, 256, 257, 258, 259, 260, 261, 0, 262, + 0, 263, 0, 0, 266, 0, 268, 269, 270, 271, + 272, 273, 0, 0, 274, 0, 276, 0, 0, 278, + 279, 280, 0, 0, 281, 282, 283, 284, 285, 506, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 0, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 0, + 307, 308, 309, 310, 311, 0, 312, 313, 0, 315, + 0, 316, 317, 318, 319, 320, 321, 0, 322, 323, + 0, 0, 324, 325, 326, 0, 0, 327, 328, 0, + 330, 0, 332, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 0, 343, 344, 345, 0, 347, 348, + 349, 350, 351, 352, 0, 353, 354, 355, 356, 357, + 358, 0, 359, 360, 361, 362, 363, 364, 365, 366, + 0, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 0, 380, 381, 0, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 0, 398, 399, 400, 401, 402, 0, + 404, 405, 406, 407, 408, 0, 410, 411, 412, 413, + 0, 414, 415, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 425, 507, 427, 428, 429, 0, 430, 431, + 0, 432, 0, 434, 435, 436, 437, 438, 0, 439, + 440, 0, 0, 441, 442, 443, 444, 445, 0, 446, + 447, 448, 449, 450, 451, 452, 453, 0, 0, 454, + 455, 456, 457, 458, 459, 0, 0, 461, 462, 463, + 464, 465, 466, 467, 0, 468, 0, 470, 471, 472, + 473, 474, 0, 0, 475, 0, 0, 476, 477, 478, + 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, + 489, 490, 491, 492, 493, 494, 495, 496, 504, 0, + 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 105, 106, 107, 108, + 109, 110, 111, 112, 0, 113, 114, 115, 0, 0, + 0, 0, 0, 0, 0, 116, 117, 0, 118, 119, + 120, 0, 122, 123, 124, 125, 126, 0, 128, 129, + 0, 130, 131, 132, 133, 134, 135, 0, 0, 136, + 137, 138, 139, 140, 0, 141, 142, 143, 144, 145, + 0, 0, 0, 147, 148, 149, 150, 151, 152, 0, + 154, 155, 156, 0, 157, 158, 159, 160, 161, 162, + 0, 0, 164, 165, 166, 0, 0, 0, 0, 0, + 0, 0, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 0, 182, 0, 183, 184, 185, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 0, 0, 194, + 195, 196, 197, 198, 0, 199, 200, 201, 0, 202, + 203, 204, 0, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 0, 216, 0, 217, 218, 219, + 220, 0, 221, 0, 222, 0, 0, 0, 225, 226, + 505, 0, 229, 0, 230, 0, 231, 232, 233, 0, + 234, 235, 236, 237, 238, 719, 240, 0, 242, 243, + 244, 245, 0, 246, 247, 248, 249, 250, 251, 0, + 252, 0, 254, 255, 256, 257, 258, 259, 260, 261, + 0, 262, 0, 263, 0, 0, 266, 0, 268, 269, + 270, 271, 272, 273, 0, 0, 274, 0, 276, 0, + 0, 278, 279, 280, 0, 0, 281, 282, 283, 284, + 285, 506, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 0, 307, 308, 309, 310, 311, 0, 312, 313, + 0, 315, 0, 316, 317, 318, 319, 320, 321, 0, + 322, 323, 0, 0, 324, 325, 326, 0, 0, 327, + 328, 0, 330, 0, 332, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 0, 343, 344, 345, 0, + 347, 348, 349, 350, 351, 352, 0, 353, 354, 355, + 356, 357, 358, 0, 359, 360, 361, 362, 363, 364, + 365, 366, 0, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 0, 380, 381, 0, + 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 0, 398, 399, 400, 401, + 402, 0, 404, 405, 406, 407, 408, 0, 410, 411, + 412, 413, 0, 414, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 425, 507, 427, 428, 429, 0, + 430, 431, 0, 432, 0, 434, 435, 436, 437, 438, + 0, 439, 440, 0, 0, 441, 442, 443, 444, 445, + 0, 446, 447, 448, 449, 450, 451, 452, 453, 0, + 0, 454, 455, 456, 457, 458, 459, 0, 0, 461, + 462, 463, 464, 465, 466, 467, 0, 468, 0, 470, + 471, 472, 473, 474, 0, 0, 475, 0, 0, 476, + 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, + 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, + 504, 0, 530, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 105, 106, + 107, 108, 109, 110, 111, 112, 0, 113, 114, 115, + 0, 0, 0, 0, 0, 0, 0, 116, 117, 0, + 118, 119, 120, 0, 122, 123, 124, 125, 126, 0, + 128, 129, 0, 130, 131, 132, 133, 134, 135, 0, + 0, 136, 137, 138, 139, 140, 0, 141, 142, 143, + 144, 145, 0, 0, 0, 147, 148, 149, 150, 151, + 152, 0, 154, 155, 156, 0, 157, 158, 159, 160, + 161, 162, 0, 0, 164, 165, 166, 0, 0, 0, + 0, 0, 0, 0, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 0, 182, 0, 183, 184, 185, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 0, + 0, 194, 195, 196, 197, 198, 0, 199, 200, 201, + 0, 202, 203, 204, 0, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 0, 216, 0, 217, + 218, 219, 220, 0, 221, 0, 222, 0, 0, 0, + 225, 226, 505, 0, 229, 0, 230, 0, 231, 232, + 233, 0, 234, 235, 236, 237, 238, 723, 240, 0, + 242, 243, 244, 245, 0, 246, 247, 248, 249, 250, + 251, 0, 252, 0, 254, 255, 256, 257, 258, 259, + 260, 261, 0, 262, 0, 263, 0, 0, 266, 0, + 268, 269, 270, 271, 272, 273, 0, 0, 274, 0, + 276, 0, 0, 278, 279, 280, 0, 0, 281, 282, + 283, 284, 285, 506, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 0, 307, 308, 309, 310, 311, 0, + 312, 313, 0, 315, 0, 316, 317, 318, 319, 320, + 321, 0, 322, 323, 0, 0, 324, 325, 326, 0, + 0, 327, 328, 0, 330, 0, 332, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 0, 343, 344, + 345, 0, 347, 348, 349, 350, 351, 352, 0, 353, + 354, 355, 356, 357, 358, 0, 359, 360, 361, 362, + 363, 364, 365, 366, 0, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 0, 380, + 381, 0, 383, 384, 385, 386, 387, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 0, 398, 399, + 400, 401, 402, 0, 404, 405, 406, 407, 408, 0, + 410, 411, 412, 413, 0, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 507, 427, 428, + 429, 0, 430, 431, 0, 432, 0, 434, 435, 436, + 437, 438, 0, 439, 440, 0, 0, 441, 442, 443, + 444, 445, 0, 446, 447, 448, 449, 450, 451, 452, + 453, 0, 0, 454, 455, 456, 457, 458, 459, 0, + 0, 461, 462, 463, 464, 465, 466, 467, 0, 468, + 0, 470, 471, 472, 473, 474, 0, 0, 475, 0, + 0, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, + 495, 496, 504, 0, 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 959, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 509, + 105, 106, 107, 108, 109, 110, 111, 112, 0, 113, + 114, 115, 0, 0, 0, 0, 0, 0, 0, 116, + 117, 0, 118, 119, 120, 0, 122, 123, 124, 125, + 126, 0, 128, 129, 0, 130, 131, 132, 133, 134, + 135, 0, 0, 136, 137, 138, 139, 140, 0, 141, + 142, 143, 144, 145, 0, 0, 0, 147, 148, 149, + 150, 151, 152, 0, 154, 155, 156, 0, 157, 158, + 159, 160, 161, 162, 0, 0, 164, 165, 166, 0, + 0, 0, 0, 0, 0, 0, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 0, 182, 0, 183, + 184, 185, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 0, 0, 194, 195, 196, 197, 198, 0, 199, + 200, 201, 0, 202, 203, 204, 0, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 0, 216, + 0, 217, 218, 219, 220, 0, 221, 0, 222, 0, + 0, 0, 225, 226, 505, 0, 229, 0, 230, 0, + 231, 232, 233, 0, 234, 235, 236, 237, 238, 733, + 240, 0, 242, 243, 244, 245, 0, 246, 247, 248, + 249, 250, 251, 0, 252, 0, 254, 255, 256, 257, + 258, 259, 260, 261, 0, 262, 0, 263, 0, 0, + 266, 0, 268, 269, 270, 271, 272, 273, 0, 0, + 274, 0, 276, 0, 0, 278, 279, 280, 0, 0, + 281, 282, 283, 284, 285, 506, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, 0, 307, 308, 309, 310, + 311, 0, 312, 313, 0, 315, 0, 316, 317, 318, + 319, 320, 321, 0, 322, 323, 0, 0, 324, 325, + 326, 0, 0, 327, 328, 0, 330, 0, 332, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 0, + 343, 344, 345, 0, 347, 348, 349, 350, 351, 352, + 0, 353, 354, 355, 356, 357, 358, 0, 359, 360, + 361, 362, 363, 364, 365, 366, 0, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 0, 380, 381, 0, 383, 384, 385, 386, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 0, + 398, 399, 400, 401, 402, 0, 404, 405, 406, 407, + 408, 0, 410, 411, 412, 413, 0, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 507, + 427, 428, 429, 0, 430, 431, 0, 432, 0, 434, + 435, 436, 437, 438, 0, 439, 440, 0, 0, 441, + 442, 443, 444, 445, 0, 446, 447, 448, 449, 450, + 451, 452, 453, 0, 0, 454, 455, 456, 457, 458, + 459, 0, 0, 461, 462, 463, 464, 465, 466, 467, + 0, 468, 0, 470, 471, 472, 473, 474, 0, 0, + 475, 0, 0, 476, 477, 478, 479, 480, 481, 482, + 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, + 493, 494, 495, 496, 504, 0, 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 1292, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 509, + 0, 0, 105, 106, 107, 108, 109, 110, 111, 112, + 0, 113, 114, 115, 0, 0, 0, 0, 0, 0, + 0, 116, 117, 0, 118, 119, 120, 0, 122, 123, + 124, 125, 126, 0, 128, 129, 0, 130, 131, 132, + 133, 134, 135, 0, 0, 136, 137, 138, 139, 140, + 0, 141, 142, 143, 144, 145, 0, 0, 0, 147, + 148, 149, 150, 151, 152, 0, 154, 155, 156, 0, + 157, 158, 159, 160, 161, 162, 0, 0, 164, 165, + 166, 0, 0, 0, 0, 0, 0, 0, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 0, 182, + 0, 183, 184, 185, 186, 187, 188, 0, 189, 190, + 191, 192, 193, 0, 0, 194, 195, 196, 197, 198, + 0, 199, 200, 201, 0, 202, 203, 204, 0, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 0, 216, 0, 217, 218, 219, 220, 0, 221, 0, + 222, 0, 0, 0, 225, 226, 505, 0, 229, 0, + 230, 0, 231, 232, 233, 0, 234, 235, 236, 237, + 238, 740, 240, 0, 242, 243, 244, 245, 0, 246, + 247, 248, 249, 250, 251, 0, 252, 0, 254, 255, + 256, 257, 258, 259, 260, 261, 0, 262, 0, 263, + 0, 0, 266, 0, 268, 269, 270, 271, 272, 273, + 0, 0, 274, 0, 276, 0, 0, 278, 279, 280, + 0, 0, 281, 282, 283, 284, 285, 506, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 0, 307, 308, + 309, 310, 311, 0, 312, 313, 0, 315, 0, 316, + 317, 318, 319, 320, 321, 0, 322, 323, 0, 0, + 324, 325, 326, 0, 0, 327, 328, 0, 330, 0, + 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 0, 343, 344, 345, 0, 347, 348, 349, 350, + 351, 352, 0, 353, 354, 355, 356, 357, 358, 0, + 359, 360, 361, 362, 363, 364, 365, 366, 0, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 0, 380, 381, 0, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 0, 398, 399, 400, 401, 402, 0, 404, 405, + 406, 407, 408, 0, 410, 411, 412, 413, 0, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 507, 427, 428, 429, 0, 430, 431, 0, 432, + 0, 434, 435, 436, 437, 438, 0, 439, 440, 0, + 0, 441, 442, 443, 444, 445, 0, 446, 447, 448, + 449, 450, 451, 452, 453, 0, 0, 454, 455, 456, + 457, 458, 459, 0, 0, 461, 462, 463, 464, 465, + 466, 467, 0, 468, 0, 470, 471, 472, 473, 474, + 0, 0, 475, 0, 0, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, + 491, 492, 493, 494, 495, 496, 504, 0, 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 1294, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 0, 0, 0, 0, 105, 106, 107, 108, 109, 110, + 111, 112, 0, 113, 114, 115, 0, 0, 0, 0, + 0, 0, 0, 116, 117, 0, 118, 119, 120, 0, + 122, 123, 124, 125, 126, 0, 128, 129, 0, 130, + 131, 132, 133, 134, 135, 0, 0, 136, 137, 138, + 139, 140, 0, 141, 142, 143, 144, 145, 0, 0, + 0, 147, 148, 149, 150, 151, 152, 0, 154, 155, + 156, 0, 157, 158, 159, 160, 161, 162, 0, 0, + 164, 165, 166, 0, 0, 0, 0, 0, 0, 0, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 0, 182, 0, 183, 184, 185, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 0, 0, 194, 195, 196, + 197, 198, 0, 199, 200, 201, 0, 202, 203, 204, + 0, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 214, 215, 0, 216, 0, 217, 218, 219, 220, 0, + 221, 0, 222, 0, 0, 0, 225, 226, 505, 0, + 229, 0, 230, 0, 231, 232, 233, 0, 234, 235, + 236, 237, 238, 846, 240, 0, 242, 243, 244, 245, + 0, 246, 247, 248, 249, 250, 251, 0, 252, 0, + 254, 255, 256, 257, 258, 259, 260, 261, 0, 262, + 0, 263, 0, 0, 266, 0, 268, 269, 270, 271, + 272, 273, 0, 0, 274, 0, 276, 0, 0, 278, + 279, 280, 0, 0, 281, 282, 283, 284, 285, 506, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 509, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 0, + 307, 308, 309, 310, 311, 0, 312, 313, 0, 315, + 0, 316, 317, 318, 319, 320, 321, 0, 322, 323, + 0, 0, 324, 325, 326, 0, 0, 327, 328, 0, + 330, 0, 332, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 0, 343, 344, 345, 0, 347, 348, + 349, 350, 351, 352, 0, 353, 354, 355, 356, 357, + 358, 0, 359, 360, 361, 362, 363, 364, 365, 366, + 0, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 0, 380, 381, 0, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 0, 398, 399, 400, 401, 402, 0, + 404, 405, 406, 407, 408, 0, 410, 411, 412, 413, + 0, 414, 415, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 425, 507, 427, 428, 429, 0, 430, 431, + 0, 432, 0, 434, 435, 436, 437, 438, 0, 439, + 440, 0, 0, 441, 442, 443, 444, 445, 0, 446, + 447, 448, 449, 450, 451, 452, 453, 0, 0, 454, + 455, 456, 457, 458, 459, 0, 0, 461, 462, 463, + 464, 465, 466, 467, 0, 468, 0, 470, 471, 472, + 473, 474, 0, 0, 475, 0, 0, 476, 477, 478, + 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, + 489, 490, 491, 492, 493, 494, 495, 496, 504, 0, + 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 105, 106, 107, 108, + 109, 110, 111, 112, 0, 113, 114, 115, 0, 0, + 0, 0, 0, 0, 0, 116, 117, 0, 118, 119, + 120, 0, 122, 123, 124, 125, 126, 0, 128, 129, + 0, 130, 131, 132, 133, 134, 135, 0, 0, 136, + 137, 138, 139, 140, 0, 141, 142, 143, 144, 145, + 0, 0, 0, 147, 148, 149, 150, 151, 152, 0, + 154, 155, 156, 0, 157, 158, 159, 160, 161, 162, + 0, 0, 164, 165, 166, 0, 0, 0, 0, 0, + 0, 0, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 0, 182, 0, 183, 184, 185, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 0, 0, 194, + 195, 196, 197, 198, 0, 199, 200, 201, 0, 202, + 203, 204, 0, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 0, 216, 0, 217, 218, 219, + 220, 0, 221, 0, 222, 0, 0, 0, 225, 226, + 505, 0, 229, 0, 230, 0, 231, 232, 233, 0, + 234, 235, 236, 237, 238, 849, 240, 0, 242, 243, + 244, 245, 0, 246, 247, 248, 249, 250, 251, 0, + 252, 0, 254, 255, 256, 257, 258, 259, 260, 261, + 0, 262, 0, 263, 0, 0, 266, 0, 268, 269, + 270, 271, 272, 273, 0, 0, 274, 0, 276, 0, + 0, 278, 279, 280, 0, 0, 281, 282, 283, 284, + 285, 506, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 0, 307, 308, 309, 310, 311, 0, 312, 313, + 0, 315, 0, 316, 317, 318, 319, 320, 321, 0, + 322, 323, 0, 0, 324, 325, 326, 0, 0, 327, + 328, 0, 330, 0, 332, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 0, 343, 344, 345, 0, + 347, 348, 349, 350, 351, 352, 0, 353, 354, 355, + 356, 357, 358, 0, 359, 360, 361, 362, 363, 364, + 365, 366, 0, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 0, 380, 381, 0, + 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 0, 398, 399, 400, 401, + 402, 0, 404, 405, 406, 407, 408, 0, 410, 411, + 412, 413, 0, 414, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 425, 507, 427, 428, 429, 0, + 430, 431, 0, 432, 0, 434, 435, 436, 437, 438, + 0, 439, 440, 0, 0, 441, 442, 443, 444, 445, + 0, 446, 447, 448, 449, 450, 451, 452, 453, 0, + 0, 454, 455, 456, 457, 458, 459, 0, 0, 461, + 462, 463, 464, 465, 466, 467, 0, 468, 0, 470, + 471, 472, 473, 474, 0, 0, 475, 0, 0, 476, + 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, + 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, + 504, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 105, 106, + 107, 108, 109, 110, 111, 112, 0, 113, 114, 115, + 0, 0, 0, 0, 0, 977, 0, 116, 117, 0, + 118, 119, 120, 0, 122, 123, 124, 125, 126, 0, + 128, 129, 0, 130, 131, 132, 133, 134, 135, 0, + 0, 136, 137, 138, 139, 140, 0, 141, 142, 143, + 144, 145, 0, 0, 0, 147, 148, 149, 150, 151, + 152, 0, 154, 155, 156, 0, 157, 158, 159, 160, + 161, 162, 0, 0, 164, 165, 166, 0, 0, 0, + 0, 0, 0, 0, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 0, 182, 0, 183, 184, 185, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 0, + 0, 194, 195, 196, 197, 198, 0, 199, 200, 201, + 0, 202, 203, 204, 0, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 0, 216, 0, 217, + 218, 219, 220, 0, 221, 0, 222, 0, 0, 0, + 225, 226, 505, 0, 229, 0, 230, 0, 231, 232, + 233, 0, 234, 235, 236, 237, 238, 239, 240, 0, + 242, 243, 244, 245, 0, 246, 247, 248, 249, 250, + 251, 0, 252, 0, 254, 255, 256, 257, 258, 259, + 260, 261, 0, 262, 0, 263, 0, 0, 266, 0, + 268, 269, 270, 271, 272, 273, 0, 0, 274, 0, + 276, 0, 0, 278, 279, 280, 0, 0, 281, 282, + 283, 284, 285, 506, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 0, 307, 308, 309, 310, 311, 0, + 312, 313, 0, 315, 0, 316, 317, 318, 319, 320, + 321, 0, 322, 323, 0, 0, 324, 325, 326, 0, + 0, 327, 328, 0, 330, 0, 332, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 0, 343, 344, + 345, 0, 347, 348, 349, 350, 351, 352, 0, 353, + 354, 355, 356, 357, 358, 0, 359, 360, 361, 362, + 363, 364, 365, 366, 0, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 0, 380, + 381, 0, 383, 384, 385, 386, 387, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 0, 398, 399, + 400, 401, 402, 0, 404, 405, 406, 407, 408, 0, + 410, 411, 412, 413, 0, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 507, 427, 428, + 429, 0, 430, 431, 0, 432, 0, 434, 435, 436, + 437, 438, 0, 439, 440, 0, 0, 441, 442, 443, + 444, 445, 0, 446, 447, 448, 449, 450, 451, 452, + 453, 0, 0, 454, 455, 456, 457, 458, 459, 0, + 0, 461, 462, 463, 464, 465, 466, 467, 0, 468, + 0, 470, 471, 472, 473, 474, 0, 0, 475, 0, + 0, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, + 495, 496, 504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 1298, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 509, + 105, 106, 107, 108, 109, 110, 111, 112, 0, 113, + 114, 115, 0, 0, 0, 0, 0, 995, 0, 116, + 117, 0, 118, 119, 120, 0, 122, 123, 124, 125, + 126, 0, 128, 129, 0, 130, 131, 132, 133, 134, + 135, 0, 0, 136, 137, 138, 139, 140, 0, 141, + 142, 143, 144, 145, 0, 0, 0, 147, 148, 149, + 150, 151, 152, 0, 154, 155, 156, 0, 157, 158, + 159, 160, 161, 162, 0, 0, 164, 165, 166, 0, + 0, 0, 0, 0, 0, 0, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 0, 182, 0, 183, + 184, 185, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 0, 0, 194, 195, 196, 197, 198, 0, 199, + 200, 201, 0, 202, 203, 204, 0, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 0, 216, + 0, 217, 218, 219, 220, 0, 221, 0, 222, 0, + 0, 0, 225, 226, 505, 0, 229, 0, 230, 0, + 231, 232, 233, 0, 234, 235, 236, 237, 238, 239, + 240, 0, 242, 243, 244, 245, 0, 246, 247, 248, + 249, 250, 251, 0, 252, 0, 254, 255, 256, 257, + 258, 259, 260, 261, 0, 262, 0, 263, 0, 0, + 266, 0, 268, 269, 270, 271, 272, 273, 0, 0, + 274, 0, 276, 0, 0, 278, 279, 280, 0, 0, + 281, 282, 283, 284, 285, 506, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, 0, 307, 308, 309, 310, + 311, 0, 312, 313, 0, 315, 0, 316, 317, 318, + 319, 320, 321, 0, 322, 323, 0, 0, 324, 325, + 326, 0, 0, 327, 328, 0, 330, 0, 332, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 0, + 343, 344, 345, 0, 347, 348, 349, 350, 351, 352, + 0, 353, 354, 355, 356, 357, 358, 0, 359, 360, + 361, 362, 363, 364, 365, 366, 0, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 0, 380, 381, 0, 383, 384, 385, 386, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 0, + 398, 399, 400, 401, 402, 0, 404, 405, 406, 407, + 408, 0, 410, 411, 412, 413, 0, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 507, + 427, 428, 429, 0, 430, 431, 0, 432, 0, 434, + 435, 436, 437, 438, 0, 439, 440, 0, 0, 441, + 442, 443, 444, 445, 0, 446, 447, 448, 449, 450, + 451, 452, 453, 0, 0, 454, 455, 456, 457, 458, + 459, 0, 0, 461, 462, 463, 464, 465, 466, 467, + 0, 468, 0, 470, 471, 472, 473, 474, 0, 0, + 475, 0, 0, 476, 477, 478, 479, 480, 481, 482, + 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, + 493, 494, 495, 496, 504, 0, 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 2074, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 509, + 0, 0, 105, 106, 107, 108, 109, 110, 111, 112, + 0, 113, 114, 115, 0, 0, 0, 0, 0, 0, + 0, 116, 117, 0, 118, 119, 120, 0, 122, 123, + 124, 125, 126, 0, 128, 129, 0, 130, 131, 132, + 133, 134, 135, 0, 0, 136, 137, 138, 139, 140, + 0, 141, 142, 143, 144, 145, 0, 0, 0, 147, + 148, 149, 150, 151, 152, 0, 154, 155, 156, 0, + 157, 158, 159, 160, 161, 162, 0, 0, 164, 165, + 166, 0, 0, 0, 0, 0, 0, 0, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 0, 182, + 0, 183, 184, 185, 186, 187, 188, 0, 189, 190, + 191, 192, 193, 0, 0, 194, 195, 196, 197, 198, + 0, 199, 200, 201, 0, 202, 203, 204, 0, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 0, 216, 0, 217, 218, 219, 220, 0, 221, 0, + 222, 0, 0, 0, 225, 226, 505, 0, 229, 0, + 230, 0, 231, 232, 233, 0, 234, 235, 236, 237, + 238, 1336, 240, 0, 242, 243, 244, 245, 0, 246, + 247, 248, 249, 250, 251, 0, 252, 0, 254, 255, + 256, 257, 258, 259, 260, 261, 0, 262, 0, 263, + 0, 0, 266, 0, 268, 269, 270, 271, 272, 273, + 0, 0, 274, 0, 276, 0, 0, 278, 279, 280, + 0, 0, 281, 282, 283, 284, 285, 506, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 0, 307, 308, + 309, 310, 311, 0, 312, 313, 0, 315, 0, 316, + 317, 318, 319, 320, 321, 0, 322, 323, 0, 0, + 324, 325, 326, 0, 0, 327, 328, 0, 330, 0, + 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 0, 343, 344, 345, 0, 347, 348, 349, 350, + 351, 352, 0, 353, 354, 355, 356, 357, 358, 0, + 359, 360, 361, 362, 363, 364, 365, 366, 0, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 0, 380, 381, 0, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 0, 398, 399, 400, 401, 402, 0, 404, 405, + 406, 407, 408, 0, 410, 411, 412, 413, 0, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 507, 427, 428, 429, 0, 430, 431, 0, 432, + 0, 434, 435, 436, 437, 438, 0, 439, 440, 0, + 0, 441, 442, 443, 444, 445, 0, 446, 447, 448, + 449, 450, 451, 452, 453, 0, 0, 454, 455, 456, + 457, 458, 459, 0, 0, 461, 462, 463, 464, 465, + 466, 467, 0, 468, 0, 470, 471, 472, 473, 474, + 0, 0, 475, 0, 0, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, + 491, 492, 493, 494, 495, 496, 504, 0, 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 2731, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 0, 0, 0, 0, 105, 106, 107, 108, 109, 110, + 111, 112, 0, 113, 114, 115, 0, 0, 0, 0, + 0, 0, 0, 116, 117, 0, 118, 119, 120, 0, + 122, 123, 124, 125, 126, 0, 128, 129, 0, 130, + 131, 132, 133, 134, 135, 0, 0, 136, 137, 138, + 139, 140, 0, 141, 142, 143, 144, 145, 0, 0, + 0, 147, 148, 149, 150, 151, 152, 0, 154, 155, + 156, 0, 157, 158, 159, 160, 161, 162, 0, 0, + 164, 165, 166, 0, 0, 0, 0, 0, 0, 0, + 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, + 0, 182, 0, 183, 184, 185, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 0, 0, 194, 195, 196, + 197, 198, 0, 199, 200, 201, 0, 202, 203, 204, + 0, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 214, 215, 0, 216, 0, 217, 218, 219, 220, 0, + 221, 0, 222, 0, 0, 0, 225, 226, 505, 0, + 229, 0, 230, 0, 231, 232, 233, 0, 234, 235, + 236, 237, 238, 1338, 240, 0, 242, 243, 244, 245, + 0, 246, 247, 248, 249, 250, 251, 0, 252, 0, + 254, 255, 256, 257, 258, 259, 260, 261, 0, 262, + 0, 263, 0, 0, 266, 0, 268, 269, 270, 271, + 272, 273, 0, 0, 274, 0, 276, 0, 0, 278, + 279, 280, 0, 0, 281, 282, 283, 284, 285, 506, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 0, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 0, + 307, 308, 309, 310, 311, 0, 312, 313, 0, 315, + 0, 316, 317, 318, 319, 320, 321, 0, 322, 323, + 0, 0, 324, 325, 326, 0, 0, 327, 328, 0, + 330, 0, 332, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 0, 343, 344, 345, 0, 347, 348, + 349, 350, 351, 352, 0, 353, 354, 355, 356, 357, + 358, 0, 359, 360, 361, 362, 363, 364, 365, 366, + 0, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 0, 380, 381, 0, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 0, 398, 399, 400, 401, 402, 0, + 404, 405, 406, 407, 408, 0, 410, 411, 412, 413, + 0, 414, 415, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 425, 507, 427, 428, 429, 0, 430, 431, + 0, 432, 0, 434, 435, 436, 437, 438, 0, 439, + 440, 0, 0, 441, 442, 443, 444, 445, 0, 446, + 447, 448, 449, 450, 451, 452, 453, 0, 0, 454, + 455, 456, 457, 458, 459, 0, 0, 461, 462, 463, + 464, 465, 466, 467, 0, 468, 0, 470, 471, 472, + 473, 474, 0, 0, 475, 0, 0, 476, 477, 478, + 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, + 489, 490, 491, 492, 493, 494, 495, 496, 504, 0, + 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 105, 106, 107, 108, + 109, 110, 111, 112, 0, 113, 114, 115, 0, 0, + 0, 0, 0, 0, 0, 116, 117, 0, 118, 119, + 120, 0, 122, 123, 124, 125, 126, 0, 128, 129, + 0, 130, 131, 132, 133, 134, 135, 0, 0, 136, + 137, 138, 139, 140, 0, 141, 142, 143, 144, 145, + 0, 0, 0, 147, 148, 149, 150, 151, 152, 0, + 154, 155, 156, 0, 157, 158, 159, 160, 161, 162, + 0, 0, 164, 165, 166, 0, 0, 0, 0, 0, + 0, 0, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 0, 182, 0, 183, 184, 185, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 0, 0, 194, + 195, 196, 197, 198, 0, 199, 200, 201, 0, 202, + 203, 204, 0, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 0, 216, 0, 217, 218, 219, + 220, 0, 221, 0, 222, 0, 0, 0, 225, 226, + 505, 0, 229, 0, 230, 0, 231, 232, 233, 0, + 234, 235, 236, 237, 238, 1341, 240, 0, 242, 243, + 244, 245, 0, 246, 247, 248, 249, 250, 251, 0, + 252, 0, 254, 255, 256, 257, 258, 259, 260, 261, + 0, 262, 0, 263, 0, 0, 266, 0, 268, 269, + 270, 271, 272, 273, 0, 0, 274, 0, 276, 0, + 0, 278, 279, 280, 0, 0, 281, 282, 283, 284, + 285, 506, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 0, 307, 308, 309, 310, 311, 0, 312, 313, + 0, 315, 0, 316, 317, 318, 319, 320, 321, 0, + 322, 323, 0, 0, 324, 325, 326, 0, 0, 327, + 328, 0, 330, 0, 332, 333, 334, 335, 336, 337, + 338, 339, 340, 341, 342, 0, 343, 344, 345, 0, + 347, 348, 349, 350, 351, 352, 0, 353, 354, 355, + 356, 357, 358, 0, 359, 360, 361, 362, 363, 364, + 365, 366, 0, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 0, 380, 381, 0, + 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 0, 398, 399, 400, 401, + 402, 0, 404, 405, 406, 407, 408, 0, 410, 411, + 412, 413, 0, 414, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 425, 507, 427, 428, 429, 0, + 430, 431, 0, 432, 0, 434, 435, 436, 437, 438, + 0, 439, 440, 0, 0, 441, 442, 443, 444, 445, + 0, 446, 447, 448, 449, 450, 451, 452, 453, 0, + 0, 454, 455, 456, 457, 458, 459, 0, 0, 461, + 462, 463, 464, 465, 466, 467, 0, 468, 0, 470, + 471, 472, 473, 474, 0, 0, 475, 0, 0, 476, + 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, + 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, + 504, 0, 530, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 105, 106, + 107, 108, 109, 110, 111, 112, 0, 113, 114, 115, + 0, 0, 0, 0, 0, 0, 0, 116, 117, 0, + 118, 119, 120, 0, 122, 123, 124, 125, 126, 0, + 128, 129, 0, 130, 131, 132, 133, 134, 135, 0, + 0, 136, 137, 138, 139, 140, 0, 141, 142, 143, + 144, 145, 0, 0, 0, 147, 148, 149, 150, 151, + 152, 0, 154, 155, 156, 0, 157, 158, 159, 160, + 161, 162, 0, 0, 164, 165, 166, 0, 0, 0, + 0, 0, 0, 0, 172, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 0, 182, 0, 183, 184, 185, + 186, 187, 188, 0, 189, 190, 191, 192, 193, 0, + 0, 194, 195, 196, 197, 198, 0, 199, 200, 201, + 0, 202, 203, 204, 0, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 0, 216, 0, 217, + 218, 219, 220, 0, 221, 0, 222, 0, 0, 0, + 225, 226, 505, 0, 229, 0, 230, 0, 231, 232, + 233, 0, 234, 235, 236, 237, 238, 1343, 240, 0, + 242, 243, 244, 245, 0, 246, 247, 248, 249, 250, + 251, 0, 252, 0, 254, 255, 256, 257, 258, 259, + 260, 261, 0, 262, 0, 263, 0, 0, 266, 0, + 268, 269, 270, 271, 272, 273, 0, 0, 274, 0, + 276, 0, 0, 278, 279, 280, 0, 0, 281, 282, + 283, 284, 285, 506, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 0, 307, 308, 309, 310, 311, 0, + 312, 313, 0, 315, 0, 316, 317, 318, 319, 320, + 321, 0, 322, 323, 0, 0, 324, 325, 326, 0, + 0, 327, 328, 0, 330, 0, 332, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 0, 343, 344, + 345, 0, 347, 348, 349, 350, 351, 352, 0, 353, + 354, 355, 356, 357, 358, 0, 359, 360, 361, 362, + 363, 364, 365, 366, 0, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 0, 380, + 381, 0, 383, 384, 385, 386, 387, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 0, 398, 399, + 400, 401, 402, 0, 404, 405, 406, 407, 408, 0, + 410, 411, 412, 413, 0, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 507, 427, 428, + 429, 0, 430, 431, 0, 432, 0, 434, 435, 436, + 437, 438, 0, 439, 440, 0, 0, 441, 442, 443, + 444, 445, 0, 446, 447, 448, 449, 450, 451, 452, + 453, 0, 0, 454, 455, 456, 457, 458, 459, 0, + 0, 461, 462, 463, 464, 465, 466, 467, 0, 468, + 0, 470, 471, 472, 473, 474, 0, 0, 475, 0, + 0, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, + 495, 496, 504, 0, 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 0, + 105, 106, 107, 108, 109, 110, 111, 112, 0, 113, + 114, 115, 0, 0, 0, 0, 0, 0, 0, 116, + 117, 0, 118, 119, 120, 0, 122, 123, 124, 125, + 126, 0, 128, 129, 0, 130, 131, 132, 133, 134, + 135, 0, 0, 136, 137, 138, 139, 140, 0, 141, + 142, 143, 144, 145, 0, 0, 0, 147, 148, 149, + 150, 151, 152, 0, 154, 155, 156, 0, 157, 158, + 159, 160, 161, 162, 0, 0, 164, 165, 166, 0, + 0, 0, 0, 0, 0, 0, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 0, 182, 0, 183, + 184, 185, 186, 187, 188, 0, 189, 190, 191, 192, + 193, 0, 0, 194, 195, 196, 197, 198, 0, 199, + 200, 201, 0, 202, 203, 204, 0, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 0, 216, + 0, 217, 218, 219, 220, 0, 221, 0, 222, 0, + 0, 0, 225, 226, 505, 0, 229, 0, 230, 0, + 231, 232, 233, 0, 234, 235, 236, 237, 238, 2133, + 240, 0, 242, 243, 244, 245, 0, 246, 247, 248, + 249, 250, 251, 0, 252, 0, 254, 255, 256, 257, + 258, 259, 260, 261, 0, 262, 0, 263, 0, 0, + 266, 0, 268, 269, 270, 271, 272, 273, 0, 0, + 274, 0, 276, 0, 0, 278, 279, 280, 0, 0, + 281, 282, 283, 284, 285, 506, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, 0, 307, 308, 309, 310, + 311, 0, 312, 313, 0, 315, 0, 316, 317, 318, + 319, 320, 321, 0, 322, 323, 0, 0, 324, 325, + 326, 0, 0, 327, 328, 0, 330, 0, 332, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 0, + 343, 344, 345, 0, 347, 348, 349, 350, 351, 352, + 0, 353, 354, 355, 356, 357, 358, 0, 359, 360, + 361, 362, 363, 364, 365, 366, 0, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 0, 380, 381, 0, 383, 384, 385, 386, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 0, + 398, 399, 400, 401, 402, 0, 404, 405, 406, 407, + 408, 0, 410, 411, 412, 413, 0, 414, 415, 416, + 417, 418, 419, 420, 421, 422, 423, 424, 425, 507, + 427, 428, 429, 0, 430, 431, 0, 432, 0, 434, + 435, 436, 437, 438, 0, 439, 440, 0, 0, 441, + 442, 443, 444, 445, 0, 446, 447, 448, 449, 450, + 451, 452, 453, 0, 0, 454, 455, 456, 457, 458, + 459, 0, 0, 461, 462, 463, 464, 465, 466, 467, + 0, 468, 0, 470, 471, 472, 473, 474, 0, 0, + 475, 0, 0, 476, 477, 478, 479, 480, 481, 482, + 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, + 493, 494, 495, 496, 504, 0, 530, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 643, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 644, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 645, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 646, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 647, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 0, + 0, 0, 105, 106, 107, 108, 109, 110, 111, 112, + 0, 113, 114, 115, 0, 0, 0, 0, 0, 0, + 0, 116, 117, 0, 118, 119, 120, 0, 122, 123, + 124, 125, 126, 0, 128, 129, 0, 130, 131, 132, + 133, 134, 135, 0, 0, 136, 137, 138, 139, 140, + 0, 141, 142, 143, 144, 145, 0, 0, 0, 147, + 148, 149, 150, 151, 152, 0, 154, 155, 156, 0, + 157, 158, 159, 160, 161, 162, 0, 0, 164, 165, + 166, 0, 0, 0, 0, 0, 0, 0, 172, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 0, 182, + 0, 183, 184, 185, 186, 187, 188, 0, 189, 190, + 191, 192, 193, 0, 0, 194, 195, 196, 197, 198, + 0, 199, 200, 201, 0, 202, 203, 204, 0, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, + 0, 216, 0, 217, 218, 219, 220, 0, 221, 0, + 222, 0, 0, 0, 225, 226, 505, 0, 229, 0, + 230, 0, 231, 232, 233, 0, 234, 235, 236, 237, + 238, 2801, 240, 0, 242, 243, 244, 245, 0, 246, + 247, 248, 249, 250, 251, 0, 252, 0, 254, 255, + 256, 257, 258, 259, 260, 261, 0, 262, 0, 263, + 0, 0, 266, 0, 268, 269, 270, 271, 272, 273, + 0, 0, 274, 0, 276, 0, 0, 278, 279, 280, + 0, 0, 281, 282, 283, 284, 285, 506, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 0, 307, 308, + 309, 310, 311, 0, 312, 313, 0, 315, 0, 316, + 317, 318, 319, 320, 321, 0, 322, 323, 0, 0, + 324, 325, 326, 0, 0, 327, 328, 0, 330, 0, + 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, + 342, 0, 343, 344, 345, 0, 347, 348, 349, 350, + 351, 352, 0, 353, 354, 355, 356, 357, 358, 0, + 359, 360, 361, 362, 363, 364, 365, 366, 0, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 0, 380, 381, 0, 383, 384, 385, 386, + 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 0, 398, 399, 400, 401, 402, 0, 404, 405, + 406, 407, 408, 0, 410, 411, 412, 413, 0, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 507, 427, 428, 429, 0, 430, 431, 0, 432, + 0, 434, 435, 436, 437, 438, 0, 439, 440, 0, + 0, 441, 442, 443, 444, 445, 0, 446, 447, 448, + 449, 450, 451, 452, 453, 0, 0, 454, 455, 456, + 457, 458, 459, 0, 0, 461, 462, 463, 464, 465, + 466, 467, 0, 468, 0, 470, 471, 472, 473, 474, + 0, 0, 475, 0, 0, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, + 491, 492, 493, 494, 495, 496, 2725, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 714, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 0, 0, 0, 0, 105, 106, 107, 108, 109, 110, + 111, 112, 0, 113, 114, 115, 0, 0, 0, 0, + 0, 0, 0, 116, 117, 0, 118, 119, 120, 2726, + 122, 123, 124, 0, 768, 2727, 770, 771, 0, 130, + 131, 132, 133, 134, 135, 0, 0, 136, 137, 772, + 773, 140, 0, 141, 142, 143, 144, 0, 0, 2728, + 0, 2729, 148, 149, 150, 151, 152, 2730, 154, 155, + 156, 0, 157, 158, 159, 160, 161, 162, 0, 2731, + 164, 165, 166, 2732, 2733, 2734, 2735, 0, 0, 2736, + 172, 173, 174, 175, 176, 177, 178, 783, 784, 181, + 0, 182, 0, 183, 184, 185, 186, 187, 188, 0, + 189, 190, 191, 192, 193, 0, 0, 194, 195, 785, + 197, 198, 0, 199, 200, 201, 0, 202, 203, 204, + 0, 205, 206, 207, 208, 0, 210, 211, 212, 213, + 214, 0, 0, 216, 0, 217, 218, 786, 220, 0, + 221, 0, 222, 2737, 0, 2738, 225, 226, 2739, 2740, + 229, 0, 230, 0, 0, 0, 233, 0, 234, 235, + 236, 237, 238, 239, 240, 2741, 242, 243, 244, 245, + 0, 246, 247, 248, 249, 250, 251, 0, 252, 2742, + 0, 255, 256, 257, 258, 259, 793, 794, 0, 795, + 0, 263, 2743, 2744, 266, 2745, 268, 269, 270, 271, + 272, 273, 0, 0, 274, 2746, 276, 2747, 0, 278, + 279, 280, 0, 0, 281, 282, 283, 284, 285, 2941, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 0, + 297, 298, 299, 300, 301, 302, 303, 304, 802, 2749, + 804, 308, 309, 310, 0, 0, 312, 313, 2751, 315, + 0, 0, 317, 806, 319, 320, 321, 0, 322, 323, + 0, 0, 324, 325, 326, 0, 0, 327, 0, 2753, + 330, 2754, 0, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 0, 343, 344, 0, 2755, 347, 348, + 0, 350, 351, 352, 0, 353, 354, 355, 356, 357, + 358, 0, 359, 360, 361, 810, 363, 364, 365, 366, + 0, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 0, 380, 381, 2756, 383, 384, + 385, 0, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 0, 398, 399, 400, 401, 402, 2757, + 404, 0, 406, 407, 408, 2759, 410, 411, 816, 413, + 0, 414, 415, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 425, 2942, 427, 0, 429, 0, 430, 431, + 0, 432, 2761, 434, 435, 436, 437, 438, 0, 819, + 820, 0, 0, 441, 442, 0, 444, 0, 0, 446, + 447, 2762, 449, 450, 451, 452, 453, 0, 0, 454, + 455, 456, 457, 458, 459, 2764, 0, 461, 462, 463, + 464, 465, 0, 824, 0, 468, 2765, 470, 471, 472, + 473, 474, 0, 0, 475, 0, 0, 476, 477, 478, + 479, 480, 481, 504, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 493, 494, 495, 496, 0, 0, + 0, 105, 106, 107, 108, 109, 110, 111, 112, 0, + 113, 114, 115, 0, 0, 0, 0, 0, 0, 0, + 116, 117, 0, 118, 119, 120, 0, 122, 123, 124, + 125, 126, 0, 128, 129, 0, 130, 131, 132, 133, + 134, 135, 0, 0, 136, 137, 138, 139, 140, 0, + 141, 142, 143, 144, 145, 0, 0, 0, 147, 148, + 149, 150, 151, 152, 0, 154, 155, 156, 0, 157, + 158, 159, 160, 161, 162, 0, 0, 164, 165, 166, + 0, 0, 0, 0, 0, 0, 0, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 0, 182, 0, + 183, 184, 185, 186, 187, 188, 0, 189, 190, 191, + 192, 193, 0, 0, 194, 195, 196, 197, 198, 0, + 199, 200, 201, 0, 202, 203, 204, 0, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 0, + 216, 0, 217, 218, 219, 220, 0, 221, 0, 222, + 0, 0, 0, 225, 226, 505, 0, 229, 0, 230, + 0, 231, 232, 233, 0, 234, 235, 236, 237, 238, + 239, 240, 0, 242, 243, 244, 245, 0, 246, 247, + 248, 249, 250, 251, 0, 252, 0, 254, 255, 256, + 257, 258, 259, 260, 261, 0, 262, 0, 263, 0, + 0, 266, 0, 268, 269, 270, 271, 272, 273, 0, + 0, 274, 0, 276, 0, 0, 278, 279, 280, 0, + 0, 281, 282, 283, 284, 285, 506, 287, 288, 289, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 0, 307, 308, 309, + 310, 311, 0, 312, 313, 0, 315, 0, 316, 317, + 318, 319, 320, 321, 0, 322, 323, 0, 0, 324, + 325, 326, 0, 0, 327, 328, 0, 330, 0, 332, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 0, 343, 344, 345, 0, 347, 348, 349, 350, 351, + 352, 0, 353, 354, 355, 356, 357, 358, 0, 359, + 360, 361, 362, 363, 364, 365, 366, 0, 367, 368, + 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, + 379, 0, 380, 381, 0, 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + 0, 398, 399, 400, 401, 402, 0, 404, 405, 406, + 407, 408, 0, 410, 411, 412, 413, 0, 414, 415, + 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, + 507, 427, 428, 429, 0, 430, 431, 0, 432, 0, + 434, 435, 436, 437, 438, 0, 439, 440, 0, 0, + 441, 442, 443, 444, 445, 0, 446, 447, 448, 449, + 450, 451, 452, 453, 0, 0, 454, 455, 456, 457, + 458, 459, 0, 0, 461, 462, 463, 464, 465, 466, + 467, 0, 468, 0, 470, 471, 472, 473, 474, 0, + 0, 475, 0, 0, 476, 477, 478, 479, 480, 481, + 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, + 492, 493, 494, 495, 496, 504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 812, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 0, + 0, 0, 0, 105, 106, 107, 108, 109, 110, 111, + 112, 0, 113, 114, 115, 0, 0, 0, 0, 0, + 0, 0, 116, 117, 0, 118, 119, 120, 0, 122, + 123, 124, 125, 126, 0, 128, 129, 0, 130, 131, + 132, 133, 134, 135, 0, 0, 136, 137, 138, 139, + 140, 0, 141, 142, 143, 144, 145, 0, 0, 0, + 147, 148, 149, 150, 151, 152, 0, 154, 155, 156, + 0, 157, 158, 159, 160, 161, 162, 0, 0, 164, + 165, 166, 0, 0, 0, 0, 0, 0, 0, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 0, + 182, 0, 183, 184, 185, 186, 187, 188, 0, 189, + 190, 191, 192, 193, 0, 0, 194, 195, 196, 197, + 198, 0, 199, 200, 201, 0, 202, 203, 204, 0, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 0, 216, 0, 217, 218, 219, 220, 0, 221, + 0, 222, 0, 0, 0, 225, 226, 505, 0, 665, + 0, 230, 0, 231, 232, 233, 0, 234, 235, 236, + 237, 238, 239, 240, 0, 242, 243, 244, 245, 0, + 246, 247, 248, 249, 250, 251, 0, 252, 0, 254, + 255, 256, 257, 258, 259, 260, 261, 0, 262, 0, + 263, 0, 0, 266, 0, 268, 269, 270, 271, 272, + 273, 0, 0, 274, 0, 276, 0, 0, 278, 279, + 666, 0, 0, 281, 282, 283, 284, 285, 506, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, 0, 307, + 308, 309, 310, 311, 0, 312, 313, 0, 315, 0, + 316, 317, 318, 319, 320, 321, 0, 322, 323, 0, + 0, 324, 325, 326, 0, 0, 327, 328, 0, 330, + 0, 332, 333, 334, 335, 336, 337, 338, 339, 340, + 341, 342, 0, 343, 344, 345, 0, 347, 348, 349, + 350, 351, 352, 0, 353, 354, 355, 356, 357, 358, + 0, 359, 360, 361, 362, 363, 364, 365, 366, 0, + 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, + 377, 378, 379, 0, 380, 381, 0, 383, 384, 385, + 386, 387, 388, 389, 390, 667, 392, 393, 394, 395, + 396, 397, 0, 398, 399, 400, 401, 668, 0, 404, + 405, 406, 407, 408, 0, 410, 411, 412, 413, 0, + 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, + 424, 425, 507, 427, 428, 429, 0, 430, 431, 0, + 432, 0, 434, 435, 436, 437, 438, 0, 669, 440, + 0, 0, 441, 442, 443, 444, 445, 0, 446, 447, + 448, 449, 450, 451, 452, 453, 0, 0, 454, 455, + 456, 457, 458, 459, 0, 0, 461, 462, 463, 464, + 465, 466, 467, 0, 468, 0, 470, 471, 472, 473, + 474, 0, 0, 475, 0, 0, 476, 477, 478, 479, + 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, + 490, 491, 492, 493, 494, 495, 496, 504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 645, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 647, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 0, + 0, 0, 0, 0, 0, 105, 106, 107, 108, 109, + 110, 111, 112, 0, 113, 114, 115, 0, 0, 0, + 0, 0, 0, 0, 116, 117, 0, 118, 119, 120, + 0, 122, 123, 124, 125, 126, 0, 128, 129, 0, + 130, 131, 132, 133, 134, 135, 0, 0, 136, 137, + 138, 139, 140, 0, 141, 142, 143, 144, 145, 0, + 0, 0, 147, 148, 149, 150, 151, 152, 0, 154, + 155, 156, 0, 157, 158, 159, 160, 161, 162, 0, + 0, 164, 165, 166, 0, 0, 0, 0, 0, 0, + 0, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 0, 182, 0, 183, 184, 185, 186, 187, 188, + 0, 189, 190, 191, 192, 193, 0, 0, 194, 195, + 196, 197, 198, 0, 199, 200, 201, 0, 202, 203, + 204, 0, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 0, 216, 0, 217, 218, 219, 220, + 0, 221, 0, 222, 0, 0, 0, 225, 226, 505, + 0, 229, 0, 230, 0, 231, 232, 233, 0, 234, + 235, 236, 237, 238, 754, 240, 0, 242, 243, 244, + 245, 0, 246, 247, 248, 249, 250, 251, 0, 252, + 0, 254, 255, 256, 257, 258, 259, 260, 261, 0, + 262, 0, 263, 0, 0, 266, 0, 268, 269, 270, + 271, 272, 273, 0, 0, 274, 0, 276, 0, 0, + 278, 279, 280, 0, 0, 281, 282, 283, 284, 285, + 506, 287, 288, 289, 290, 291, 292, 293, 294, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + 0, 307, 308, 309, 310, 311, 0, 312, 313, 0, + 315, 0, 316, 317, 318, 319, 320, 321, 0, 322, + 323, 0, 0, 324, 325, 326, 0, 0, 327, 328, + 0, 330, 0, 332, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342, 0, 343, 344, 345, 0, 347, + 348, 349, 350, 351, 352, 0, 353, 354, 355, 356, + 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, + 366, 0, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 0, 380, 381, 0, 383, + 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 0, 398, 399, 400, 401, 402, + 0, 404, 405, 406, 407, 408, 0, 410, 411, 412, + 413, 0, 414, 415, 416, 417, 418, 419, 420, 421, + 422, 423, 424, 425, 507, 427, 428, 429, 0, 430, + 431, 0, 432, 0, 434, 435, 436, 437, 438, 0, + 439, 440, 0, 0, 441, 442, 443, 444, 445, 0, + 446, 447, 448, 449, 450, 451, 452, 453, 0, 0, + 454, 455, 456, 457, 458, 459, 0, 0, 461, 462, + 463, 464, 465, 466, 467, 0, 468, 0, 470, 471, + 472, 473, 474, 0, 0, 475, 0, 0, 476, 477, + 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, + 488, 489, 490, 491, 492, 493, 494, 495, 496, 504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 1577, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 0, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 105, 106, 107, + 108, 109, 110, 111, 112, 0, 113, 114, 115, 0, + 0, 0, 0, 0, 0, 0, 116, 117, 0, 118, + 119, 120, 0, 122, 123, 124, 125, 126, 0, 128, + 129, 0, 130, 131, 132, 133, 134, 135, 0, 0, + 136, 137, 138, 139, 140, 0, 141, 142, 143, 144, + 145, 0, 0, 0, 147, 148, 149, 150, 151, 152, + 0, 154, 155, 156, 0, 157, 158, 159, 160, 161, + 162, 0, 0, 164, 165, 166, 0, 0, 0, 0, + 0, 0, 0, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 0, 182, 0, 183, 184, 185, 186, + 187, 188, 0, 189, 190, 191, 192, 193, 0, 0, + 194, 195, 196, 197, 198, 0, 199, 200, 201, 0, + 202, 203, 204, 0, 205, 206, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 0, 216, 0, 217, 218, + 219, 220, 0, 221, 0, 222, 0, 0, 0, 225, + 226, 505, 0, 229, 0, 230, 0, 231, 232, 233, + 0, 234, 235, 236, 237, 238, 844, 240, 0, 242, + 243, 244, 245, 0, 246, 247, 248, 249, 250, 251, + 0, 252, 0, 254, 255, 256, 257, 258, 259, 260, + 261, 0, 262, 0, 263, 0, 0, 266, 0, 268, + 269, 270, 271, 272, 273, 0, 0, 274, 0, 276, + 0, 0, 278, 279, 280, 0, 0, 281, 282, 283, + 284, 285, 506, 287, 288, 289, 290, 291, 292, 293, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, 0, 307, 308, 309, 310, 311, 0, 312, + 313, 0, 315, 0, 316, 317, 318, 319, 320, 321, + 0, 322, 323, 0, 0, 324, 325, 326, 0, 0, + 327, 328, 0, 330, 0, 332, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 0, 343, 344, 345, + 0, 347, 348, 349, 350, 351, 352, 0, 353, 354, + 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, + 364, 365, 366, 0, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378, 379, 0, 380, 381, + 0, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, 0, 398, 399, 400, + 401, 402, 0, 404, 405, 406, 407, 408, 0, 410, + 411, 412, 413, 0, 414, 415, 416, 417, 418, 419, + 420, 421, 422, 423, 424, 425, 507, 427, 428, 429, + 0, 430, 431, 0, 432, 0, 434, 435, 436, 437, + 438, 0, 439, 440, 0, 0, 441, 442, 443, 444, + 445, 0, 446, 447, 448, 449, 450, 451, 452, 453, + 0, 0, 454, 455, 456, 457, 458, 459, 0, 0, + 461, 462, 463, 464, 465, 466, 467, 0, 468, 0, + 470, 471, 472, 473, 474, 0, 0, 475, 0, 0, + 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, + 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, + 496, 504, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, + 106, 107, 108, 109, 110, 111, 112, 0, 113, 114, + 115, 0, 0, 0, 0, 0, 0, 0, 116, 117, + 0, 118, 119, 120, 0, 122, 123, 124, 125, 126, + 0, 128, 129, 0, 130, 131, 132, 133, 134, 135, + 0, 0, 136, 137, 138, 139, 140, 0, 141, 142, + 143, 144, 145, 0, 0, 0, 147, 148, 149, 150, + 151, 152, 0, 154, 155, 156, 0, 157, 158, 159, + 160, 161, 162, 0, 0, 164, 165, 166, 0, 0, + 0, 0, 0, 0, 0, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 0, 182, 0, 183, 184, + 185, 186, 187, 188, 0, 189, 190, 191, 192, 193, + 0, 0, 194, 195, 196, 197, 198, 0, 199, 200, + 201, 0, 202, 203, 204, 0, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 0, 216, 0, + 217, 218, 219, 220, 0, 221, 0, 222, 0, 0, + 0, 225, 226, 505, 0, 229, 0, 230, 0, 231, + 232, 233, 0, 234, 235, 236, 237, 238, 239, 240, + 0, 242, 243, 244, 245, 0, 246, 247, 248, 249, + 250, 251, 0, 252, 0, 254, 255, 256, 257, 258, + 259, 260, 261, 0, 262, 0, 263, 0, 0, 266, + 0, 268, 269, 270, 271, 272, 273, 0, 0, 274, + 0, 276, 0, 0, 278, 279, 280, 0, 0, 281, + 282, 283, 284, 285, 506, 287, 288, 289, 290, 291, + 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, 0, 307, 308, 309, 310, 311, + 0, 312, 313, 0, 315, 0, 316, 317, 318, 319, + 320, 321, 0, 322, 323, 0, 0, 324, 325, 326, + 0, 0, 327, 328, 0, 330, 0, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 0, 343, + 344, 345, 0, 347, 348, 349, 350, 351, 352, 0, + 353, 354, 355, 356, 357, 358, 0, 359, 360, 361, + 362, 363, 364, 365, 366, 0, 367, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378, 379, 0, + 380, 381, 0, 383, 384, 385, 386, 387, 388, 389, + 390, 667, 392, 393, 394, 395, 396, 397, 0, 398, + 399, 400, 401, 402, 0, 404, 405, 406, 407, 408, + 0, 410, 411, 412, 413, 0, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 425, 507, 427, + 428, 429, 0, 430, 431, 0, 432, 0, 434, 435, + 436, 437, 438, 0, 669, 440, 0, 0, 441, 442, + 443, 444, 445, 0, 446, 447, 448, 449, 450, 451, + 452, 453, 0, 0, 454, 455, 456, 457, 458, 459, + 0, 0, 461, 462, 463, 464, 465, 466, 467, 0, + 468, 0, 470, 471, 472, 473, 474, 0, 0, 475, + 0, 0, 476, 477, 478, 479, 480, 481, 482, 483, + 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, + 494, 495, 496, 504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 1734, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 0, + 0, 105, 106, 107, 108, 109, 110, 111, 112, 0, + 113, 114, 115, 0, 0, 0, 0, 0, 1629, 0, + 116, 117, 0, 118, 119, 120, 0, 122, 123, 124, + 125, 126, 0, 128, 129, 0, 130, 131, 132, 133, + 134, 135, 0, 0, 136, 137, 138, 139, 140, 0, + 141, 142, 143, 144, 145, 0, 0, 0, 147, 148, + 149, 150, 151, 152, 0, 154, 155, 156, 0, 157, + 158, 159, 160, 161, 162, 0, 0, 164, 165, 166, + 0, 0, 0, 0, 0, 0, 0, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 0, 182, 0, + 183, 184, 185, 186, 187, 188, 0, 189, 190, 191, + 192, 193, 0, 0, 194, 195, 196, 197, 198, 0, + 199, 200, 201, 0, 202, 203, 204, 0, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 0, + 216, 0, 217, 218, 219, 220, 0, 221, 0, 222, + 0, 0, 0, 225, 226, 505, 0, 229, 0, 230, + 0, 231, 232, 233, 0, 234, 235, 236, 237, 238, + 239, 240, 0, 242, 243, 244, 245, 0, 246, 247, + 248, 249, 250, 251, 0, 252, 0, 254, 255, 256, + 257, 258, 259, 260, 261, 0, 262, 0, 263, 0, + 0, 266, 0, 268, 269, 270, 271, 272, 273, 0, + 0, 274, 0, 276, 0, 0, 278, 279, 280, 0, + 0, 281, 282, 283, 284, 285, 506, 287, 288, 289, + 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 0, 307, 308, 309, + 310, 311, 0, 312, 313, 0, 315, 0, 316, 317, + 318, 319, 320, 321, 0, 322, 323, 0, 0, 324, + 325, 326, 0, 0, 327, 328, 0, 330, 0, 332, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 0, 343, 344, 345, 0, 347, 348, 349, 350, 351, + 352, 0, 353, 354, 355, 356, 357, 358, 0, 359, + 360, 361, 362, 363, 364, 365, 366, 0, 367, 368, + 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, + 379, 0, 380, 381, 0, 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + 0, 398, 399, 400, 401, 402, 0, 0, 405, 406, + 407, 408, 0, 410, 411, 412, 413, 0, 414, 415, + 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, + 507, 427, 428, 429, 0, 430, 431, 0, 432, 0, + 434, 435, 436, 437, 438, 0, 439, 440, 0, 0, + 441, 442, 443, 444, 445, 0, 446, 447, 448, 449, + 450, 451, 452, 453, 0, 0, 454, 455, 456, 457, + 458, 459, 0, 0, 461, 462, 463, 464, 465, 466, + 467, 0, 468, 0, 470, 471, 472, 473, 474, 0, + 0, 475, 0, 0, 476, 477, 478, 479, 480, 481, + 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, + 492, 493, 494, 495, 496, 504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 2061, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 508, 0, 0, + 0, 0, 0, 105, 106, 107, 108, 109, 110, 111, + 112, 0, 113, 114, 115, 0, 0, 0, 0, 0, + 0, 0, 116, 117, 0, 118, 119, 120, 0, 122, + 123, 124, 125, 126, 0, 128, 129, 0, 130, 131, + 132, 133, 134, 135, 0, 0, 136, 137, 138, 139, + 140, 0, 141, 142, 143, 144, 145, 0, 0, 0, + 147, 148, 149, 150, 151, 152, 0, 154, 155, 156, + 0, 157, 158, 159, 160, 161, 162, 0, 0, 164, + 165, 166, 0, 0, 0, 0, 0, 0, 0, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 0, + 182, 0, 183, 184, 185, 186, 187, 188, 0, 189, + 190, 191, 192, 193, 0, 0, 194, 195, 196, 197, + 198, 0, 199, 200, 201, 0, 202, 203, 204, 0, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 0, 216, 0, 217, 218, 219, 220, 0, 221, + 0, 222, 0, 0, 0, 225, 226, 505, 0, 229, + 0, 230, 0, 231, 232, 233, 0, 234, 235, 236, + 237, 238, 1791, 240, 0, 242, 243, 244, 245, 0, + 246, 247, 248, 249, 250, 251, 0, 252, 0, 254, + 255, 256, 257, 258, 259, 260, 261, 0, 262, 0, + 263, 0, 0, 266, 0, 268, 269, 270, 271, 272, + 273, 0, 0, 274, 0, 276, 0, 0, 278, 279, + 280, 0, 0, 281, 282, 283, 284, 285, 506, 287, + 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, 0, 307, + 308, 309, 310, 311, 0, 312, 313, 0, 315, 0, + 316, 317, 318, 319, 320, 321, 0, 322, 323, 0, + 0, 324, 325, 326, 0, 0, 327, 328, 0, 330, + 0, 332, 333, 334, 335, 336, 337, 338, 339, 340, + 341, 342, 0, 343, 344, 345, 0, 347, 348, 349, + 350, 351, 352, 0, 353, 354, 355, 356, 357, 358, + 0, 359, 360, 361, 362, 363, 364, 365, 366, 0, + 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, + 377, 378, 379, 0, 380, 381, 0, 383, 384, 385, + 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 0, 398, 399, 400, 401, 402, 0, 404, + 405, 406, 407, 408, 0, 410, 411, 412, 413, 0, + 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, + 424, 425, 507, 427, 428, 429, 0, 430, 431, 0, + 432, 0, 434, 435, 436, 437, 438, 0, 439, 440, + 0, 0, 441, 442, 443, 444, 445, 0, 446, 447, + 448, 449, 450, 451, 452, 453, 0, 0, 454, 455, + 456, 457, 458, 459, 0, 0, 461, 462, 463, 464, + 465, 466, 467, 0, 468, 0, 470, 471, 472, 473, + 474, 0, 0, 475, 0, 0, 476, 477, 478, 479, + 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, + 490, 491, 492, 493, 494, 495, 496, 504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 2076, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 2657, 0, 0, + 0, 0, 0, 0, 0, 105, 106, 107, 108, 109, + 110, 111, 112, 0, 113, 114, 115, 0, 0, 0, + 0, 0, 0, 0, 116, 117, 0, 118, 119, 120, + 0, 122, 123, 124, 125, 126, 0, 128, 129, 0, + 130, 131, 132, 133, 134, 135, 0, 0, 136, 137, + 138, 139, 140, 0, 141, 142, 143, 144, 145, 0, + 0, 0, 147, 148, 149, 150, 151, 152, 0, 154, + 155, 156, 0, 157, 158, 159, 160, 161, 162, 0, + 0, 164, 165, 166, 0, 0, 0, 0, 0, 0, + 0, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 0, 182, 0, 183, 184, 185, 186, 187, 188, + 0, 189, 190, 191, 192, 193, 0, 0, 194, 195, + 196, 197, 198, 0, 199, 200, 201, 0, 202, 203, + 204, 0, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 0, 216, 0, 217, 218, 219, 220, + 0, 221, 0, 222, 0, 0, 0, 225, 226, 505, + 0, 229, 0, 230, 0, 231, 232, 233, 0, 234, + 235, 236, 237, 238, 2120, 240, 0, 242, 243, 244, + 245, 0, 246, 247, 248, 249, 250, 251, 0, 252, + 0, 254, 255, 256, 257, 258, 259, 260, 261, 0, + 262, 0, 263, 0, 0, 266, 0, 268, 269, 270, + 271, 272, 273, 0, 0, 274, 0, 276, 0, 0, + 278, 279, 280, 0, 0, 281, 282, 283, 284, 285, + 506, 287, 288, 289, 290, 291, 292, 293, 294, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + 0, 307, 308, 309, 310, 311, 0, 312, 313, 0, + 315, 0, 316, 317, 318, 319, 320, 321, 0, 322, + 323, 0, 0, 324, 325, 326, 0, 0, 327, 328, + 0, 330, 0, 332, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342, 0, 343, 344, 345, 0, 347, + 348, 349, 350, 351, 352, 0, 353, 354, 355, 356, + 357, 358, 0, 359, 360, 361, 362, 363, 364, 365, + 366, 0, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 0, 380, 381, 0, 383, + 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 0, 398, 399, 400, 401, 402, + 0, 404, 405, 406, 407, 408, 0, 410, 411, 412, + 413, 0, 414, 415, 416, 417, 418, 419, 420, 421, + 422, 423, 424, 425, 507, 427, 428, 429, 0, 430, + 431, 0, 432, 0, 434, 435, 436, 437, 438, 0, + 439, 440, 0, 0, 441, 442, 443, 444, 445, 0, + 446, 447, 448, 449, 450, 451, 452, 453, 0, 0, + 454, 455, 456, 457, 458, 459, 0, 0, 461, 462, + 463, 464, 465, 466, 467, 0, 468, 0, 470, 471, + 472, 473, 474, 0, 0, 475, 0, 0, 476, 477, + 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, + 488, 489, 490, 491, 492, 493, 494, 495, 496, 504, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 2658, 113, 114, 115, 0, 737, 2659, 739, 740, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 741, 742, 131, 0, 132, 133, 134, 135, 0, 0, - 2660, 0, 2661, 139, 140, 141, 142, 143, 2662, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 2663, 155, 156, 157, 2664, 2665, 2666, 2667, 0, 0, - 2668, 163, 164, 165, 166, 167, 168, 169, 752, 753, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 754, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 0, 201, 202, 203, - 204, 205, 0, 0, 207, 0, 208, 209, 755, 211, - 0, 212, 0, 213, 2669, 0, 2670, 216, 217, 2671, - 2672, 220, 0, 221, 0, 0, 0, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 2673, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 2674, 0, 246, 247, 248, 249, 250, 762, 763, 0, - 764, 0, 254, 2675, 2676, 257, 2677, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 2678, 267, 2679, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 2871, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 771, - 2681, 773, 299, 300, 301, 0, 0, 303, 304, 2683, - 306, 0, 0, 308, 775, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 0, - 2685, 321, 2686, 0, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 0, 334, 335, 0, 337, 338, - 0, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 350, 351, 778, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 2687, 373, 374, - 375, 0, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 2688, - 394, 0, 396, 397, 398, 2690, 400, 401, 784, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 2872, 417, 0, 419, 0, 420, 421, - 0, 422, 2692, 424, 425, 426, 427, 428, 0, 787, - 788, 0, 0, 431, 432, 0, 434, 0, 0, 436, - 437, 2693, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 2695, 0, 450, 451, 452, 453, - 454, 0, 792, 0, 457, 2696, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 735, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 482, 483, 484, 485, 0, 0, 0, - 96, 97, 98, 99, 100, 101, 102, 103, 0, 104, - 105, 106, 0, 0, 0, 0, 0, 0, 0, 107, - 108, 0, 109, 110, 111, 736, 113, 114, 115, 0, - 737, 738, 739, 740, 0, 121, 122, 123, 124, 125, - 126, 0, 0, 127, 128, 741, 742, 131, 0, 132, - 133, 134, 135, 0, 0, 743, 0, 744, 139, 140, - 141, 142, 143, 745, 145, 146, 147, 0, 148, 149, - 150, 151, 152, 153, 0, 746, 155, 156, 157, 747, - 748, 749, 750, 0, 0, 751, 163, 164, 165, 166, - 167, 168, 169, 752, 753, 172, 0, 173, 0, 174, - 175, 176, 177, 178, 179, 0, 180, 181, 182, 183, - 184, 0, 0, 185, 186, 754, 188, 189, 0, 190, - 191, 192, 0, 193, 194, 195, 0, 196, 197, 198, - 199, 0, 201, 202, 203, 204, 205, 0, 0, 207, - 0, 208, 209, 755, 211, 0, 212, 0, 213, 756, - 0, 757, 216, 217, 0, 758, 220, 0, 221, 0, - 0, 0, 224, 0, 225, 226, 227, 228, 229, 230, - 231, 760, 233, 234, 235, 236, 0, 237, 238, 239, - 240, 241, 242, 0, 243, 761, 0, 246, 247, 248, - 249, 250, 762, 763, 0, 764, 0, 254, 765, 766, - 257, 767, 259, 260, 261, 262, 263, 264, 0, 0, - 265, 768, 267, 769, 0, 269, 270, 271, 0, 0, - 272, 273, 274, 275, 276, 0, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, 293, 294, 295, 771, 772, 773, 299, 300, 301, - 0, 0, 303, 304, 774, 306, 0, 0, 308, 775, - 310, 311, 312, 0, 313, 314, 0, 0, 315, 316, - 317, 0, 0, 318, 0, 776, 321, 777, 0, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 0, - 334, 335, 0, 337, 338, 0, 340, 341, 342, 0, - 343, 344, 345, 346, 347, 348, 0, 349, 350, 351, - 778, 353, 354, 355, 356, 0, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, 369, 0, - 370, 371, 779, 373, 374, 375, 0, 377, 378, 379, - 380, 381, 382, 383, 384, 385, 386, 387, 0, 388, - 389, 390, 391, 392, 781, 394, 0, 396, 397, 398, - 783, 400, 401, 784, 403, 0, 404, 405, 406, 407, - 408, 409, 410, 411, 412, 413, 414, 415, 0, 417, - 0, 419, 0, 420, 421, 0, 422, 786, 424, 425, - 426, 427, 428, 0, 787, 788, 0, 0, 431, 432, - 0, 434, 0, 0, 436, 437, 789, 439, 440, 441, - 442, 443, 0, 0, 444, 445, 446, 447, 448, 791, - 0, 450, 451, 452, 453, 454, 0, 792, 0, 457, - 793, 459, 460, 461, 462, 463, 0, 0, 464, 0, - 0, 465, 466, 467, 468, 469, 470, 508, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 482, 483, - 484, 485, 0, 0, 0, 96, 97, 98, 99, 100, - 101, 102, 103, 0, 104, 105, 106, 0, 0, 0, - 0, 0, 0, 0, 107, 108, 0, 109, 110, 111, - 0, 113, 114, 115, 116, 117, 0, 119, 120, 0, - 121, 122, 123, 124, 125, 126, 0, 0, 127, 128, - 129, 130, 131, 0, 132, 133, 134, 135, 136, 0, - 0, 0, 138, 139, 140, 141, 142, 143, 0, 145, - 146, 147, 0, 148, 149, 150, 151, 152, 153, 0, - 0, 155, 156, 157, 0, 0, 0, 0, 0, 0, - 0, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 0, 173, 0, 174, 175, 176, 177, 178, 179, - 0, 180, 181, 182, 183, 184, 0, 0, 185, 186, - 187, 188, 189, 0, 190, 191, 192, 0, 193, 194, - 195, 0, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 0, 207, 0, 208, 209, 210, 211, - 0, 212, 0, 213, 0, 0, 0, 216, 217, 511, - 0, 220, 0, 221, 0, 222, 223, 224, 0, 225, - 226, 227, 228, 229, 230, 231, 0, 233, 234, 235, - 236, 0, 237, 238, 239, 240, 241, 242, 0, 243, - 0, 245, 246, 247, 248, 249, 250, 251, 252, 0, - 253, 0, 254, 0, 0, 257, 0, 259, 260, 261, - 262, 263, 264, 0, 0, 265, 0, 267, 0, 0, - 269, 270, 271, 0, 0, 272, 273, 274, 275, 276, - 512, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 0, 298, 299, 300, 301, 302, 0, 303, 304, 0, - 306, 0, 307, 308, 309, 310, 311, 312, 0, 313, - 314, 0, 0, 315, 316, 317, 0, 0, 318, 319, - 0, 321, 0, 323, 324, 325, 326, 327, 328, 329, - 0, 331, 332, 333, 0, 334, 335, 336, 337, 338, - 339, 340, 341, 342, 0, 343, 344, 345, 346, 347, - 348, 0, 349, 0, 351, 352, 353, 354, 355, 356, - 0, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 0, 370, 371, 0, 373, 374, - 375, 376, 0, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 0, 388, 389, 390, 391, 392, 0, - 394, 395, 396, 397, 398, 0, 400, 401, 402, 403, - 0, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 514, 417, 418, 419, 0, 420, 421, - 0, 422, 0, 424, 425, 426, 427, 428, 0, 429, - 430, 0, 0, 431, 432, 433, 434, 435, 0, 436, - 437, 438, 439, 440, 441, 442, 443, 0, 0, 444, - 445, 446, 447, 448, 0, 0, 450, 451, 452, 453, - 454, 455, 456, 0, 457, 0, 459, 460, 461, 462, - 463, 0, 0, 464, 0, 0, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, 484, 485, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0, 2, 2, 3, - 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 5, 5, 0, 0, 0, - 0, 0, 0, 0, 6, 6, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, - 9, 10, 10, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, - 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 12, 12, 0, 0, 0, 0, 0, - 0, 0, 0, 13, 13, 0, 0, 0, 0, 14, - 14, 0, 0, 0, 0, 0, 0, 15, 15, 0, + 0, 0, 0, 0, 0, 0, 0, 105, 106, 107, + 108, 109, 110, 111, 112, 0, 113, 114, 115, 0, + 0, 0, 0, 0, 0, 0, 116, 117, 0, 118, + 119, 120, 0, 122, 123, 124, 125, 126, 0, 128, + 129, 0, 130, 131, 132, 133, 134, 135, 0, 0, + 136, 137, 138, 139, 140, 0, 141, 142, 143, 144, + 145, 0, 0, 0, 147, 148, 149, 150, 151, 152, + 0, 154, 155, 156, 0, 157, 158, 159, 160, 161, + 162, 0, 0, 164, 165, 166, 0, 0, 0, 0, + 0, 0, 0, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 0, 182, 0, 183, 184, 185, 186, + 187, 188, 0, 189, 190, 191, 192, 193, 0, 0, + 194, 195, 196, 197, 198, 0, 199, 200, 201, 0, + 202, 203, 204, 0, 205, 206, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 0, 216, 0, 217, 218, + 219, 220, 0, 221, 0, 222, 0, 0, 0, 225, + 226, 505, 0, 229, 0, 230, 0, 231, 232, 233, + 0, 234, 235, 236, 237, 238, 2135, 240, 0, 242, + 243, 244, 245, 0, 246, 247, 248, 249, 250, 251, + 0, 252, 0, 254, 255, 256, 257, 258, 259, 260, + 261, 0, 262, 0, 263, 0, 0, 266, 0, 268, + 269, 270, 271, 272, 273, 0, 0, 274, 0, 276, + 0, 0, 278, 279, 280, 0, 0, 281, 282, 283, + 284, 285, 506, 287, 288, 289, 290, 291, 292, 293, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, 0, 307, 308, 309, 310, 311, 0, 312, + 313, 0, 315, 0, 316, 317, 318, 319, 320, 321, + 0, 322, 323, 0, 0, 324, 325, 326, 0, 0, + 327, 328, 0, 330, 0, 332, 333, 334, 335, 336, + 337, 338, 339, 340, 341, 342, 0, 343, 344, 345, + 0, 347, 348, 349, 350, 351, 352, 0, 353, 354, + 355, 356, 357, 358, 0, 359, 360, 361, 362, 363, + 364, 365, 366, 0, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378, 379, 0, 380, 381, + 0, 383, 384, 385, 386, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, 0, 398, 399, 400, + 401, 402, 0, 404, 405, 406, 407, 408, 0, 410, + 411, 412, 413, 0, 414, 415, 416, 417, 418, 419, + 420, 421, 422, 423, 424, 425, 507, 427, 428, 429, + 0, 430, 431, 0, 432, 0, 434, 435, 436, 437, + 438, 0, 439, 440, 0, 0, 441, 442, 443, 444, + 445, 0, 446, 447, 448, 449, 450, 451, 452, 453, + 0, 0, 454, 455, 456, 457, 458, 459, 0, 0, + 461, 462, 463, 464, 465, 466, 467, 0, 468, 0, + 470, 471, 472, 473, 474, 0, 0, 475, 0, 0, + 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, + 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, + 496, 766, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 105, + 106, 107, 108, 109, 110, 111, 112, 0, 113, 114, + 115, 0, 0, 0, 0, 0, 0, 0, 116, 117, + 0, 118, 119, 120, 767, 122, 123, 124, 0, 768, + 769, 770, 771, 0, 130, 131, 132, 133, 134, 135, + 0, 0, 136, 137, 772, 773, 140, 0, 141, 142, + 143, 144, 0, 0, 774, 0, 775, 148, 149, 150, + 151, 152, 776, 154, 155, 156, 0, 157, 158, 159, + 160, 161, 162, 0, 777, 164, 165, 166, 778, 779, + 780, 781, 0, 0, 782, 172, 173, 174, 175, 176, + 177, 178, 783, 784, 181, 0, 182, 0, 183, 184, + 185, 186, 187, 188, 0, 189, 190, 191, 192, 193, + 0, 0, 194, 195, 785, 197, 198, 0, 199, 200, + 201, 0, 202, 203, 204, 0, 205, 206, 207, 208, + 0, 210, 211, 212, 213, 214, 0, 0, 216, 0, + 217, 218, 786, 220, 0, 221, 0, 222, 787, 0, + 788, 225, 226, 0, 789, 229, 0, 230, 0, 0, + 0, 233, 0, 234, 235, 236, 237, 238, 239, 240, + 791, 242, 243, 244, 245, 0, 246, 247, 248, 249, + 250, 251, 0, 252, 792, 0, 255, 256, 257, 258, + 259, 793, 794, 0, 795, 0, 263, 796, 797, 266, + 798, 268, 269, 270, 271, 272, 273, 0, 0, 274, + 799, 276, 800, 0, 278, 279, 280, 0, 0, 281, + 282, 283, 284, 285, 0, 287, 288, 289, 290, 291, + 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 802, 803, 804, 308, 309, 310, 0, + 0, 312, 313, 805, 315, 0, 0, 317, 806, 319, + 320, 321, 0, 322, 323, 0, 0, 324, 325, 326, + 0, 0, 327, 0, 807, 330, 808, 0, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 0, 343, + 344, 0, 809, 347, 348, 0, 350, 351, 352, 0, + 353, 354, 355, 356, 357, 358, 0, 359, 360, 361, + 810, 363, 364, 365, 366, 0, 367, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378, 379, 0, + 380, 381, 811, 383, 384, 385, 0, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, 0, 398, + 399, 400, 401, 402, 813, 404, 0, 406, 407, 408, + 815, 410, 411, 816, 413, 0, 414, 415, 416, 417, + 418, 419, 420, 421, 422, 423, 424, 425, 0, 427, + 0, 429, 0, 430, 431, 0, 432, 818, 434, 435, + 436, 437, 438, 0, 819, 820, 0, 0, 441, 442, + 0, 444, 0, 0, 446, 447, 821, 449, 450, 451, + 452, 453, 0, 0, 454, 455, 456, 457, 458, 459, + 823, 0, 461, 462, 463, 464, 465, 0, 824, 0, + 468, 825, 470, 471, 472, 473, 474, 0, 0, 475, + 0, 0, 476, 477, 478, 479, 480, 481, 504, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 493, + 494, 495, 496, 0, 0, 0, 105, 106, 107, 108, + 109, 110, 111, 112, 0, 113, 114, 115, 0, 0, + 0, 0, 0, 0, 0, 116, 117, 0, 118, 119, + 120, 0, 122, 123, 124, 125, 126, 0, 128, 129, + 0, 130, 131, 132, 133, 134, 135, 0, 0, 136, + 137, 138, 139, 140, 0, 141, 142, 143, 144, 145, + 0, 0, 0, 147, 148, 149, 150, 151, 152, 0, + 154, 155, 156, 0, 157, 158, 159, 160, 161, 162, + 0, 0, 164, 165, 166, 0, 0, 0, 0, 0, + 0, 0, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 0, 182, 0, 183, 184, 185, 186, 187, + 188, 0, 189, 190, 191, 192, 193, 0, 0, 194, + 195, 196, 197, 198, 0, 199, 200, 201, 0, 202, + 203, 204, 0, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 0, 216, 0, 217, 218, 219, + 220, 0, 221, 0, 222, 0, 0, 0, 225, 226, + 505, 0, 229, 0, 230, 0, 231, 232, 233, 0, + 234, 235, 236, 237, 238, 239, 240, 0, 242, 243, + 244, 245, 0, 246, 247, 248, 249, 250, 251, 0, + 252, 0, 254, 255, 256, 257, 258, 259, 260, 261, + 0, 262, 0, 263, 0, 0, 266, 0, 268, 269, + 270, 271, 272, 273, 0, 0, 274, 0, 276, 0, + 0, 278, 279, 280, 0, 0, 281, 282, 283, 284, + 285, 506, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 0, 307, 308, 309, 310, 311, 0, 312, 313, + 0, 315, 0, 316, 317, 318, 319, 320, 321, 0, + 322, 323, 0, 0, 324, 325, 326, 0, 0, 327, + 328, 0, 330, 0, 332, 333, 334, 335, 336, 337, + 338, 0, 340, 341, 342, 0, 343, 344, 345, 0, + 347, 348, 349, 350, 351, 352, 0, 353, 354, 355, + 356, 357, 358, 0, 359, 0, 361, 362, 363, 364, + 365, 366, 0, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 0, 380, 381, 0, + 383, 384, 385, 386, 0, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 0, 398, 399, 400, 401, + 402, 0, 404, 405, 406, 407, 408, 0, 410, 411, + 412, 413, 0, 414, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 425, 507, 427, 428, 429, 0, + 430, 431, 0, 432, 0, 434, 435, 436, 437, 438, + 0, 439, 440, 0, 0, 441, 442, 443, 444, 445, + 0, 446, 447, 448, 449, 450, 451, 452, 453, 0, + 0, 454, 455, 456, 457, 458, 459, 0, 0, 461, + 462, 463, 464, 465, 466, 467, 0, 468, 0, 470, + 471, 472, 473, 474, 0, 0, 475, 0, 0, 476, + 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, + 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, + 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 2, 3, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, + 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, + 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 10, 10, 568, 568, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 18, 18, 0, 0, 19, 19, 0, + 0, 0, 12, 12, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 13, 13, 0, 0, + 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, + 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, + 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 20, 20, 0, 0, + 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 21, 21, 0, + 23, 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 22, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 25, 25, 0, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 23, 23, 0, 24, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 27, 27, 0, 0, + 0, 0, 0, 0, 0, 28, 28, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, + 29, 0, 0, 0, 0, 0, 30, 30, 0, 0, + 31, 31, 0, 0, 0, 0, 0, 0, 0, 0, + 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 33, 33, 0, 0, 34, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 25, 25, 0, 0, 0, 0, 0, 0, - 0, 26, 26, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 27, 27, 0, 0, 0, - 0, 0, 28, 28, 0, 0, 29, 29, 0, 0, - 0, 0, 0, 0, 0, 0, 30, 30, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 31, 31, - 0, 0, 32, 32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 35, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 33, 33, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 34, 34, - 0, 0, 0, 35, 35, 0, 0, 546, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 36, 36, 0, + 0, 0, 0, 37, 37, 0, 0, 0, 38, 38, + 0, 0, 569, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 39, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 37, 37, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 547, 38 + 570, 41 }; static const yytype_int16 yycheck[] = { - 6, 503, 697, 708, 38, 61, 0, 0, 0, 6, - 0, 6, 19, 19, 0, 0, 934, 912, 1142, 0, - 704, 683, 19, 663, 19, 782, 813, 547, 713, 816, - 63, 1115, 0, 1140, 63, 16, 19, 609, 1427, 541, - 706, 1318, 1486, 16, 1083, 1556, 1595, 788, 1021, 1598, - 32, 1991, 912, 1120, 1994, 2023, 1117, 0, 2026, 2072, - 621, 1465, 1111, 546, 539, 1038, 1189, 923, 697, 611, - 699, 923, 701, 547, 616, 1047, 542, 923, 641, 1052, - 923, 0, 1054, 2423, 1145, 1420, 1421, 969, 31, 0, - 1425, 1510, 1511, 2423, 0, 0, 657, 0, 0, 0, - 0, 1019, 2452, 0, 1960, 0, 0, 0, 1323, 0, - 92, 0, 37, 0, 0, 0, 0, 0, 0, 0, - 0, 2116, 2117, 2118, 2014, 2472, 570, 0, 741, 742, - 22, 2450, 2465, 2300, 9, 13, 14, 5, 2131, 82, - 2068, 1563, 1708, 16, 0, 1288, 19, 5, 5, 0, - 60, 5, 680, 5, 13, 14, 5, 1616, 31, 5, - 773, 13, 14, 680, 5, 38, 5, 5, 5, 5, - 5, 9, 13, 14, 13, 14, 13, 14, 13, 14, - 820, 5, 11, 4, 171, 9, 15, 5, 9, 5, - 63, 5, 1618, 2140, 1832, 13, 14, 13, 14, 69, - 1060, 5, 172, 29, 119, 5, 5, 124, 52, 82, - 36, 5, 2723, 13, 14, 5, 5, 5, 5, 2147, - 5, 5, 5, 13, 14, 13, 14, 189, 13, 14, - 13, 14, 5, 42, 5, 675, 5, 5, 5, 95, - 5, 5, 109, 9, 95, 122, 77, 77, 615, 932, - 5, 2727, 11, 122, 285, 60, 15, 88, 88, 2359, - 139, 288, 171, 273, 11, 24, 287, 2743, 15, 1129, - 1011, 1153, 1132, 1133, 60, 3, 11, 36, 37, 919, - 15, 2875, 42, 1165, 309, 2213, 2214, 21, 22, 1311, - 60, 224, 85, 29, 2911, 2631, 43, 224, 168, 2575, - 966, 108, 2578, 244, 117, 33, 34, 50, 43, 276, - 29, 29, 244, 3, 4, 5, 357, 36, 36, 9, - 2951, 293, 52, 38, 171, 2265, 38, 2705, 75, 75, - 5, 90, 369, 210, 161, 309, 129, 270, 70, 293, - 75, 122, 119, 270, 80, 4, 2341, 39, 109, 2689, - 9, 147, 132, 89, 357, 358, 137, 13, 14, 191, - 163, 2294, 120, 2982, 11, 2340, 461, 97, 2343, 419, - 348, 1128, 539, 165, 987, 988, 948, 2390, 1018, 61, - 441, 953, 118, 925, 358, 2735, 32, 69, 405, 1002, - 485, 11, 912, 123, 488, 15, 43, 939, 376, 1065, - 1858, 1859, 1860, 330, 29, 2373, 110, 501, 235, 2342, - 56, 141, 163, 378, 464, 145, 383, 1100, 2737, 215, - 2896, 362, 497, 440, 2740, 228, 501, 117, 75, 439, - 417, 287, 915, 176, 126, 193, 287, 167, 499, 349, - 170, 2297, 170, 250, 172, 3064, 379, 29, 968, 192, - 320, 258, 379, 189, 197, 185, 3087, 1479, 499, 2387, - 175, 2389, 1023, 175, 277, 201, 503, 2978, 499, 494, - 1110, 1875, 499, 1808, 1809, 1810, 1811, 1812, 499, 211, - 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, 1823, 1824, - 2766, 234, 1053, 2593, 350, 2873, 437, 293, 2834, 350, - 277, 488, 282, 3120, 3098, 437, 439, 132, 417, 270, - 166, 304, 439, 547, 501, 347, 1960, 2853, 269, 1080, - 494, 11, 369, 315, 441, 15, 216, 3146, 443, 499, - 2477, 503, 1194, 539, 499, 2875, 11, 499, 319, 406, - 15, 547, 1062, 1063, 349, 2875, 2521, 277, 238, 503, - 132, 2884, 495, 43, 1638, 285, 238, 924, 499, 406, - 386, 2636, 439, 349, 434, 546, 244, 499, 110, 2644, - 439, 1694, 2500, 2032, 547, 609, 1719, 1996, 457, 349, - 1108, 2025, 2391, 2149, 2222, 75, 417, 417, 594, 2602, - 3066, 1108, 1297, 503, 403, 2017, 450, 594, 328, 594, - 447, 1725, 609, 609, 1288, 461, 463, 2033, 1943, 1944, - 461, 594, 609, 503, 609, 782, 2609, 463, 411, 172, - 653, 499, 495, 498, 653, 2792, 609, 683, 485, 497, - 2980, 499, 1076, 501, 492, 641, 642, 433, 381, 485, - 499, 2988, 499, 403, 500, 499, 502, 499, 1088, 500, - 499, 502, 499, 499, 2987, 499, 392, 663, 499, 395, - 499, 499, 499, 499, 499, 2981, 495, 386, 386, 490, - 491, 1311, 2481, 546, 547, 499, 1558, 659, 672, 672, - 672, 499, 672, 499, 362, 499, 672, 672, 661, 120, - 582, 672, 77, 675, 132, 499, 702, 703, 704, 499, - 499, 2591, 5, 88, 672, 499, 1319, 1320, 1392, 499, - 499, 499, 499, 406, 499, 499, 499, 503, 393, 394, - 161, 594, 3072, 451, 490, 491, 499, 2722, 499, 672, - 499, 499, 499, 503, 499, 499, 609, 1420, 1421, 664, - 11, 2597, 1425, 3062, 499, 492, 493, 494, 495, 3065, - 1894, 497, 305, 672, 513, 501, 173, 1880, 3098, 437, - 495, 672, 193, 38, 56, 396, 672, 672, 3098, 672, - 672, 672, 672, 149, 3034, 672, 782, 672, 672, 672, - 653, 672, 57, 672, 543, 672, 672, 672, 672, 672, - 672, 672, 672, 1433, 235, 3114, 60, 2725, 499, 672, - 490, 491, 461, 970, 75, 441, 1845, 1667, 2266, 2267, - 2268, 2269, 1478, 4, 820, 1290, 329, 1677, 9, 3169, - 1680, 499, 198, 2836, 455, 334, 485, 3149, 245, 382, - 69, 490, 491, 108, 272, 1501, 1875, 1477, 1522, 1479, - 1506, 0, 1317, 284, 282, 358, 580, 1487, 582, 1993, - 1732, 3025, 3026, 2297, 2243, 244, 1376, 4, 1333, 502, - 3182, 161, 9, 499, 1366, 1367, 166, 1507, 171, 244, - 3130, 1373, 492, 493, 494, 495, 1915, 1561, 117, 171, - 1452, 1853, 451, 1778, 1447, 1457, 4, 1553, 1460, 623, - 2309, 9, 1375, 1060, 1560, 117, 1562, 406, 1440, 499, - 3074, 119, 1376, 1369, 1760, 664, 912, 1803, 1760, 1761, - 1762, 645, 918, 919, 1760, 1761, 1759, 334, 1778, 25, - 494, 1604, 928, 463, 199, 931, 932, 501, 934, 935, - 936, 937, 25, 463, 915, 235, 1497, 1833, 31, 66, - 67, 948, 948, 2956, 453, 485, 953, 953, 1921, 1998, - 2941, 948, 2943, 948, 1741, 485, 953, 200, 953, 499, - 2175, 1128, 968, 969, 970, 948, 2181, 189, 1663, 2184, - 953, 1655, 2096, 362, 344, 250, 1763, 488, 1765, 2423, - 986, 1768, 244, 258, 284, 1019, 204, 362, 499, 406, - 251, 2326, 2327, 4, 177, 270, 2119, 1003, 9, 946, - 490, 491, 492, 493, 494, 495, 270, 1636, 1014, 1015, - 1016, 958, 1018, 1019, 961, 490, 491, 492, 493, 494, - 495, 3012, 410, 1525, 412, 494, 301, 1712, 1690, 1691, - 1692, 137, 501, 272, 1663, 1719, 453, 1043, 277, 1514, - 422, 132, 915, 2104, 137, 2322, 2019, 406, 437, 200, - 272, 244, 270, 1682, 272, 238, 1062, 1063, 1687, 77, - 1093, 1094, 437, 1096, 1093, 1094, 369, 1096, 159, 1987, - 88, 161, 2815, 348, 2817, 948, 166, 369, 497, 453, - 953, 320, 501, 463, 365, 349, 132, 272, 499, 1095, - 3030, 2158, 277, 1099, 1100, 370, 2163, 336, 1738, 500, - 362, 151, 503, 406, 1110, 485, 1088, 177, 5, 982, - 499, 2515, 376, 159, 406, 390, 410, 166, 412, 499, - 993, 171, 1128, 1290, 499, 1808, 1809, 1810, 1811, 1812, - 200, 334, 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, - 1823, 1824, 499, 328, 447, 235, 1019, 1153, 3161, 499, - 1317, 1318, 497, 2597, 499, 447, 501, 500, 461, 1165, - 503, 499, 1144, 3131, 3132, 499, 1333, 370, 238, 362, - 500, 1673, 1647, 503, 2509, 437, 1678, 2920, 912, 13, - 14, 3121, 485, 1189, 1783, 291, 277, 499, 1787, 923, - 1789, 282, 499, 3133, 284, 434, 499, 499, 291, 147, - 499, 1841, 441, 406, 13, 14, 25, 499, 3176, 13, - 14, 362, 31, 161, 172, 117, 13, 14, 166, 370, - 1093, 1094, 292, 1096, 171, 500, 272, 410, 485, 412, - 753, 277, 13, 14, 968, 2512, 282, 499, 492, 2278, - 346, 3181, 348, 1432, 437, 1434, 1435, 499, 206, 342, - 453, 499, 775, 346, 437, 406, 643, 644, 1778, 646, - 1943, 1944, 256, 257, 222, 500, 499, 215, 503, 171, - 376, 499, 8, 500, 232, 11, 503, 1752, 499, 15, - 2404, 2558, 1288, 376, 1290, 499, 809, 235, 2075, 2624, - 2077, 1025, 499, 1287, 1287, 1287, 2403, 1287, 1870, 497, - 1034, 499, 453, 221, 2388, 1311, 499, 43, 1948, 2204, - 500, 1317, 1318, 503, 50, 1049, 1791, 482, 137, 369, - 501, 500, 500, 1082, 503, 503, 1060, 1333, 1062, 1063, - 1992, 500, 1807, 424, 503, 2402, 284, 2404, 2445, 75, - 410, 287, 412, 500, 435, 293, 503, 1514, 13, 14, - 5, 444, 500, 8, 25, 503, 406, 482, 1878, 14, - 31, 1836, 500, 500, 434, 503, 503, 437, 1843, 501, - 1376, 26, 366, 367, 500, 30, 500, 503, 424, 503, - 500, 170, 2300, 503, 2357, 500, 1392, 500, 503, 435, - 503, 1397, 503, 500, 1375, 353, 503, 447, 300, 1874, - 500, 500, 1877, 1376, 503, 500, 500, 1882, 503, 145, - 499, 461, 25, 500, 1420, 1421, 503, 171, 31, 1425, - 500, 1427, 500, 503, 2759, 503, 1432, 1433, 1434, 1435, - 1427, 2875, 1427, 2944, 2139, 485, 2825, 217, 2179, 2180, - 176, 1447, 1448, 499, 1427, 1452, 1452, 13, 14, 499, - 1457, 1457, 56, 1460, 1460, 1452, 192, 1452, 13, 14, - 1457, 197, 1457, 1460, 221, 1460, 137, 369, 991, 1452, - 482, 1477, 291, 1479, 1457, 152, 500, 1460, 96, 503, - 1647, 1487, 1005, 2760, 8, 433, 342, 11, 1474, 1474, - 461, 15, 463, 1474, 18, 19, 20, 500, 234, 152, - 503, 1507, 1375, 1509, 406, 410, 1474, 412, 1514, 1515, - 1516, 1517, 1518, 1519, 1520, 1521, 1522, 152, 2202, 2603, - 1526, 1527, 2911, 342, 137, 1531, 2650, 346, 173, 1535, - 500, 1474, 1538, 1539, 1540, 1541, 1542, 1543, 1544, 1545, - 1546, 152, 3091, 1549, 3093, 447, 500, 272, 500, 503, - 1556, 503, 1558, 289, 172, 1561, 499, 376, 500, 461, - 410, 503, 412, 2423, 501, 187, 188, 25, 1601, 13, - 14, 500, 1601, 31, 503, 500, 1582, 38, 503, 1452, - 2078, 453, 2080, 485, 1457, 1752, 84, 1460, 206, 89, - 2387, 91, 2389, 93, 954, 465, 956, 499, 1604, 450, - 245, 1474, 316, 677, 222, 679, 499, 1580, 3157, 1615, - 1616, 1370, 499, 1372, 232, 13, 14, 13, 14, 152, - 291, 8, 13, 14, 1791, 444, 357, 358, 15, 13, - 14, 18, 19, 20, 256, 257, 13, 14, 2304, 499, - 1807, 1647, 3031, 2326, 2327, 381, 1589, 1653, 266, 1655, - 13, 14, 13, 14, 3098, 1528, 13, 14, 13, 14, - 13, 14, 499, 13, 14, 37, 13, 14, 499, 1836, - 499, 342, 152, 197, 152, 346, 1843, 25, 291, 137, - 13, 14, 2157, 31, 2204, 13, 14, 152, 1694, 334, - 287, 1697, 1698, 499, 1700, 219, 499, 2199, 260, 261, - 2366, 9, 366, 367, 499, 376, 2493, 1874, 25, 500, - 1877, 357, 358, 1719, 31, 1882, 1589, 151, 357, 358, - 1062, 1063, 408, 499, 217, 370, 1732, 222, 1601, 342, - 222, 3120, 1738, 346, 499, 353, 296, 171, 2422, 38, - 2424, 294, 233, 499, 366, 367, 1752, 483, 5, 1483, - 5, 499, 499, 499, 490, 491, 492, 493, 494, 495, - 499, 406, 5, 376, 5, 289, 499, 5, 5, 499, - 2455, 499, 1778, 444, 2881, 148, 2438, 9, 462, 298, - 503, 2641, 503, 99, 500, 1791, 1729, 38, 376, 137, - 166, 1797, 166, 233, 1800, 284, 1802, 282, 499, 499, - 417, 1807, 1808, 1809, 1810, 1811, 1812, 88, 453, 1815, - 1816, 1817, 1818, 1819, 1820, 1821, 1822, 1823, 1824, 417, - 137, 503, 56, 56, 1830, 1831, 2509, 417, 1834, 508, - 1836, 444, 263, 291, 1568, 1841, 417, 1843, 500, 417, - 461, 152, 95, 501, 272, 272, 38, 1720, 499, 932, - 272, 499, 499, 37, 415, 497, 1729, 1863, 2776, 415, - 1866, 2756, 500, 1870, 1870, 2548, 2653, 2654, 1874, 497, - 417, 1877, 1878, 1870, 1880, 1870, 1882, 417, 417, 417, - 1639, 171, 171, 503, 342, 1891, 8, 1870, 346, 11, - 1649, 500, 1651, 15, 500, 1654, 18, 19, 20, 500, - 500, 1660, 289, 1662, 500, 500, 500, 500, 500, 500, - 499, 1917, 458, 35, 1948, 1674, 1922, 500, 376, 1925, - 1679, 2587, 222, 499, 1683, 1684, 1685, 1686, 503, 1688, - 1689, 457, 2689, 11, 344, 369, 503, 1943, 1944, 498, - 503, 2624, 1948, 291, 508, 415, 277, 162, 2423, 171, - 8, 499, 180, 11, 96, 507, 1962, 15, 499, 1965, - 417, 1967, 486, 487, 488, 171, 490, 491, 492, 493, - 494, 495, 406, 503, 291, 3099, 2010, 171, 500, 499, - 215, 1987, 38, 1990, 1990, 43, 444, 441, 38, 503, - 2157, 263, 50, 1990, 342, 1990, 496, 1870, 346, 2006, - 2006, 57, 2574, 224, 379, 288, 309, 1990, 309, 2006, - 500, 2006, 224, 447, 2489, 2875, 503, 75, 2024, 2005, - 2005, 224, 499, 2006, 2005, 272, 293, 461, 376, 346, - 172, 8, 2534, 325, 11, 2041, 2042, 2005, 15, 285, - 453, 18, 19, 20, 1778, 152, 499, 499, 1782, 152, - 461, 485, 108, 109, 2060, 152, 38, 287, 35, 376, - 497, 117, 2005, 272, 206, 499, 482, 500, 500, 287, - 482, 500, 2078, 2079, 2080, 1948, 2759, 500, 300, 369, - 222, 500, 500, 38, 171, 11, 38, 145, 180, 166, - 232, 500, 500, 1966, 500, 499, 444, 219, 598, 486, - 487, 488, 499, 490, 491, 492, 493, 494, 495, 1982, - 500, 2145, 500, 2119, 499, 498, 406, 1990, 176, 175, - 2622, 500, 500, 482, 266, 171, 417, 444, 155, 499, - 501, 500, 2005, 2006, 192, 425, 500, 2010, 458, 197, - 447, 499, 287, 199, 1878, 287, 488, 369, 484, 2854, - 499, 2157, 288, 499, 288, 2322, 11, 447, 503, 439, - 15, 243, 2168, 503, 3082, 417, 272, 289, 152, 24, - 499, 461, 200, 152, 152, 369, 234, 2652, 417, 279, - 279, 36, 37, 344, 406, 500, 417, 687, 539, 498, - 417, 417, 38, 499, 250, 485, 2202, 285, 2204, 503, - 461, 287, 258, 500, 38, 152, 500, 277, 171, 499, - 498, 353, 406, 498, 270, 499, 272, 56, 500, 184, - 499, 721, 722, 723, 724, 447, 500, 500, 75, 500, - 143, 289, 500, 197, 500, 90, 2756, 2243, 3098, 461, - 171, 499, 219, 297, 2003, 301, 2243, 503, 2243, 350, - 500, 500, 500, 447, 86, 446, 2423, 499, 288, 152, - 2243, 539, 428, 485, 500, 175, 2300, 461, 38, 38, - 81, 6, 2145, 2957, 503, 499, 11, 499, 2334, 499, - 15, 2921, 499, 2923, 19, 2291, 21, 22, 23, 24, - 25, 485, 348, 28, 2300, 500, 31, 32, 2332, 441, - 500, 36, 37, 500, 2310, 499, 441, 2313, 503, 2315, - 500, 498, 289, 171, 370, 503, 2322, 2323, 499, 460, - 2326, 2327, 2489, 381, 500, 2331, 2332, 500, 500, 2335, - 488, 500, 3037, 503, 390, 500, 392, 1420, 1421, 395, - 500, 500, 1425, 2349, 500, 2512, 461, 82, 202, 117, - 2084, 3046, 38, 499, 89, 90, 91, 92, 93, 2365, - 224, 83, 3024, 190, 486, 487, 488, 500, 490, 491, - 492, 493, 494, 495, 277, 277, 501, 501, 501, 417, - 501, 3, 501, 5, 501, 501, 417, 501, 501, 501, - 501, 2558, 501, 501, 38, 2129, 501, 501, 488, 501, - 2875, 272, 2161, 501, 109, 501, 501, 501, 501, 461, - 501, 2145, 2418, 3097, 499, 287, 2422, 2423, 2424, 38, - 501, 501, 501, 499, 9, 483, 501, 2300, 501, 929, - 501, 782, 490, 491, 492, 493, 494, 495, 501, 501, - 501, 501, 501, 499, 501, 343, 69, 327, 501, 190, - 499, 499, 75, 88, 133, 336, 503, 500, 503, 2332, - 2454, 2454, 2454, 499, 2454, 88, 38, 152, 500, 124, - 2204, 1554, 152, 38, 500, 2209, 358, 2211, 500, 358, - 499, 2215, 2216, 2489, 499, 2652, 503, 38, 441, 111, - 112, 306, 446, 75, 117, 499, 119, 277, 248, 189, - 441, 428, 499, 2509, 782, 69, 2512, 290, 2451, 486, - 487, 488, 69, 490, 491, 492, 493, 494, 495, 9, - 500, 1604, 2689, 2529, 2530, 500, 499, 360, 56, 488, - 3032, 2537, 376, 2476, 270, 287, 2479, 428, 38, 499, - 202, 290, 2548, 290, 500, 287, 2552, 2553, 499, 287, - 500, 2557, 2558, 122, 500, 439, 2562, 357, 24, 2565, - 2566, 35, 672, 2405, 2570, 187, 188, 2574, 2574, 1661, - 2418, 2073, 2586, 3031, 2821, 3094, 2582, 2574, 2451, 2574, - 2646, 204, 3052, 3141, 2363, 2461, 2847, 3100, 3109, 1089, - 3134, 2574, 1115, 2760, 2898, 2066, 2079, 3097, 3107, 2397, - 2466, 2063, 2422, 2476, 3095, 0, 2479, 1366, 1317, 1285, - 2616, 2135, 2202, 2756, 1114, 2448, 1082, 947, 2624, 970, - 947, 2024, 1632, 3098, 2383, 2263, 1102, 1127, 1103, 3080, - 252, 253, 254, 255, 256, 257, 2041, 2643, 260, 261, - 1604, 2584, 2585, 3014, 2925, 1631, 2652, 19, 1148, 272, - 1105, 2410, 2006, 955, 277, 925, 1871, 594, 513, 2243, - 609, 2242, 2868, 2282, 923, 1335, 2425, 2426, 2427, 2428, - 2429, 2430, 2431, 2432, 2433, 2434, 3017, 1923, 923, 923, - 3018, 3128, 1966, 2689, 2025, 1700, 1892, 542, 543, 2423, - 1963, 2005, 970, 1448, 2582, 2141, 3007, 320, 923, 1580, - 95, 2574, 1376, 1878, 2364, 1581, 25, 82, 2875, -1, - -1, 2584, 2585, 336, 2448, -1, -1, -1, -1, -1, - -1, -1, -1, 2729, -1, 1808, 1809, 1810, 1811, 1812, - -1, -1, 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, - 1823, 1824, 2776, -1, 366, 367, -1, -1, -1, -1, - 2756, -1, 147, 2759, 2760, -1, -1, -1, -1, -1, - -1, 496, -1, -1, -1, 500, 161, -1, 503, -1, - 2776, 166, -1, -1, -1, -1, 171, 1128, 513, -1, - -1, -1, -1, -1, -1, 180, 2792, -1, -1, 184, - -1, 1291, -1, 8, -1, 2738, 11, 2803, 2804, -1, - 15, 2807, -1, 18, 19, 20, 541, 542, 543, 664, - -1, 434, -1, -1, -1, -1, -1, -1, 441, 2825, - 215, 2827, 8, -1, -1, 11, -1, 539, 2825, 15, - 2825, -1, 18, 19, 20, 25, -1, -1, -1, 2845, - 235, 31, 2825, -1, -1, 2579, -1, 582, 38, 35, - 1128, -1, -1, -1, -1, -1, -1, 479, 480, 594, - 1943, 1944, -1, 598, 2623, 2738, -1, 57, -1, 2875, - -1, -1, -1, -1, 609, 610, 611, -1, -1, -1, - 615, 616, -1, -1, -1, -1, -1, -1, -1, 284, - -1, -1, 287, -1, -1, -1, -1, -1, 293, -1, - -1, 2907, -1, 2776, -1, 2911, 641, 642, 643, 644, - -1, 646, -1, -1, 2911, 2921, 2911, 2923, 108, 2925, - -1, -1, -1, 2929, 659, -1, -1, 2933, 2911, 664, - -1, 3098, 327, -1, -1, -1, -1, -1, 2944, 1290, - 675, 2947, -1, 2886, 2887, -1, -1, 137, -1, -1, - 1450, 2957, 687, -1, -1, 350, 2962, -1, -1, -1, - 177, -1, -1, -1, -1, 8, 1317, 1318, 11, -1, - -1, -1, 15, -1, -1, 18, 19, 20, -1, -1, - 539, -1, 1333, 200, -1, -1, 721, 722, 723, 724, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 2734, -1, -1, -1, 219, 147, -1, -1, 3014, 199, - -1, 406, 1290, 2886, 2887, -1, -1, -1, -1, 161, - -1, 238, 2756, -1, 166, 3031, -1, -1, -1, -1, - -1, -1, -1, 219, 3031, 0, 3031, -1, 433, 1317, - 1318, -1, -1, 2986, -1, -1, 441, 3053, 3031, -1, - -1, -1, -1, -1, -1, 1333, -1, -1, -1, -1, - 250, -1, 3005, 458, -1, 460, 461, -1, 258, -1, - 782, -1, -1, 215, 289, 292, 3082, -1, -1, 1579, - 270, 1581, 2816, -1, 3027, -1, -1, 942, -1, -1, - -1, 3097, 3098, 235, 539, -1, -1, 2856, -1, -1, - -1, 291, 497, 289, 959, 500, 501, 502, -1, -1, - -1, 301, -1, 2986, 3120, -1, -1, 2876, 2877, -1, - -1, 3127, 3128, 3120, -1, 3120, -1, -1, -1, 1629, - 95, -1, 3005, -1, -1, -1, 2895, 3120, -1, -1, - -1, 2875, 284, 3149, -1, 362, -1, -1, -1, -1, - -1, 293, 342, -1, 3027, 38, 346, -1, 348, -1, - -1, -1, -1, 1514, -1, -1, -1, 1022, -1, -1, - 3113, -1, -1, -1, 57, -1, 3182, -1, -1, -1, - 370, -1, 147, -1, -1, -1, 376, 2946, -1, 924, - 925, -1, -1, 410, 929, 412, 161, -1, -1, -1, - 390, 166, -1, 938, 939, -1, 171, 942, 1708, 1709, - 1710, 428, -1, 948, -1, 180, -1, 434, 953, 184, - 437, -1, -1, 782, 959, 108, -1, 1082, 1083, -1, - -1, -1, -1, -1, -1, -1, 1514, -1, -1, 974, - 3113, -1, -1, 2326, 2327, 2979, 289, -1, 539, -1, - 215, -1, -1, -1, 444, -1, -1, -1, 970, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 235, 486, 487, 488, -1, 490, 491, 492, 493, 494, - 495, -1, -1, 8, -1, -1, 11, 1022, -1, -1, - 15, 433, 175, 18, 19, 20, 1647, -1, -1, -1, - 486, 487, 488, -1, 490, 491, 492, 493, 494, 495, - 35, -1, -1, -1, -1, -1, 199, -1, -1, 284, - -1, -1, 287, -1, -1, -1, -1, -1, 293, 1064, - -1, 1066, -1, -1, -1, -1, -1, 782, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 1082, 1083, -1, - -1, -1, -1, 1088, 1089, 497, -1, 1857, 500, 501, - -1, -1, 327, -1, 3098, 8, -1, 250, 11, 1647, - -1, -1, 15, -1, -1, 258, -1, -1, 25, 1114, - 1115, -1, -1, -1, 31, 350, -1, 270, -1, -1, - -1, 38, 1127, -1, -1, -1, 38, -1, -1, -1, - 43, 1752, -1, -1, -1, -1, -1, 50, -1, 1144, - 57, 970, -1, 1148, -1, 57, 1128, -1, 301, -1, - -1, -1, -1, -1, -1, -1, 2509, -1, -1, -1, - -1, -1, 75, -1, -1, -1, -1, -1, -1, -1, - 1791, 406, -1, 486, 487, 488, -1, 490, 491, 492, - 493, 494, 495, -1, -1, -1, 1807, -1, -1, -1, - -1, 108, -1, -1, -1, 348, 108, -1, 433, -1, - -1, -1, -1, -1, 1752, -1, 441, -1, -1, -1, - -1, -1, -1, -1, -1, 1836, -1, 370, -1, -1, - 137, 782, 1843, 458, 219, 460, 461, -1, -1, -1, - -1, -1, 145, -1, -1, -1, -1, 390, -1, -1, - -1, -1, -1, 1791, 1369, 1370, -1, 1372, -1, -1, - -1, -1, -1, 1874, -1, 970, 1877, -1, -1, 1807, - -1, 1882, 497, 176, -1, 500, 501, 502, -1, -1, - -1, 2624, -1, -1, -1, -1, -1, -1, 1283, 192, - -1, -1, 199, -1, 197, -1, 1291, 199, 1836, -1, - -1, -1, -1, -1, 289, 1843, 1301, -1, -1, 1128, - -1, -1, 8, 0, -1, 11, -1, -1, 1290, 15, - -1, -1, 18, 19, 20, -1, -1, -1, -1, -1, - 1445, 234, -1, -1, -1, 1330, 1874, -1, -1, 1877, - 1335, -1, -1, 250, 1882, 1317, 1318, 1462, 250, -1, - 1465, 258, -1, -1, -1, -1, 258, -1, -1, -1, - -1, 1333, -1, 270, -1, -1, -1, -1, 270, -1, - -1, 1366, 1367, -1, 1369, 1370, 2136, 1372, 1373, -1, - -1, -1, -1, -1, 291, -1, 289, -1, 2148, 2149, - 2150, -1, -1, -1, 301, -1, -1, -1, -1, 301, - -1, -1, -1, -1, -1, 2165, -1, -1, 95, -1, - 2170, -1, -1, -1, -1, -1, 2759, -1, -1, 970, - -1, -1, -1, 1128, -1, -1, -1, -1, -1, -1, - -1, -1, 1427, -1, -1, 342, -1, -1, -1, 346, - -1, 348, -1, -1, -1, 1440, 348, 1442, -1, -1, - 1445, -1, 1447, 1448, -1, 1450, -1, 1452, -1, -1, - 147, -1, 1457, 370, -1, 1460, -1, 1462, 370, 376, - 1465, 1290, -1, -1, 161, -1, -1, -1, 381, 166, - -1, -1, -1, 390, 171, -1, -1, -1, 390, -1, - -1, 1486, -1, 180, -1, -1, 1491, 184, 1317, 1318, - -1, 486, 487, 488, -1, 490, 491, 492, 493, 494, - 495, 2271, 2272, 2273, 1333, -1, -1, -1, -1, -1, - -1, -1, -1, 219, 1639, -1, -1, -1, 215, -1, - 1525, -1, -1, -1, 1649, -1, 1651, 444, -1, 1654, - -1, -1, 1514, -1, -1, 1660, 2157, 1662, 235, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 1674, - -1, 1556, -1, -1, 1679, -1, -1, -1, 1683, 1684, - 1685, 1686, -1, 1688, 1689, -1, -1, 1128, -1, 23, - 483, -1, 1577, -1, 1579, 1290, 1581, 490, 491, 492, - 493, 494, 495, 289, -1, -1, 1591, 284, -1, -1, - 287, -1, -1, -1, -1, -1, 293, -1, -1, -1, - -1, -1, 1317, 1318, -1, -1, -1, -1, -1, 2157, - -1, 2381, -1, -1, -1, -1, -1, -1, 1333, -1, - -1, -1, 76, -1, 1629, -1, -1, -1, -1, -1, - 327, -1, -1, 1638, 1639, -1, -1, -1, 92, -1, - -1, -1, -1, -1, 1649, 1650, 1651, 1652, -1, 1654, - -1, -1, -1, 350, -1, 1660, -1, 1662, -1, -1, - -1, -1, -1, -1, -1, 1647, -1, -1, 1673, 1674, - -1, -1, -1, 1678, 1679, -1, -1, -1, 1683, 1684, - 1685, 1686, -1, 1688, 1689, 1514, 2456, -1, -1, 111, - 112, -1, 146, -1, -1, -1, -1, -1, -1, -1, - -1, 2322, 156, 1708, 1709, 1710, 1711, -1, -1, 406, - -1, -1, -1, -1, 168, -1, -1, -1, -1, 173, - 1845, -1, 1727, -1, -1, -1, -1, -1, -1, 1290, - -1, -1, -1, -1, -1, -1, 433, -1, -1, -1, - -1, -1, -1, -1, 441, -1, 200, -1, -1, -1, - 1875, -1, 2522, 2523, 2524, 2525, 1317, 1318, -1, -1, - -1, 458, -1, 460, 461, 187, 188, -1, -1, -1, - 1752, -1, 1333, -1, 2322, -1, -1, -1, -1, -1, - 486, 487, 488, -1, 490, 491, 492, 493, 494, 495, - 1915, 245, -1, -1, -1, 249, -1, -1, 1923, 1514, - 497, -1, 2423, 500, 501, 502, -1, -1, -1, 1791, - -1, -1, -1, -1, -1, -1, -1, -1, 1647, -1, - -1, -1, -1, -1, -1, 1807, -1, -1, -1, -1, - 252, 253, 254, 255, 256, 257, -1, -1, 260, 261, - 1845, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 1857, -1, 1836, -1, -1, -1, 312, -1, - 2630, 1843, -1, -1, -1, 1870, -1, -1, 2489, -1, - 1875, -1, 326, -1, -1, 2423, -1, -1, 2003, -1, - -1, -1, 8, -1, -1, 11, -1, -1, -1, 15, - -1, 2512, 1874, -1, -1, 1877, -1, -1, -1, -1, - 1882, -1, -1, -1, -1, 359, -1, -1, 362, -1, - 1915, -1, -1, -1, 1919, -1, 370, 43, 1923, 373, - -1, -1, -1, 1752, 50, -1, -1, -1, -1, -1, - -1, -1, 1647, -1, -1, -1, -1, 2558, 392, -1, - -1, 2489, -1, -1, 366, 367, -1, -1, -1, 75, - -1, -1, 406, 1514, -1, 1960, -1, -1, -1, 413, - -1, -1, 1791, -1, 2512, -1, -1, -1, 422, -1, - -1, -1, -1, -1, 428, -1, -1, -1, 1807, -1, - 8, -1, -1, 11, -1, 1990, -1, 15, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 2003, 453, - -1, 2006, -1, -1, -1, 2010, -1, 1836, 2013, 2014, - 2558, -1, -1, -1, 1843, 43, -1, -1, -1, 145, - -1, -1, 50, -1, -1, -1, -1, -1, -1, -1, - -1, 2652, -1, -1, -1, -1, 2161, 1752, -1, 8, - -1, -1, 11, -1, -1, 1874, 15, 75, 1877, -1, - 176, -1, -1, 1882, -1, -1, -1, 479, 480, -1, - -1, -1, -1, 2068, -1, -1, 192, -1, 2689, -1, - -1, 197, -1, -1, 43, -1, 1791, 499, -1, -1, - -1, 50, -1, -1, -1, -1, 1647, -1, -1, -1, - -1, -1, 1807, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 2652, -1, 75, -1, 234, -1, - -1, -1, -1, -1, -1, -1, -1, 145, -1, 2889, - -1, 1836, -1, -1, -1, -1, 2131, -1, 1843, -1, - -1, 2136, -1, -1, -1, -1, -1, -1, 2908, 2760, - -1, 2689, 2147, 2148, 2149, 2150, -1, -1, 176, -1, - -1, -1, -1, 2278, -1, -1, 2161, 2282, -1, 1874, - 2165, -1, 1877, 289, 192, 2170, -1, 1882, -1, 197, - -1, -1, -1, -1, -1, 2157, 145, 2182, -1, -1, - -1, -1, -1, -1, -1, 2955, -1, -1, -1, -1, - -1, 1752, -1, -1, 2199, -1, -1, -1, -1, -1, - -1, -1, 111, 112, -1, -1, 234, 176, 2213, 2214, - -1, -1, 2760, -1, -1, 2985, -1, -1, -1, -1, - -1, -1, -1, 192, -1, -1, -1, -1, 197, -1, - 1791, -1, -1, -1, -1, -1, -1, -1, 2243, -1, - -1, -1, -1, -1, -1, -1, 1807, -1, -1, -1, - -1, -1, -1, -1, 2875, 381, -1, 2262, 2383, -1, - -1, 289, -1, -1, -1, 234, 2271, 2272, 2273, -1, - -1, -1, -1, 2278, -1, 1836, -1, 2282, 187, 188, - -1, -1, 1843, -1, -1, 2410, -1, -1, -1, -1, - -1, -1, 2297, -1, -1, -1, -1, -1, -1, -1, - 2425, 2426, 2427, 2428, 2429, 2430, 2431, 2432, 2433, 2434, - -1, -1, -1, 1874, -1, -1, 1877, -1, -1, -1, - 289, 1882, -1, -1, -1, -1, -1, 2875, 2157, -1, + 7, 7, 41, 66, 0, 0, 0, 0, 720, 570, + 686, 0, 728, 706, 21, 21, 945, 969, 814, 1181, + 730, 732, 945, 632, 1348, 1537, 1192, 1179, 18, 7, + 739, 1090, 1154, 820, 2131, 1121, 958, 68, 2054, 1608, + 1231, 2057, 68, 21, 33, 958, 1368, 0, 0, 0, + 2082, 1159, 1156, 2085, 1373, 0, 21, 1517, 34, 1648, + 1150, 563, 1651, 634, 561, 569, 561, 958, 639, 570, + 720, 644, 722, 18, 724, 663, 958, 1085, 2513, 564, + 1184, 0, 0, 561, 1092, 1562, 1563, 1005, 1478, 0, + 0, 0, 0, 845, 0, 847, 2511, 0, 1422, 0, + 89, 0, 0, 1055, 0, 0, 679, 0, 0, 40, + 0, 0, 2022, 2127, 2526, 0, 2533, 0, 0, 0, + 0, 0, 24, 99, 2073, 593, 18, 5, 0, 21, + 21, 2482, 2482, 2175, 2176, 2177, 2364, 1615, 0, 772, + 773, 33, 5, 11, 56, 1766, 703, 15, 5, 41, + 13, 14, 5, 1349, 5, 52, 703, 5, 698, 13, + 14, 1669, 5, 5, 5, 5, 5, 9, 5, 1098, + 5, 804, 13, 14, 5, 851, 68, 5, 13, 14, + 5, 2190, 13, 14, 5, 13, 14, 5, 13, 14, + 9, 5, 5, 2207, 5, 13, 14, 89, 2797, 13, + 14, 5, 13, 14, 1894, 13, 14, 1671, 5, 13, + 14, 5, 2201, 5, 2813, 5, 13, 14, 5, 13, + 14, 5, 9, 95, 4, 42, 60, 5, 5, 9, + 60, 5, 5, 95, 5, 5, 5, 5, 5, 1168, + 109, 29, 1171, 1172, 42, 638, 171, 29, 36, 3, + 4, 5, 172, 1577, 36, 9, 189, 122, 119, 171, + 1047, 2275, 2276, 287, 2278, 11, 285, 309, 3, 15, + 9, 293, 139, 2810, 60, 244, 1194, 171, 954, 8, + 224, 2699, 11, 171, 60, 2945, 15, 1361, 1206, 18, + 19, 20, 1002, 171, 244, 293, 122, 43, 33, 34, + 2639, 124, 288, 2642, 3052, 29, 35, 273, 172, 224, + 309, 137, 36, 2329, 3021, 191, 191, 359, 69, 814, + 2403, 358, 276, 2406, 77, 70, 270, 379, 3083, 75, + 2774, 2450, 335, 77, 4, 88, 814, 161, 3, 9, + 61, 2886, 85, 2888, 88, 75, 8, 109, 69, 11, + 165, 117, 2449, 15, 119, 270, 18, 19, 20, 161, + 443, 117, 2404, 117, 3147, 784, 38, 2966, 5, 443, + 2805, 1167, 132, 122, 983, 967, 11, 110, 1054, 988, + 3012, 2816, 3014, 406, 945, 3133, 129, 806, 3136, 960, + 1023, 1024, 2807, 1103, 363, 110, 38, 172, 1865, 108, + 2432, 2358, 1726, 974, 407, 1038, 132, 1731, 2758, 13, + 14, 235, 370, 363, 110, 287, 331, 168, 501, 442, + 407, 163, 841, 189, 2543, 287, 1956, 501, 1895, 561, + 384, 206, 2446, 235, 2448, 170, 380, 172, 3193, 501, + 75, 305, 3225, 1004, 948, 110, 2991, 222, 2405, 501, + 29, 2361, 455, 0, 496, 3087, 1530, 232, 370, 11, + 284, 210, 216, 15, 501, 380, 211, 11, 11, 438, + 345, 15, 348, 1149, 440, 3223, 370, 501, 1938, 351, + 23, 24, 501, 505, 238, 3192, 2904, 1060, 438, 351, + 219, 43, 370, 418, 320, 407, 440, 496, 2837, 2943, + 11, 316, 2585, 175, 15, 2923, 272, 505, 270, 3169, + 2022, 1006, 277, 407, 3051, 501, 350, 238, 1091, 383, + 350, 277, 282, 75, 513, 440, 2056, 269, 1006, 407, + 418, 570, 501, 175, 504, 197, 3135, 449, 407, 1100, + 1101, 250, 2954, 1236, 505, 1118, 272, 505, 2562, 258, + 2539, 501, 60, 132, 561, 449, 282, 219, 1749, 102, + 289, 304, 166, 570, 350, 490, 959, 453, 501, 1691, + 321, 449, 2084, 2670, 350, 440, 66, 67, 503, 354, + 570, 501, 2059, 2091, 445, 463, 1126, 404, 2209, 501, + 1147, 463, 459, 632, 2945, 2945, 2286, 3134, 2076, 387, + 1147, 463, 1798, 1098, 501, 387, 404, 501, 1027, 487, + 617, 617, 465, 452, 465, 3050, 1920, 1921, 1922, 1781, + 443, 513, 1041, 501, 569, 632, 632, 289, 2092, 497, + 502, 1342, 504, 1349, 487, 2863, 487, 494, 501, 617, + 502, 3058, 504, 706, 675, 3057, 1114, 501, 501, 675, + 501, 499, 617, 501, 632, 503, 663, 664, 501, 501, + 501, 501, 501, 387, 501, 418, 501, 632, 2677, 412, + 501, 505, 1167, 501, 418, 505, 501, 569, 570, 686, + 501, 500, 814, 501, 435, 1361, 1852, 501, 501, 1167, + 501, 440, 1610, 501, 684, 29, 149, 501, 244, 695, + 695, 695, 695, 605, 501, 681, 695, 501, 3143, 501, + 2659, 501, 492, 493, 501, 1424, 3131, 501, 453, 726, + 727, 728, 698, 501, 501, 617, 1442, 501, 501, 505, + 501, 501, 501, 501, 501, 50, 1369, 1370, 492, 493, + 632, 632, 695, 695, 695, 198, 3229, 120, 5, 2791, + 695, 497, 1943, 492, 493, 2665, 687, 394, 395, 488, + 489, 490, 270, 492, 493, 494, 495, 496, 497, 499, + 3185, 490, 39, 503, 120, 163, 695, 695, 501, 397, + 3263, 2795, 501, 675, 695, 695, 695, 695, 411, 695, + 413, 1720, 695, 463, 695, 420, 695, 695, 132, 695, + 695, 1730, 695, 695, 1733, 695, 695, 814, 1484, 2906, + 695, 3246, 695, 695, 695, 695, 695, 487, 3169, 3169, + 193, 1907, 492, 493, 13, 14, 488, 489, 490, 132, + 492, 493, 494, 495, 496, 497, 1333, 119, 1333, 457, + 228, 466, 350, 171, 851, 1347, 25, 193, 1558, 2361, + 981, 463, 1938, 1529, 1530, 1333, 159, 349, 1574, 126, + 345, 176, 1538, 994, 11, 1426, 997, 147, 15, 377, + 1367, 1789, 1367, 1368, 1006, 487, 32, 192, 69, 1471, + 1472, 244, 197, 1559, 1476, 377, 1383, 117, 1383, 1367, + 1368, 1977, 438, 1603, 1503, 2372, 43, 1613, 1820, 1508, + 56, 1510, 1612, 1512, 1614, 1383, 496, 1915, 1821, 1838, + 1498, 4, 465, 503, 1416, 1838, 9, 2307, 2237, 234, + 1491, 1425, 204, 490, 2243, 1426, 117, 2246, 75, 3026, + 1821, 1822, 1823, 1418, 487, 215, 503, 2261, 945, 1821, + 1822, 171, 494, 495, 496, 497, 953, 954, 492, 493, + 494, 495, 496, 497, 200, 501, 963, 29, 137, 966, + 967, 244, 969, 970, 971, 972, 330, 110, 171, 272, + 2482, 2061, 300, 200, 277, 1548, 983, 983, 77, 282, + 77, 988, 988, 494, 495, 496, 497, 2178, 270, 88, + 272, 88, 1708, 2155, 2704, 359, 110, 1004, 1005, 1006, + 363, 272, 2712, 948, 1716, 983, 277, 4, 80, 505, + 988, 132, 9, 293, 1606, 1022, 1055, 89, 983, 2078, + 411, 423, 413, 988, 496, 11, 2330, 2331, 2332, 2333, + 251, 503, 1039, 499, 177, 1167, 407, 503, 159, 1689, + 256, 257, 370, 1050, 1051, 1052, 118, 1054, 1055, 455, + 1802, 499, 1745, 1746, 1747, 503, 948, 43, 329, 2163, + 603, 1770, 605, 2385, 366, 1657, 1716, 382, 501, 1566, + 300, 1566, 1824, 1825, 1081, 438, 1828, 501, 25, 407, + 363, 272, 1798, 501, 31, 1735, 277, 166, 1566, 75, + 1740, 983, 983, 1100, 1101, 238, 988, 988, 2050, 25, + 501, 1132, 1133, 646, 1135, 31, 1132, 1133, 161, 1135, + 2218, 1843, 291, 166, 501, 1847, 2224, 189, 1850, 2579, + 244, 449, 425, 1799, 667, 501, 1018, 1134, 244, 201, + 321, 1138, 1139, 436, 173, 463, 363, 1029, 501, 96, + 370, 3238, 1149, 499, 371, 501, 337, 3163, 3100, 3101, + 1126, 367, 368, 2665, 434, 438, 277, 4, 501, 487, + 1167, 282, 9, 1055, 4, 173, 465, 370, 347, 9, + 349, 177, 502, 501, 161, 505, 2656, 407, 3194, 166, + 407, 2661, 235, 1483, 501, 1485, 1486, 1194, 487, 499, + 137, 501, 501, 503, 25, 3227, 3228, 3149, 377, 1206, + 31, 1333, 501, 1700, 407, 1700, 245, 1183, 501, 665, + 666, 137, 668, 502, 501, 172, 505, 25, 501, 449, + 171, 3237, 1700, 31, 1231, 487, 502, 1903, 455, 505, + 3262, 284, 238, 463, 494, 1367, 1368, 245, 501, 363, + 1132, 1133, 501, 1135, 435, 3261, 449, 363, 235, 206, + 502, 1383, 443, 505, 2576, 502, 2342, 487, 505, 502, + 463, 502, 505, 502, 505, 222, 505, 501, 411, 335, + 413, 501, 484, 502, 2598, 232, 505, 1838, 1870, 1871, + 1872, 1873, 1874, 501, 487, 1877, 1878, 1879, 1880, 1881, + 1882, 1883, 1884, 1885, 1886, 438, 335, 284, 501, 989, + 2622, 2463, 992, 501, 425, 371, 137, 13, 14, 266, + 2462, 25, 287, 25, 438, 436, 1813, 31, 1813, 31, + 221, 393, 438, 1932, 396, 2447, 1333, 335, 502, 137, + 287, 505, 371, 503, 2010, 1813, 1332, 1332, 1332, 1332, + 484, 407, 1349, 2266, 291, 492, 493, 494, 495, 496, + 497, 503, 2504, 2461, 1361, 2463, 1853, 314, 1853, 465, + 1367, 1368, 2055, 170, 502, 291, 2690, 505, 407, 463, + 505, 465, 1869, 25, 1869, 1853, 1383, 501, 501, 31, + 1941, 487, 2134, 502, 2136, 501, 505, 502, 171, 455, + 505, 1869, 411, 502, 413, 501, 343, 354, 502, 407, + 347, 1898, 945, 1898, 292, 411, 502, 413, 1905, 505, + 1905, 56, 2364, 2005, 2006, 958, 455, 343, 501, 1426, + 1898, 347, 411, 137, 413, 137, 502, 1905, 502, 505, + 377, 505, 438, 2945, 1566, 1442, 1426, 2137, 484, 2139, + 1937, 1448, 1937, 1940, 221, 1940, 3015, 455, 1945, 152, + 1945, 377, 343, 502, 2241, 2242, 505, 13, 14, 1937, + 291, 1004, 1940, 561, 1471, 1472, 2446, 1945, 2448, 1476, + 502, 1478, 1478, 505, 13, 14, 1483, 1484, 1485, 1486, + 1425, 502, 152, 291, 505, 137, 443, 502, 152, 2200, + 505, 1498, 1499, 13, 14, 502, 1503, 1503, 505, 446, + 1478, 1508, 1508, 1510, 1510, 1512, 1512, 502, 502, 2831, + 505, 505, 343, 1478, 6, 152, 347, 9, 502, 1062, + 446, 505, 1529, 1530, 16, 1503, 502, 38, 1071, 505, + 1508, 1538, 1510, 1425, 1512, 343, 28, 1526, 1503, 347, + 32, 13, 14, 1508, 1087, 1510, 377, 1512, 2264, 2671, + 13, 14, 1559, 2482, 1561, 1098, 2718, 1100, 1101, 1566, + 1567, 1568, 1569, 1570, 1571, 1572, 1573, 1574, 1700, 377, + 502, 1578, 1579, 1526, 1526, 1526, 1583, 291, 501, 291, + 1587, 1526, 177, 1590, 1591, 1592, 1593, 1594, 1595, 1596, + 1597, 1598, 2982, 502, 1601, 2654, 505, 502, 272, 502, + 505, 1608, 505, 1610, 502, 200, 1613, 505, 3197, 171, + 3199, 1503, 1503, 13, 14, 446, 1508, 1508, 1510, 1510, + 1512, 1512, 700, 1654, 702, 151, 2792, 1634, 1654, 343, + 272, 3021, 38, 347, 1526, 347, 13, 14, 446, 291, + 147, 147, 1632, 238, 502, 171, 502, 505, 84, 505, + 1657, 13, 14, 455, 161, 161, 152, 3169, 3247, 166, + 166, 1668, 1669, 377, 505, 377, 5, 13, 14, 13, + 14, 13, 14, 13, 14, 13, 14, 13, 14, 13, + 14, 1813, 13, 14, 13, 14, 13, 14, 1580, 13, + 14, 343, 503, 1700, 3, 347, 467, 292, 452, 1706, + 501, 1708, 13, 14, 317, 2266, 501, 8, 215, 215, + 11, 13, 14, 152, 15, 2425, 814, 18, 19, 20, + 2217, 1853, 2217, 13, 14, 377, 358, 359, 235, 235, + 152, 38, 446, 501, 446, 358, 359, 1869, 501, 2217, + 367, 368, 1749, 260, 261, 1752, 1753, 152, 1755, 501, + 57, 358, 359, 37, 3144, 501, 12, 358, 359, 151, + 287, 17, 1654, 1100, 1101, 2481, 1898, 2483, 363, 152, + 26, 110, 345, 1905, 501, 418, 501, 284, 284, 171, + 2709, 38, 1789, 39, 40, 1328, 293, 293, 9, 502, + 501, 1798, 1799, 409, 446, 222, 1785, 2389, 2390, 2951, + 57, 108, 3192, 2555, 2497, 1937, 1813, 2516, 1940, 501, + 217, 296, 222, 1945, 222, 501, 411, 294, 413, 38, + 233, 3145, 3146, 3147, 501, 2536, 5, 5, 501, 501, + 501, 1838, 501, 5, 429, 5, 501, 5, 177, 501, + 435, 97, 5, 438, 370, 148, 1853, 9, 3, 464, + 501, 108, 1859, 298, 99, 1862, 505, 1864, 505, 217, + 284, 200, 1869, 1870, 1871, 1872, 1873, 1874, 175, 502, + 1877, 1878, 1879, 1880, 1881, 1882, 1883, 1884, 1885, 1886, + 38, 407, 3048, 377, 1776, 1892, 1893, 187, 188, 1896, + 2385, 1898, 199, 1785, 166, 2847, 1903, 166, 1905, 238, + 282, 3225, 1445, 233, 2827, 501, 418, 2385, 1006, 501, + 418, 88, 505, 56, 56, 418, 263, 418, 1925, 502, + 171, 1928, 511, 449, 152, 1932, 1932, 434, 434, 418, + 1937, 463, 152, 1940, 1941, 95, 1943, 463, 1945, 272, + 272, 501, 199, 250, 38, 503, 1953, 272, 501, 272, + 501, 258, 37, 292, 1932, 416, 256, 257, 416, 499, + 502, 487, 2758, 270, 499, 418, 418, 1932, 418, 2721, + 2722, 2010, 1979, 502, 418, 501, 171, 1984, 370, 502, + 1987, 2573, 460, 502, 502, 2482, 502, 2482, 289, 502, + 505, 1534, 499, 250, 301, 502, 503, 502, 2005, 2006, + 8, 258, 502, 2010, 2482, 502, 501, 15, 3170, 502, + 18, 19, 20, 270, 502, 407, 2945, 2024, 222, 501, + 2027, 505, 2029, 11, 363, 459, 345, 1471, 1472, 2638, + 500, 505, 1476, 501, 505, 52, 511, 510, 416, 277, + 1932, 1932, 349, 2050, 301, 501, 2053, 2053, 418, 180, + 162, 171, 443, 502, 2551, 501, 2551, 449, 505, 215, + 263, 288, 2069, 2069, 371, 505, 380, 367, 368, 1167, + 224, 463, 411, 2551, 413, 2053, 2083, 1620, 309, 2068, + 97, 2576, 2071, 309, 391, 2217, 505, 502, 2053, 501, + 429, 2069, 349, 2100, 2101, 487, 435, 224, 2576, 438, + 2692, 272, 224, 293, 2069, 285, 123, 171, 326, 501, + 455, 501, 2119, 501, 371, 2068, 2068, 2068, 2010, 370, + 152, 152, 152, 2068, 141, 152, 463, 2622, 145, 38, + 2137, 2138, 2139, 272, 391, 287, 2028, 502, 502, 499, + 287, 484, 38, 484, 2622, 502, 502, 502, 502, 56, + 167, 171, 2044, 170, 11, 38, 407, 166, 180, 171, + 418, 2053, 2053, 155, 460, 38, 2205, 502, 185, 288, + 486, 2178, 288, 440, 502, 426, 2068, 2069, 2069, 2071, + 502, 501, 503, 501, 2894, 502, 501, 488, 489, 490, + 502, 492, 493, 494, 495, 496, 497, 96, 449, 484, + 505, 7, 8, 500, 502, 3157, 12, 502, 502, 502, + 2217, 17, 463, 2924, 501, 21, 490, 23, 24, 25, + 26, 27, 2229, 2720, 30, 2720, 501, 33, 34, 505, + 36, 501, 243, 39, 40, 1333, 487, 501, 2830, 272, + 3169, 501, 2720, 418, 152, 502, 200, 152, 152, 418, + 501, 418, 418, 2385, 418, 561, 279, 2264, 279, 2266, + 277, 502, 501, 2758, 500, 171, 2827, 38, 285, 1367, + 1368, 345, 502, 172, 287, 285, 532, 463, 38, 177, + 2758, 289, 505, 89, 38, 1383, 152, 502, 500, 306, + 96, 97, 98, 99, 100, 1838, 277, 502, 500, 1842, + 2307, 2307, 200, 57, 171, 501, 56, 206, 501, 565, + 502, 3027, 329, 2205, 502, 502, 2992, 75, 2994, 184, + 143, 502, 197, 222, 69, 2364, 502, 171, 501, 2307, + 75, 297, 351, 232, 2397, 449, 2831, 502, 287, 152, + 238, 288, 2307, 88, 505, 502, 505, 175, 2355, 502, + 2482, 501, 501, 2831, 108, 501, 2395, 2364, 502, 429, + 38, 967, 502, 38, 502, 502, 2373, 266, 502, 2376, + 505, 2378, 117, 501, 119, 81, 443, 2416, 2385, 2386, + 505, 171, 2389, 2390, 501, 500, 462, 2394, 2395, 502, + 448, 2398, 502, 502, 292, 3106, 502, 505, 1941, 502, + 502, 86, 490, 3115, 502, 2412, 3099, 502, 463, 202, + 117, 38, 501, 224, 83, 314, 190, 2424, 277, 2551, + 503, 277, 503, 503, 503, 503, 1870, 1871, 1872, 1873, + 1874, 687, 503, 1877, 1878, 1879, 1880, 1881, 1882, 1883, + 1884, 1885, 1886, 503, 2576, 199, 8, 503, 2945, 11, + 2945, 503, 3168, 15, 503, 354, 18, 19, 20, 204, + 503, 503, 503, 503, 503, 503, 503, 2945, 1566, 503, + 2477, 38, 2364, 35, 2481, 2482, 2483, 503, 503, 503, + 488, 489, 490, 490, 492, 493, 494, 495, 496, 497, + 2622, 418, 418, 272, 109, 463, 250, 503, 503, 503, + 503, 503, 503, 2395, 258, 503, 503, 503, 814, 503, + 503, 501, 503, 411, 503, 413, 270, 503, 503, 2515, + 2515, 2515, 2515, 2512, 2416, 502, 38, 272, 287, 501, + 9, 501, 277, 1139, 344, 190, 501, 435, 505, 328, + 438, 505, 502, 337, 2551, 501, 38, 301, 152, 2538, + 502, 124, 2541, 152, 38, 359, 502, 359, 38, 502, + 501, 2005, 2006, 501, 38, 505, 2573, 443, 306, 2576, + 88, 501, 133, 277, 248, 189, 321, 429, 501, 443, + 69, 290, 69, 9, 75, 502, 2593, 2594, 2720, 502, + 501, 361, 337, 56, 2601, 349, 490, 448, 270, 287, + 2143, 38, 1700, 429, 501, 2612, 290, 290, 501, 2616, + 2617, 502, 502, 377, 2621, 2622, 202, 371, 502, 2626, + 2512, 287, 2629, 2630, 287, 122, 2758, 2634, 440, 358, + 24, 2638, 2638, 35, 695, 2464, 561, 391, 2132, 2646, + 2893, 1714, 3017, 2422, 2477, 2188, 2538, 3210, 3144, 2541, + 2714, 2522, 3121, 2196, 3218, 2917, 3171, 219, 3180, 3211, + 2638, 2968, 2205, 1154, 2125, 2138, 3178, 2527, 3168, 2481, + 2122, 2456, 3169, 2638, 3169, 3166, 1367, 2684, 2194, 2264, + 1330, 2827, 1120, 982, 2083, 2692, 1685, 2507, 1142, 2327, + 435, 3169, 3155, 982, 1657, 2100, 1684, 3089, 443, 2831, + 1006, 2996, 1144, 21, 2711, 960, 1141, 2069, 514, 990, + 516, 632, 1934, 2720, 520, 1813, 617, 523, 2307, 2306, + 2346, 2938, 1385, 2266, 958, 958, 532, 289, 2271, 958, + 2273, 537, 3092, 958, 2277, 3093, 2279, 1985, 2028, 3206, + 2084, 1954, 1755, 1499, 2025, 2068, 2638, 2638, 2202, 3078, + 604, 2758, 1632, 1941, 36, 1853, 2423, 563, 564, 565, + 1426, 1633, 2646, 758, 27, 89, -1, -1, -1, -1, + -1, 1869, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 2322, -1, -1, 252, 253, 254, 255, 256, 257, -1, - -1, 260, 261, 381, -1, -1, -1, 483, 2363, -1, - -1, -1, -1, -1, 490, 491, 492, 493, 494, 495, - -1, -1, -1, -1, -1, -1, 2381, -1, 2383, -1, - -1, -1, 2387, 2388, 2389, -1, 2391, -1, -1, -1, - 2515, -1, -1, -1, -1, -1, -1, -1, 641, 642, - -1, -1, -1, -1, -1, 2410, -1, 2412, -1, -1, - -1, -1, 381, -1, -1, -1, -1, -1, -1, -1, - 2425, 2426, 2427, 2428, 2429, 2430, 2431, 2432, 2433, 2434, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 2423, 2157, -1, -1, 2450, -1, -1, -1, -1, - -1, 2456, -1, -1, -1, 483, -1, 366, 367, 702, - 703, 2466, 490, 491, 492, 493, 494, 495, -1, -1, - -1, -1, -1, -1, -1, -1, 2481, 3098, -1, -1, + -1, -1, 2799, -1, -1, -1, -1, 603, 604, 605, + 1898, -1, -1, -1, -1, -1, -1, 1905, 2847, -1, + -1, 617, -1, 2945, 96, 621, 98, -1, 100, 2808, + 2827, -1, -1, 2830, 2831, -1, 632, 633, 634, -1, + -1, -1, 638, 639, -1, -1, -1, -1, -1, 1937, + 2847, -1, 1940, -1, -1, -1, -1, 1945, -1, -1, + -1, -1, -1, -1, -1, -1, 2863, 663, 664, 665, + 666, 1167, 668, -1, 1120, 1471, 1472, 2874, 2875, -1, + 1476, 2878, -1, -1, -1, 681, -1, -1, -1, -1, + -1, 687, -1, -1, -1, -1, -1, -1, -1, 814, + 2897, -1, 698, -1, 3, -1, 5, -1, -1, -1, + -1, -1, 2891, 2892, 710, -1, -1, 561, 2915, -1, + -1, -1, -1, -1, -1, -1, 2808, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 488, 489, 490, -1, + 492, 493, 494, 495, 496, 497, -1, 743, 2945, 2482, + -1, 747, 748, 749, 750, 2389, 2390, -1, -1, -1, + -1, -1, -1, -1, -1, 2847, -1, -1, -1, -1, + -1, -1, -1, -1, 2507, 2508, -1, 2956, 2957, -1, + -1, 2978, -1, -1, -1, 2982, 2982, -1, -1, -1, + -1, -1, -1, -1, -1, 2992, -1, 2994, -1, 2996, + -1, -1, -1, 3000, -1, -1, -1, 3004, -1, 2891, + 2892, -1, 111, 112, 2982, -1, -1, -1, 3015, -1, + -1, -1, -1, -1, 3021, 3021, -1, 2982, -1, -1, + 3027, -1, -1, -1, -1, 3032, -1, 1333, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 3169, -1, -1, + -1, -1, -1, 3021, -1, -1, -1, -1, -1, -1, + -1, 1657, -1, -1, -1, -1, 3021, -1, -1, -1, + -1, 1367, 1368, -1, 2956, 2957, -1, 3056, -1, -1, + -1, -1, 3079, -1, -1, -1, -1, 1383, 187, 188, + -1, 1006, 3089, 3072, 12, -1, -1, 3076, -1, 17, + -1, -1, -1, -1, -1, -1, -1, -1, 26, -1, + 2643, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 39, 40, -1, -1, 3122, -1, -1, -1, 2217, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 2573, + -1, -1, -1, -1, -1, -1, -1, 3144, 3144, -1, + -1, -1, -1, 252, 253, 254, 255, 256, 257, -1, + 3157, 260, 261, 959, 960, -1, -1, -1, 964, -1, + 814, 3168, 3169, 1419, 3056, 1421, 3144, 973, 974, 97, + -1, 977, 3161, -1, -1, -1, -1, 983, -1, 3144, + 3072, -1, 988, -1, 3076, 3192, 3192, -1, -1, 995, + -1, -1, -1, -1, -1, 3184, -1, -1, 3205, 3206, + -1, -1, -1, -1, 1010, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 3192, -1, -1, -1, -1, -1, + -1, -1, 3229, -1, -1, -1, -1, 3192, -1, -1, + -1, -1, 514, -1, 516, -1, -1, -1, 520, -1, + -1, 523, 1167, -1, -1, -1, -1, -1, 2692, -1, + -1, -1, -1, 1059, -1, -1, 3263, -1, 367, 368, + 1566, 2804, -1, -1, 1870, 1871, 1872, 1873, 1874, 3161, + -1, 1877, 1878, 1879, 1880, 1881, 1882, 1883, 1884, 1885, + 1886, -1, -1, -1, 2827, -1, -1, 2385, -1, -1, + -1, -1, 3184, -1, -1, -1, 1102, -1, 1104, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 2322, -1, 2500, -1, -1, 2623, -1, - -1, -1, -1, -1, -1, -1, -1, 2489, -1, -1, - 2515, -1, -1, -1, 483, -1, -1, 2522, 2523, 2524, - 2525, 490, 491, 492, 493, 494, 495, -1, -1, 2534, - 2512, -1, -1, -1, -1, -1, -1, -1, 8, -1, - -1, 11, 2547, -1, -1, 15, -1, -1, -1, -1, - 3098, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 2572, -1, 2574, - 479, 480, -1, 43, -1, -1, 2558, 2582, -1, -1, - 50, 2586, -1, -1, -1, -1, 2591, -1, -1, -1, - -1, -1, 2597, -1, 2423, -1, 2157, -1, 2603, -1, - -1, -1, -1, -1, 2609, 75, -1, 2322, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 2622, 2623, -1, - -1, -1, -1, -1, -1, 2630, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 2647, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 1120, 1121, -1, -1, -1, -1, + 1126, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 0, -1, -1, -1, -1, -1, -1, -1, -1, 621, + -1, -1, -1, -1, 2887, -1, -1, 1153, 1154, -1, + -1, -1, 1006, -1, -1, -1, -1, -1, -1, -1, + 1166, -1, -1, -1, -1, -1, -1, -1, 8, -1, + -1, 11, 481, 482, -1, 15, -1, 1183, 18, 19, + 20, 1187, -1, -1, 2482, 1191, 2830, -1, -1, -1, + -1, -1, -1, -1, 1700, -1, -1, -1, -1, 2005, + 2006, -1, 2945, 43, -1, -1, -1, -1, 1333, -1, + 50, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 95, -1, -1, 710, -1, + -1, -1, -1, -1, -1, 75, 1692, -1, -1, -1, + -1, -1, 1367, 1368, -1, -1, 1702, -1, 1704, -1, + -1, 1707, -1, 2551, -1, -1, -1, 1713, 1383, 1715, + -1, 743, -1, -1, -1, 747, 748, 749, 750, -1, + -1, 1727, -1, -1, -1, -1, 1732, 147, 2576, -1, + 1736, 1737, 1738, 1739, -1, 1741, 1742, -1, -1, -1, + -1, 161, -1, -1, -1, -1, 166, -1, -1, -1, + -1, 171, -1, -1, -1, -1, 3049, 1813, -1, -1, + 180, -1, -1, 1167, 184, -1, -1, -1, -1, 1325, + -1, -1, -1, 1329, 2622, -1, -1, -1, -1, 1335, + -1, -1, -1, -1, -1, -1, 176, -1, -1, -1, + 1346, 1347, 1348, -1, -1, 215, -1, 1853, -1, -1, + -1, -1, 192, -1, -1, -1, -1, 197, -1, -1, + -1, -1, -1, 1869, -1, 235, -1, -1, -1, -1, + -1, -1, -1, -1, 1380, -1, -1, -1, -1, 1385, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 2489, 8, -1, -1, 11, -1, -1, -1, 15, -1, - 2652, 18, 19, 20, -1, 918, -1, -1, -1, -1, - -1, -1, -1, 2512, -1, 928, -1, -1, 931, -1, - -1, 934, 935, 936, 937, -1, 43, -1, -1, -1, - -1, -1, -1, 50, -1, -1, 176, 2689, 2423, -1, + -1, -1, 1898, -1, 234, -1, 0, -1, -1, 1905, + -1, -1, 23, -1, 532, -1, -1, -1, -1, -1, + 1416, -1, 1418, 1419, 284, 1421, 1422, 287, -1, -1, + -1, -1, 2720, 293, -1, -1, 3169, -1, -1, -1, + -1, 1937, -1, -1, 1940, -1, 564, 565, -1, 1945, + -1, 1566, -1, -1, -1, -1, -1, -1, -1, 289, + -1, -1, -1, -1, -1, 76, 8, -1, 328, 11, + 2758, -1, -1, 15, -1, -1, 18, 19, 20, -1, + -1, 92, 1478, -1, -1, -1, -1, -1, -1, 1333, + -1, 351, 964, 35, -1, 1491, -1, 1493, -1, 110, + 1496, 95, 1498, 1499, -1, 1501, -1, 1503, -1, -1, + -1, -1, 1508, -1, 1510, -1, 1512, -1, 1514, -1, + -1, 1517, -1, 1367, 1368, -1, -1, -1, -1, 8, + -1, -1, 11, -1, -1, 146, 15, -1, -1, 1383, + -1, 1537, -1, 2831, -1, 156, 1542, 407, -1, -1, + -1, -1, 382, 147, -1, -1, -1, 168, -1, -1, + -1, -1, 173, -1, 43, -1, -1, 161, -1, 687, + -1, 50, 166, -1, 434, -1, -1, 171, -1, -1, + -1, 1577, -1, 443, -1, 1700, 180, -1, -1, 200, + 184, -1, -1, 2389, 2390, -1, 75, -1, -1, -1, + 460, -1, 462, 463, -1, -1, -1, -1, -1, -1, + -1, -1, 1608, -1, -1, -1, -1, -1, -1, -1, + 2066, 215, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 1629, 245, 1631, -1, 1633, 249, 499, + -1, 235, 502, 503, 504, -1, -1, 1643, 1644, -1, + -1, -1, -1, -1, -1, 485, -1, 2945, 488, 489, + 490, -1, 492, 493, 494, 495, 496, 497, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 219, -1, -1, + -1, 1153, -1, -1, -1, -1, 1682, -1, -1, -1, + 284, -1, -1, 287, 1166, 1691, 1692, 176, 1813, 293, + -1, 312, -1, -1, -1, -1, 1702, 1703, 1704, 1705, + -1, 1707, -1, 192, -1, 1187, 327, 1713, 197, 1715, + -1, 2217, 1566, -1, -1, -1, -1, -1, -1, -1, + 1726, 1727, -1, -1, 328, 1731, 1732, -1, 1853, -1, + 1736, 1737, 1738, 1739, -1, 1741, 1742, 289, -1, 360, + -1, -1, 363, -1, 1869, 234, -1, 351, -1, -1, + 371, -1, -1, 374, -1, -1, 1762, -1, -1, -1, + 1766, 1767, 1768, 1769, -1, 2221, -1, 2573, -1, -1, + -1, -1, 393, 1898, -1, -1, -1, 1783, -1, -1, + 1905, -1, -1, -1, -1, -1, 407, -1, -1, -1, + -1, -1, -1, 414, -1, -1, -1, -1, -1, -1, + 289, -1, 423, 407, -1, -1, 2612, -1, 429, -1, + -1, -1, 1937, 25, -1, 1940, -1, -1, -1, 31, + 1945, -1, -1, -1, -1, -1, 38, -1, -1, -1, + 434, -1, -1, -1, 455, -1, -1, -1, -1, 443, + -1, -1, -1, -1, -1, 57, 1700, 1329, -1, 977, + -1, -1, -1, 1335, -1, -1, 460, -1, 462, 463, + -1, -1, -1, -1, -1, -1, -1, 995, -1, -1, + -1, 3169, -1, -1, -1, -1, -1, -1, -1, 2385, + -1, -1, -1, -1, -1, 8, 2692, -1, 11, -1, + -1, -1, 15, 382, -1, 499, 108, -1, 502, 503, + 504, 1907, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 8, 1919, -1, 11, -1, -1, -1, 15, + 43, -1, 18, 19, 20, 137, 1932, 50, -1, -1, + -1, 1059, 1938, -1, -1, -1, 488, 489, 490, 35, + 492, 493, 494, 495, 496, 497, -1, -1, -1, -1, + -1, -1, 75, -1, -1, -1, -1, -1, -1, 1813, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 2725, -1, 192, -1, -1, -1, 969, 197, 75, 2558, - -1, 2856, 2737, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 986, -1, 2750, -1, -1, -1, -1, - -1, 2876, 2877, -1, -1, -1, -1, -1, -1, -1, - 1003, 2322, -1, -1, 234, -1, -1, -1, -1, -1, - 2895, 1014, 1015, 1016, 2489, 1018, 1019, -1, 2760, -1, - -1, 2786, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 2512, -1, -1, - 1043, -1, -1, -1, -1, -1, -1, 2812, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 289, - 2825, 2946, -1, 2652, -1, -1, -1, -1, -1, 176, + -1, 1977, -1, -1, -1, 1981, 2482, -1, -1, 1985, + -1, -1, -1, -1, -1, -1, 2442, 199, -1, -1, + -1, -1, 1120, 1121, -1, -1, 485, -1, -1, 1853, + -1, -1, -1, 492, 493, 494, 495, 496, 497, -1, + -1, -1, -1, 2469, -1, 1869, 2022, -1, -1, 1501, + -1, -1, 145, -1, 2830, -1, -1, -1, 2484, 2485, + 2486, 2487, 2488, 2489, 2490, 2491, 2492, 2493, 250, -1, + -1, -1, -1, -1, 1898, 2551, 258, 2053, -1, -1, + -1, 1905, -1, 176, -1, -1, -1, -1, 270, -1, + 2066, -1, -1, 2069, -1, -1, -1, 2073, -1, 192, + 2576, -1, -1, 8, 197, -1, 11, -1, -1, 291, + 15, -1, -1, 1937, -1, -1, 1940, 111, 112, 301, + -1, 1945, 2217, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 111, 112, -1, -1, 43, -1, + -1, 234, -1, -1, -1, 50, 2622, -1, -1, -1, + -1, 2127, -1, 219, -1, -1, -1, -1, -1, -1, + -1, 343, -1, -1, -1, 347, -1, 349, -1, -1, + 75, -1, -1, -1, -1, -1, -1, -1, -1, 1631, + -1, 1633, -1, -1, -1, -1, -1, 945, -1, 371, + -1, 1643, -1, 187, 188, 377, 289, -1, 956, 957, + -1, -1, -1, 961, 962, -1, -1, -1, -1, 391, + 187, 188, -1, -1, 2190, -1, -1, -1, -1, -1, + -1, 2197, -1, 289, -1, -1, -1, -1, -1, -1, + 1682, 2207, 2208, 2209, 2210, -1, -1, -1, -1, -1, + 145, -1, -1, -1, 2720, 2221, 1004, 2223, -1, -1, + 2226, -1, -1, -1, -1, 2231, -1, -1, 252, 253, + 254, 255, 256, 257, 446, 2691, 260, 261, 2244, -1, + -1, 176, -1, -1, -1, 252, 253, 254, 255, 256, + 257, -1, 2758, 260, 261, 2261, -1, 192, -1, 382, + 2385, -1, 197, -1, -1, -1, -1, -1, -1, 2275, + 2276, -1, 2278, -1, -1, -1, -1, -1, -1, -1, + 1762, -1, -1, 1071, 1766, 1767, 1768, 1769, -1, -1, + 1418, 1419, -1, 1421, -1, -1, -1, -1, -1, 234, + -1, 2307, -1, -1, -1, -1, -1, -1, -1, -1, + 1098, -1, 1100, 1101, -1, -1, -1, -1, -1, -1, + 2326, -1, -1, -1, -1, 2831, -1, -1, -1, 2335, + 2336, 2337, -1, -1, -1, -1, 2342, -1, -1, -1, + 2346, -1, -1, 367, 368, -1, -1, -1, 663, 664, + -1, -1, -1, -1, 289, 2361, -1, 2482, -1, -1, + 367, 368, 485, 2217, -1, -1, -1, -1, 1496, 492, + 493, 494, 495, 496, 497, -1, -1, -1, -1, -1, + 1168, -1, -1, 1171, 1172, -1, 1514, -1, -1, 1517, + -1, -1, 488, 489, 490, -1, 492, 493, 494, 495, + 496, 497, -1, -1, -1, -1, -1, -1, -1, -1, + 2416, 726, 727, 2419, -1, -1, 2422, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 2551, -1, -1, -1, + -1, -1, -1, -1, 2440, -1, 2442, 1919, -1, 2945, + 2446, 2447, 2448, -1, 2450, -1, -1, 382, -1, -1, + -1, 2576, -1, -1, -1, -1, -1, 481, 482, -1, + -1, -1, -1, 2469, -1, 2471, -1, -1, -1, -1, + 2926, -1, -1, -1, 481, 482, -1, 501, 2484, 2485, + 2486, 2487, 2488, 2489, 2490, 2491, 2492, 2493, -1, -1, + 2946, 2947, -1, -1, -1, -1, -1, 2622, -1, -1, + -1, -1, -1, -1, -1, 2511, -1, -1, -1, 2965, + -1, 2517, 8, -1, -1, 11, -1, -1, -1, 15, + -1, 2527, 18, 19, 20, -1, -1, -1, -1, -1, + -1, 2385, -1, -1, -1, -1, 8, 2543, -1, 11, + -1, -1, -1, 15, -1, -1, 18, 19, 20, -1, + 485, -1, -1, -1, -1, -1, 2562, 492, 493, 494, + 495, 496, 497, 35, 1692, -1, -1, -1, -1, -1, + -1, 43, -1, 2579, 1702, -1, 1704, 1365, 50, 1707, + 2586, 2587, 2588, 2589, -1, 1713, 8, 1715, 1376, 11, + 1378, -1, 2598, 15, -1, 2720, 18, 19, 20, 1727, + 1388, -1, -1, 75, 1732, 2611, -1, -1, 1736, 1737, + 1738, 1739, -1, 1741, 1742, -1, -1, 1405, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 2482, -1, + 2636, -1, 2638, 2758, -1, -1, -1, -1, 953, -1, + 2646, -1, -1, 1431, 1432, -1, -1, 3103, 963, -1, + -1, 966, -1, 2659, 969, 970, 971, 972, -1, 2665, + -1, -1, -1, 3169, -1, 2671, -1, -1, -1, -1, + -1, 2677, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 2690, 2691, -1, -1, -1, -1, + 1005, -1, 2698, -1, -1, -1, -1, 2551, -1, 38, + -1, -1, -1, -1, 176, -1, 2831, 1022, -1, 2715, + 8, -1, -1, 11, -1, 2197, -1, 15, 57, -1, + 192, -1, 2576, 219, 1039, 197, 2208, 2209, 2210, -1, + -1, -1, -1, -1, -1, 1050, 1051, 1052, -1, 1054, + 1055, 2223, -1, -1, 2226, 43, -1, 219, 220, 2231, + -1, -1, 50, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 234, -1, -1, -1, 1081, -1, 2622, 108, + 109, -1, -1, -1, -1, -1, -1, 75, 117, 1907, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 2795, + -1, -1, -1, 289, -1, -1, -1, 219, -1, -1, + 272, 2807, -1, 275, -1, -1, -1, -1, -1, -1, + 1938, -1, -1, -1, -1, 2821, -1, 289, -1, 1134, + 2945, -1, -1, 1138, 1139, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 175, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 145, -1, 1977, + -1, 2857, -1, 2335, 2336, 2337, -1, 1985, -1, -1, + 199, -1, -1, -1, -1, -1, 2720, 289, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 2883, 176, 1194, + 1668, 1669, -1, -1, -1, -1, -1, 2893, -1, -1, + -1, 1206, -1, 8, 192, -1, 11, -1, -1, 197, + 15, -1, -1, -1, 2758, -1, -1, -1, -1, -1, + 382, 250, -1, -1, -1, -1, 1231, -1, -1, 258, + 2926, -1, -1, -1, -1, -1, -1, -1, 43, -1, + -1, 270, 1720, 272, -1, 50, 234, -1, 2066, -1, + 2946, 2947, 1730, -1, -1, 1733, -1, -1, -1, -1, + -1, -1, -1, 2959, -1, 2961, -1, -1, 2440, 2965, + 75, -1, 301, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 2979, -1, -1, 2982, 2831, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 2558, -1, 192, -1, -1, -1, -1, - 197, 2856, 1095, -1, -1, -1, 1099, 1100, -1, -1, - 2689, -1, 2423, -1, -1, -1, -1, -1, -1, -1, - -1, 2876, 2877, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 2889, -1, 2891, 234, -1, -1, - 2895, -1, -1, 2875, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 2908, -1, -1, 2911, -1, -1, -1, - 1153, 381, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 1165, -1, -1, -1, -1, -1, 2489, -1, - -1, 2760, -1, -1, -1, -1, -1, 2652, -1, 2944, - -1, 2946, 289, -1, -1, -1, 1189, -1, -1, 912, - 2955, 2512, -1, -1, -1, -1, -1, -1, 921, 922, - -1, -1, -1, 926, 927, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 2689, -1, 932, -1, -1, -1, - 2985, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 2558, -1, -1, - -1, -1, -1, -1, -1, 968, -1, -1, -1, -1, - -1, -1, 3017, 483, -1, -1, -1, -1, -1, -1, - 490, 491, 492, 493, 494, 495, 3031, 3032, 3033, 3034, - -1, -1, -1, -1, 381, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 2760, 2875, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 3062, -1, -1, + -1, 289, 488, 489, 490, -1, 492, 493, 494, 495, + 496, 497, -1, -1, -1, -1, -1, -1, -1, 3015, + 349, -1, -1, 485, -1, 3021, 488, 489, 490, 3025, + 492, 493, 494, 495, 496, 497, -1, -1, 1816, 1817, + 145, -1, 371, -1, -1, 2517, -1, -1, -1, -1, + -1, -1, -1, -1, 3169, -1, -1, -1, -1, 3055, + 1838, -1, 391, -1, 393, -1, -1, 396, -1, -1, + -1, 176, -1, -1, -1, -1, 488, 489, 490, -1, + 492, 493, 494, 495, 496, 497, -1, 192, -1, -1, + -1, -1, 197, -1, 382, -1, 3092, -1, -1, -1, + -1, 2945, -1, 2221, -1, -1, -1, 3103, -1, -1, + -1, -1, -1, -1, 2586, 2587, 2588, 2589, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 234, + -1, -1, -1, -1, -1, 3131, -1, -1, -1, -1, + -1, -1, -1, 1448, -1, -1, -1, -1, 3144, 3145, + 3146, 3147, -1, -1, -1, -1, -1, -1, -1, 3155, + -1, -1, 0, 1941, -1, -1, -1, -1, -1, -1, + -1, -1, 501, -1, -1, -1, -1, -1, 1483, -1, + 1485, 1486, -1, -1, 289, -1, -1, -1, -1, 3185, + -1, -1, -1, 1498, 1499, -1, 3192, 485, -1, -1, + -1, -1, -1, -1, 492, 493, 494, 495, 496, 497, + -1, -1, -1, -1, 3210, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 2342, -1, 2698, -1, 2346, 3225, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 1034, -1, -1, -1, 3080, -1, -1, -1, 1035, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 3094, - -1, 2652, -1, -1, -1, -1, -1, 1060, -1, 1062, - 1063, -1, -1, -1, -1, -1, -1, -1, -1, 3114, - -1, -1, -1, -1, -1, 3120, 3098, -1, -1, -1, - -1, 1077, -1, 8, -1, 3130, 11, -1, 2689, -1, - 15, 16, 17, 18, 19, 20, 483, -1, -1, 486, - 487, 488, -1, 490, 491, 492, 493, 494, 495, -1, - 35, -1, -1, -1, 1397, -1, -1, -1, 43, -1, - 2875, -1, -1, -1, -1, 50, 1129, -1, -1, 1132, - 1133, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 1432, - 75, 1434, 1435, -1, -1, -1, -1, -1, -1, 2760, - -1, -1, -1, -1, 1447, 1448, -1, -1, -1, -1, - -1, -1, 8, -1, -1, 11, -1, -1, -1, 15, - -1, -1, 18, 19, 20, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 1193, -1, 35, - -1, -1, -1, -1, 1200, -1, -1, 43, -1, -1, - -1, -1, -1, -1, 50, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 1509, -1, -1, 3098, - -1, -1, 1515, 1516, 1517, 1518, 1519, 1520, 1521, 75, - -1, -1, -1, 1526, 1527, -1, -1, -1, 1531, -1, - -1, 176, 1535, -1, -1, 1538, 1539, 1540, 1541, 1542, - 1543, 1544, 1545, 1546, -1, -1, 1549, 192, -1, -1, - -1, -1, 197, 1556, 2875, 1558, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 219, 220, -1, -1, -1, 1582, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 234, - -1, -1, 1315, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 1326, -1, 1328, -1, -1, -1, -1, - -1, -1, 1615, 1616, -1, 1338, -1, -1, -1, -1, - 176, -1, -1, 3098, -1, -1, -1, 272, -1, -1, - 275, -1, 1355, -1, -1, -1, 192, -1, -1, -1, - -1, 197, -1, -1, 289, -1, -1, 292, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 1381, 1382, - -1, -1, -1, 219, 220, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 234, 1395, + -1, -1, -1, -1, -1, -1, 1561, 95, -1, -1, + -1, -1, 1567, 1568, 1569, 1570, 1571, 1572, 1573, -1, + -1, -1, -1, 1578, 1579, -1, -1, 382, 1583, -1, + 2058, -1, 1587, -1, -1, 1590, 1591, 1592, 1593, 1594, + 1595, 1596, 1597, 1598, -1, -1, 1601, -1, -1, -1, + -1, -1, -1, 1608, -1, 1610, -1, -1, -1, 147, + -1, -1, 2090, 2091, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 161, 2442, 3169, -1, -1, 166, 1634, + -1, 967, -1, 171, -1, -1, -1, -1, -1, -1, + -1, -1, 180, -1, -1, -1, 184, -1, -1, -1, + -1, 2469, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 1668, 1669, -1, 2484, 2485, 2486, 2487, + 2488, 2489, 2490, 2491, 2492, 2493, -1, 215, -1, -1, + 485, 0, -1, -1, -1, -1, -1, 492, 493, 494, + 495, 496, 497, -1, -1, -1, -1, 235, -1, -1, + -1, -1, 21, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 31, -1, 33, 34, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 44, -1, -1, -1, -1, + 49, -1, -1, -1, -1, -1, 1072, -1, -1, 58, + -1, -1, -1, -1, 1749, -1, 284, 1752, 1753, 287, + 1755, 70, -1, -1, -1, 293, -1, -1, -1, -1, + 2238, 2579, 81, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 93, -1, 95, -1, -1, 1115, + -1, -1, -1, -1, 1789, -1, -1, 2959, -1, -1, + 328, -1, -1, -1, 113, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 2979, 127, 128, + -1, -1, -1, 351, -1, -1, -1, -1, 137, -1, + -1, -1, -1, -1, 143, -1, -1, -1, -1, -1, + -1, -1, 151, -1, 153, 154, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 167, -1, + -1, -1, 171, 3025, 1859, -1, -1, 1862, -1, 1864, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 407, + -1, -1, -1, 2691, -1, -1, -1, 196, -1, -1, + -1, -1, -1, 3055, -1, -1, -1, 1892, 1893, -1, + -1, 1896, 211, -1, -1, -1, 434, -1, -1, 1235, + -1, -1, -1, -1, -1, 443, 1242, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 237, -1, + 1925, -1, 460, 1928, 462, 463, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 1943, -1, + -1, -1, -1, -1, 25, -1, -1, -1, 1953, -1, + 31, -1, -1, -1, -1, -1, -1, 38, -1, -1, + -1, 499, -1, -1, 502, 503, 504, -1, -1, -1, + -1, -1, -1, -1, 1979, -1, 57, -1, -1, 1984, + -1, -1, 1987, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 315, -1, -1, 318, + -1, -1, -1, 8, 2482, -1, 11, -1, -1, -1, + 15, 16, 17, 18, 19, 20, -1, -1, -1, 2024, + -1, -1, 2027, -1, 2029, -1, -1, 108, 347, -1, + 35, -1, -1, -1, -1, -1, -1, 356, 43, -1, + -1, -1, -1, -1, -1, 50, -1, -1, -1, -1, + -1, 370, -1, -1, -1, -1, 137, -1, 377, -1, + -1, -1, 381, -1, -1, -1, -1, -1, -1, -1, + 75, -1, 391, -1, -1, -1, -1, -1, 2083, -1, + -1, -1, -1, -1, 403, -1, -1, -1, 407, -1, + -1, -1, -1, -1, -1, 2100, 2101, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 426, 2926, -1, + 1446, -1, -1, -1, 2119, -1, -1, -1, 199, -1, + -1, -1, 441, -1, -1, 444, -1, -1, 2946, 2947, + 449, 1467, -1, 1469, -1, 1471, 1472, 1473, -1, -1, + 1476, -1, -1, 1479, 463, -1, 1482, 2965, -1, -1, + -1, 1487, -1, -1, 1490, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 487, 250, + -1, 176, -1, 2178, -1, -1, -1, 258, -1, -1, + -1, -1, 501, -1, -1, 504, -1, 192, -1, 270, + -1, -1, 197, -1, -1, -1, 1532, -1, -1, -1, + 1536, -1, -1, 1539, 1540, 1541, -1, -1, -1, 1545, + 291, -1, -1, 1549, 219, 220, -1, -1, -1, -1, + 301, -1, -1, -1, 2229, -1, -1, -1, -1, 234, + -1, 2709, -1, -1, 8, -1, 2714, 11, -1, -1, + -1, 15, 16, 17, 18, 19, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 1694, -1, -1, 1697, 1698, -1, 1700, -1, -1, - 1416, -1, 1418, -1, 1420, 1421, 1422, -1, -1, 1425, - -1, -1, 1428, -1, -1, 1431, 272, -1, -1, 275, - 1436, -1, -1, 1439, -1, -1, -1, -1, -1, 1732, - -1, -1, -1, 289, -1, -1, 381, -1, -1, -1, + -1, 35, 343, -1, 38, -1, 347, 272, 349, 43, + 275, 1607, -1, -1, -1, -1, 50, -1, -1, -1, + -1, -1, -1, -1, 289, 3103, -1, 292, 2766, 2767, + 371, -1, 3, -1, -1, -1, 377, 8, -1, -1, + 11, 75, -1, -1, 15, 16, 17, 18, 19, 20, + 391, -1, -1, -1, -1, 1651, -1, -1, -1, -1, + -1, -1, -1, -1, 35, -1, -1, 38, -1, -1, + -1, 1667, 43, -1, -1, -1, 1672, -1, -1, 50, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 2355, -1, -1, -1, -1, -1, -1, -1, -1, 2364, + -1, -1, -1, -1, 75, 446, -1, -1, 2373, -1, + -1, 2376, -1, 2378, -1, -1, -1, 382, -1, -1, + -1, 2386, -1, -1, -1, -1, -1, -1, -1, 2394, + 2395, -1, -1, 2398, -1, -1, -1, -1, -1, -1, + -1, -1, 176, -1, -1, -1, -1, 2412, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 192, 2424, + -1, -1, -1, 197, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 1481, -1, -1, -1, 1485, - -1, -1, 1488, 1489, 1490, -1, -1, 3098, 1494, -1, - -1, -1, 1498, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 1797, -1, -1, 1800, -1, 1802, + -1, -1, -1, -1, -1, 219, 220, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 2934, 2935, -1, -1, + 234, -1, -1, -1, -1, 176, -1, 2945, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 485, 192, -1, 488, 489, 490, 197, 492, 493, 494, + 495, 496, 497, -1, -1, -1, -1, -1, 272, -1, + 505, 275, -1, -1, -1, -1, -1, -1, 219, 220, + -1, -1, -1, -1, -1, 289, -1, -1, 292, 1855, + -1, -1, -1, 234, -1, -1, -1, -1, -1, -1, + -1, 1867, 1868, -1, 1870, 1871, 1872, 1873, 1874, -1, + -1, 1877, 1878, 1879, 1880, 1881, 1882, 1883, 1884, 1885, + 1886, 1887, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 272, -1, -1, 275, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 289, -1, + -1, 292, -1, -1, -1, -1, -1, -1, 2593, 2594, + -1, -1, -1, -1, -1, -1, 2601, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 2612, 382, -1, + -1, 2616, 2617, -1, -1, -1, 2621, -1, -1, -1, + -1, 2626, -1, -1, 2629, 2630, -1, -1, -1, 2634, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 381, -1, 1830, 1831, -1, - -1, 1834, -1, -1, -1, -1, -1, -1, 483, 1555, - -1, 486, 487, 488, -1, 490, 491, 492, 493, 494, - 495, -1, -1, -1, -1, -1, -1, -1, 503, -1, - 1863, -1, -1, 1866, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 1880, -1, -1, - -1, -1, 1598, -1, -1, -1, -1, -1, 1891, -1, - -1, -1, 1615, 1616, -1, -1, -1, -1, 1614, -1, - -1, -1, -1, 1619, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 1917, -1, -1, -1, -1, 1922, - -1, -1, 1925, -1, -1, -1, -1, 483, -1, -1, - 486, 487, 488, -1, 490, 491, 492, 493, 494, 495, - -1, -1, -1, -1, 1667, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 1677, -1, -1, 1680, -1, 1962, - -1, -1, 1965, -1, 1967, -1, -1, -1, -1, -1, + -1, 2646, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 1989, -1, -1, -1, 1993, 1994, 1995, + 1996, 1997, 1998, 1999, -1, -1, -1, -1, -1, 2005, + 2006, 382, 2008, 2009, -1, -1, -1, -1, -1, 2684, + -1, -1, -1, -1, 2020, -1, -1, 2023, -1, -1, + -1, 3169, -1, -1, -1, 2031, 2032, 2033, 2034, 2035, + 2036, 2037, 2038, 2039, 2040, -1, 2711, -1, -1, -1, + -1, 485, -1, -1, 488, 489, 490, -1, 492, 493, + 494, 495, 496, 497, -1, -1, -1, -1, 502, 2065, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 485, -1, -1, 488, 489, 490, + -1, 492, 493, 494, 495, 496, 497, -1, -1, -1, + -1, -1, -1, -1, 2799, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 2024, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 1755, 1756, -1, -1, -1, -1, 2041, 2042, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 1778, -1, 2060, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 1793, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 1805, - 1806, -1, 1808, 1809, 1810, 1811, 1812, -1, -1, 1815, - 1816, 1817, 1818, 1819, 1820, 1821, 1822, 1823, 1824, 1825, - -1, -1, -1, -1, -1, -1, 2119, -1, -1, -1, + -1, -1, -1, 8, -1, -1, 11, -1, -1, -1, + 15, -1, 2847, 18, 19, 20, -1, 2183, 2184, 2185, + -1, -1, 8, -1, -1, 11, -1, -1, 2863, 15, + 16, 17, 18, 19, 20, -1, -1, -1, 43, 2874, + 2875, -1, -1, 2878, -1, 50, -1, -1, -1, 35, + -1, -1, -1, -1, -1, -1, -1, 43, -1, -1, + -1, -1, 2897, -1, 50, -1, -1, -1, -1, -1, + 75, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 2915, -1, -1, -1, -1, 8, -1, -1, 11, 75, + -1, -1, 15, 16, 17, 18, 19, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 35, -1, -1, -1, -1, 2283, 2284, 2285, + 43, -1, 2288, 2289, 2290, 2291, 2292, 50, -1, -1, + 2296, 2297, 2298, 2299, 2300, 2301, 2302, 2303, 2304, 2305, + -1, -1, -1, 2978, 2310, 2311, -1, -1, -1, -1, + -1, -1, 75, -1, -1, -1, -1, -1, -1, -1, + -1, 2996, -1, -1, -1, 3000, -1, -1, -1, 3004, + -1, 176, 2338, -1, -1, 2341, -1, -1, -1, -1, + 3015, -1, -1, -1, -1, -1, -1, 192, 2354, -1, + 176, -1, 197, -1, -1, -1, -1, 3032, -1, 2365, + -1, -1, 2368, -1, 2370, -1, 192, -1, 2374, 2375, + -1, 197, -1, -1, 219, 220, -1, -1, -1, -1, + -1, -1, 2388, 2389, 2390, 2391, -1, 2393, -1, 234, + -1, -1, -1, 219, 220, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 3079, -1, -1, -1, 234, -1, + -1, -1, -1, 176, 3089, -1, 8, -1, -1, 11, + -1, -1, -1, 15, 16, 17, 18, 19, 20, 192, + 275, -1, -1, -1, 197, -1, -1, 2443, -1, -1, + -1, -1, -1, 35, 289, -1, 272, 3122, -1, 275, + -1, 43, -1, -1, -1, -1, 219, 220, 50, -1, + -1, -1, -1, 289, -1, -1, 292, -1, -1, -1, + -1, 234, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 75, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 272, + -1, -1, 275, -1, -1, -1, -1, -1, -1, -1, + 8, -1, -1, 11, -1, -1, 289, 15, -1, 292, + 3205, 3206, -1, -1, -1, 8, 2542, 382, 11, -1, + -1, -1, 15, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 3229, 43, 382, -1, -1, -1, + -1, -1, 50, -1, -1, -1, -1, 2573, -1, -1, + 43, -1, -1, -1, -1, -1, -1, 50, -1, -1, + -1, -1, -1, -1, 176, -1, -1, 75, 3263, -1, + -1, -1, -1, -1, -1, -1, 2602, -1, -1, -1, + 192, 2607, 75, -1, -1, 197, -1, -1, -1, 2615, + -1, -1, 2618, -1, 2620, -1, -1, -1, 2624, 382, + -1, 2627, 2628, -1, -1, 2631, 2632, 219, 220, 2635, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 2645, + 485, -1, 234, 488, 489, 490, -1, 492, 493, 494, + 495, 496, 497, -1, -1, -1, 2662, 145, -1, 485, + -1, -1, 488, 489, 490, -1, 492, 493, 494, 495, + 496, 497, 145, -1, -1, -1, 502, -1, -1, -1, + 272, -1, -1, 275, -1, -1, 2692, -1, 176, -1, + -1, -1, -1, -1, -1, -1, -1, 289, -1, -1, + 292, -1, -1, 176, 192, -1, -1, -1, -1, 197, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 192, + -1, -1, 485, -1, 197, 488, 489, 490, -1, 492, + 493, 494, 495, 496, 497, -1, -1, -1, -1, 502, + -1, -1, -1, -1, -1, -1, 234, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 3, 1878, -1, -1, -1, 8, - -1, -1, 11, -1, -1, 2168, 15, 16, 17, 18, - 19, 20, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 35, -1, -1, 38, - -1, -1, -1, -1, 43, -1, -1, -1, -1, -1, - -1, 50, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 1927, -1, -1, -1, 1931, 1932, 1933, 1934, 1935, - 1936, 1937, -1, -1, -1, -1, 75, 1943, 1944, -1, - 1946, 1947, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 1958, -1, -1, 1961, -1, -1, -1, -1, - -1, -1, -1, 1969, 1970, 1971, 1972, 1973, 1974, 1975, - 1976, 1977, 1978, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 1995, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 2002, -1, 2291, -1, - -1, -1, -1, -1, -1, -1, -1, 2300, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 2310, 2031, 2032, - 2313, -1, 2315, -1, -1, -1, -1, -1, 0, -1, - 2323, -1, -1, -1, -1, -1, -1, 176, 2331, 2332, - -1, -1, 2335, -1, -1, -1, -1, -1, -1, 21, - -1, -1, -1, 192, -1, -1, 2349, -1, 197, 31, - -1, 33, 34, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 2365, -1, -1, -1, -1, 49, -1, -1, - 219, 220, -1, -1, -1, -1, 58, -1, -1, -1, - -1, -1, -1, -1, -1, 234, -1, -1, 70, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 81, - -1, -1, -1, -1, -1, -1, -1, -1, 2124, 2125, - 2126, 93, -1, 95, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 272, -1, -1, 275, -1, -1, -1, - -1, 113, -1, -1, -1, -1, -1, -1, -1, -1, - 289, -1, -1, 292, -1, 127, -1, -1, -1, -1, - -1, -1, -1, 2176, -1, 137, -1, -1, -1, -1, - -1, 143, -1, -1, -1, -1, -1, -1, -1, 151, - -1, 153, 154, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 167, -1, -1, -1, 171, + -1, 234, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 2219, 2220, 2221, -1, -1, 2224, 2225, - 2226, 2227, 2228, -1, 196, -1, 2232, 2233, 2234, 2235, - 2236, 2237, 2238, 2239, 2240, 2241, 2529, 2530, -1, 211, - 2246, 2247, 381, -1, 2537, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 2548, -1, -1, -1, 2552, - 2553, -1, -1, -1, 2557, 237, -1, -1, 2274, 2562, - -1, 2277, 2565, 2566, -1, -1, -1, 2570, -1, -1, - -1, -1, -1, -1, 2290, -1, -1, -1, -1, 2582, - -1, -1, -1, -1, -1, 2301, -1, -1, -1, 2305, - -1, 2307, -1, -1, -1, 2311, 2312, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 2325, - 2326, 2327, 2328, 2616, 2330, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 314, -1, 483, 317, -1, 486, 487, 488, - 2643, 490, 491, 492, 493, 494, 495, -1, -1, -1, + 382, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 289, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 289, -1, -1, -1, + -1, -1, -1, 2829, 2830, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 346, -1, -1, -1, 2384, -1, - -1, -1, -1, 355, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 369, -1, -1, - -1, -1, -1, -1, 376, -1, -1, -1, 380, -1, - 2423, -1, 8, -1, -1, 11, -1, -1, 390, 15, - 16, 17, 18, 19, 20, -1, -1, -1, -1, -1, - 402, -1, -1, -1, 406, -1, 2729, -1, 8, 35, - -1, 11, 38, -1, -1, 15, -1, 43, 18, 19, - 20, -1, -1, 425, 50, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 35, -1, -1, -1, -1, - 442, -1, -1, 43, 2480, 447, -1, -1, -1, 75, - 50, -1, -1, 2776, -1, -1, -1, -1, -1, 461, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 2792, - -1, -1, -1, 2509, -1, 75, -1, -1, -1, -1, - 2803, 2804, -1, 485, 2807, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 499, -1, -1, - 502, -1, 2538, -1, 2827, -1, -1, 2543, -1, -1, - -1, -1, -1, -1, -1, 2551, -1, -1, 2554, -1, - 2556, -1, 2845, -1, 2560, -1, -1, 2563, 2564, -1, - -1, 2567, 2568, -1, -1, 2571, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 2581, -1, -1, -1, -1, - 176, -1, -1, -1, -1, -1, -1, -1, 2594, -1, - -1, -1, -1, -1, -1, -1, 192, -1, -1, -1, - -1, 197, -1, -1, -1, -1, 176, -1, -1, -1, - -1, -1, -1, -1, 2907, -1, -1, -1, 2624, -1, - -1, -1, 192, 219, 220, -1, -1, 197, 2641, -1, - -1, -1, 2925, 2646, -1, -1, 2929, -1, 234, -1, - 2933, -1, -1, -1, -1, -1, -1, -1, -1, 219, - 220, 2944, -1, -1, 2947, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 234, -1, -1, -1, -1, 2962, - -1, -1, -1, -1, -1, -1, 272, -1, -1, 275, - -1, -1, -1, -1, 2697, 2698, -1, -1, -1, -1, - -1, -1, -1, 289, -1, -1, 292, -1, -1, -1, - -1, -1, 272, -1, -1, 275, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 289, - -1, 3014, 292, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 2855, + 2856, -1, -1, -1, -1, 2861, -1, -1, -1, -1, + 2866, -1, 2868, 2869, 2870, -1, -1, 2873, -1, -1, + 2876, 2877, -1, -1, -1, 2881, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 485, 382, -1, 488, 489, 490, -1, + 492, 493, 494, 495, 496, 497, 2912, -1, -1, 382, + 502, -1, 2918, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 2931, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 2758, 2759, -1, -1, -1, -1, -1, -1, - 3053, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 2784, 2785, - -1, -1, -1, -1, 2790, 381, -1, -1, -1, 2795, - -1, 2797, 2798, 2799, -1, -1, 2802, -1, -1, 2805, - 2806, -1, -1, -1, 2810, -1, -1, -1, -1, -1, - -1, 381, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 3127, 3128, 2842, -1, -1, -1, - -1, -1, 2848, -1, -1, -1, -1, -1, -1, -1, - -1, 2864, 2865, -1, -1, 2861, 3149, -1, -1, -1, - -1, -1, 2875, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 2958, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 2888, -1, -1, -1, -1, 483, -1, 3182, - 486, 487, 488, -1, 490, 491, 492, 493, 494, 495, - -1, -1, -1, -1, 500, -1, -1, 2913, -1, -1, - -1, -1, -1, 483, -1, -1, 486, 487, 488, -1, - 490, 491, 492, 493, 494, 495, -1, -1, -1, 2935, - 2936, 2937, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 2953, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 2963, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 2984, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 485, -1, -1, + 3006, 3007, 3008, -1, 492, 493, 494, 495, 496, 497, + -1, -1, 485, -1, -1, -1, -1, 3023, -1, 492, + 493, 494, 495, 496, 497, -1, -1, 3033, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 3006, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 3019, -1, -1, 3022, -1, -1, -1, - -1, -1, -1, 3029, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 3048, -1, -1, -1, -1, -1, -1, -1, + -1, 3077, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 3094, -1, + -1, 3097, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 3117, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 3, 4, 5, 6, 7, 8, 9, 10, - -1, -1, -1, -1, -1, 3098, -1, -1, -1, -1, - 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, - 31, 32, -1, -1, -1, 3111, 37, -1, -1, 40, - 41, -1, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, -1, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, -1, 70, - 71, 72, 73, 74, -1, 76, 3152, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, -1, 89, 90, - 91, 92, 93, 94, -1, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, 117, 118, -1, 120, - 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, - 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, - 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, - -1, 162, 163, 164, 165, -1, 167, -1, 169, 170, - 171, 172, 173, 174, 175, 176, 177, -1, 179, -1, - 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, - 191, 192, 193, 194, 195, 196, -1, 198, 199, 200, - 201, 202, 203, -1, 205, 206, 207, 208, 209, 210, - 211, 212, 213, 214, -1, 216, -1, 218, 219, 220, - 221, 222, 223, 224, 225, 226, 227, 228, -1, -1, - 231, 232, 233, 234, -1, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, - 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, - 311, 312, 313, 314, 315, 316, 317, 318, 319, -1, - 321, 322, 323, 324, 325, 326, -1, 328, 329, 330, - 331, 332, 333, 334, 335, -1, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, -1, 387, 388, 389, 390, - 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - 411, 412, 413, -1, 415, 416, -1, -1, 419, 420, - 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, - 431, 432, -1, -1, 435, 436, 437, 438, 439, 440, - -1, 442, 443, 444, 445, 446, 447, 448, -1, 450, - 451, 452, 453, 454, 455, 456, -1, -1, 459, -1, - 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 483, -1, 485, -1, -1, -1, -1, 490, - 491, -1, -1, -1, -1, -1, 497, -1, 499, 500, - -1, -1, -1, 504, 505, 506, 3, 4, 5, 6, - 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, - 37, -1, -1, 40, 41, -1, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, -1, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, -1, 70, 71, 72, 73, 74, -1, 76, - -1, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, -1, 89, 90, 91, 92, 93, 94, -1, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, -1, 120, 121, 122, 123, 124, 125, -1, - 127, 128, 129, 130, 131, 132, -1, 134, 135, 136, - 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, - -1, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, -1, 162, 163, 164, 165, -1, - 167, -1, 169, 170, -1, 172, 173, 174, 175, 176, - 177, -1, 179, -1, 181, 182, 183, -1, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - -1, 198, 199, 200, 201, 202, 203, -1, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, -1, 216, - -1, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, -1, -1, 231, 232, 233, 234, -1, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, -1, 285, 286, - -1, -1, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, - 307, 308, 309, -1, 311, 312, 313, 314, 315, 316, - 317, 318, 319, -1, 321, 322, 323, 324, 325, 326, - -1, 328, 329, 330, 331, 332, 333, 334, 335, -1, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, 356, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - 367, 368, -1, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, 381, 382, 383, 384, 385, -1, - 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, - 397, 398, 399, 400, 401, 402, -1, 404, 405, -1, - 407, 408, 409, 410, 411, 412, 413, -1, 415, 416, - -1, -1, 419, 420, 421, 422, 423, 424, 425, 426, - 427, 428, 429, 430, 431, 432, -1, -1, 435, 436, - 437, 438, 439, 440, -1, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - -1, -1, 459, -1, -1, 462, 463, 464, 465, 466, - 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 483, -1, -1, -1, - -1, -1, -1, 490, 491, 492, -1, -1, -1, -1, - 497, -1, 499, 500, -1, -1, -1, 504, 505, 506, - 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, - 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, - -1, -1, -1, -1, 37, -1, -1, 40, 41, -1, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, -1, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, -1, 70, 71, 72, - 73, 74, -1, 76, -1, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, - 93, 94, -1, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, -1, 120, 121, 122, - 123, 124, 125, -1, 127, 128, 129, 130, 131, -1, - -1, 134, 135, 136, 137, 138, -1, 140, 141, 142, - -1, 144, 145, 146, -1, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, 158, 159, 160, -1, 162, - 163, 164, 165, -1, 167, -1, 169, 170, 171, 172, - 173, 174, 175, 176, 177, -1, 179, -1, 181, 182, - 183, -1, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, -1, 198, 199, 200, 201, 202, - 203, -1, 205, 206, 207, 208, 209, 210, 211, 212, - 213, 214, -1, 216, -1, 218, 219, 220, 221, 222, - 223, 224, 225, 226, 227, 228, -1, -1, 231, 232, - 233, 234, -1, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, - 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, - 313, 314, 315, 316, 317, 318, 319, -1, 321, 322, - 323, 324, 325, 326, -1, 328, 329, 330, 331, 332, - 333, 334, 335, -1, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, -1, 387, 388, 389, 390, 391, 392, - 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, - -1, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, -1, 415, 416, -1, -1, 419, 420, 421, 422, - 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, - -1, -1, 435, 436, 437, 438, 439, 440, -1, 442, - 443, 444, 445, 446, 447, 448, -1, 450, 451, 452, - 453, 454, 455, 456, -1, -1, 459, -1, 461, 462, - 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 483, -1, 485, -1, -1, -1, -1, 490, 491, -1, - -1, -1, -1, -1, 497, -1, 499, -1, -1, -1, - -1, 504, 505, 506, 3, 4, 5, 6, 7, 8, - 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, - -1, 30, 31, 32, -1, -1, -1, -1, 37, -1, - -1, 40, 41, -1, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - -1, 70, 71, 72, 73, 74, -1, 76, -1, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, - 89, 90, 91, 92, 93, 94, -1, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, - 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, - -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, -1, 162, 163, 164, 165, -1, 167, -1, - 169, 170, 171, 172, 173, 174, 175, 176, 177, -1, - 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, -1, 198, - 199, 200, 201, 202, 203, -1, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, -1, 216, -1, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - -1, 230, 231, 232, 233, 234, -1, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, -1, 285, 286, -1, -1, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, -1, 311, 312, 313, 314, 315, 316, 317, 318, - 319, -1, 321, 322, 323, 324, 325, 326, -1, 328, - 329, 330, 331, 332, 333, 334, 335, -1, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, 356, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, - -1, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, -1, 387, 388, - 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 402, -1, 404, 405, -1, 407, 408, - 409, 410, 411, 412, 413, -1, 415, 416, -1, 418, - 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, - 429, 430, 431, 432, -1, -1, 435, 436, 437, 438, - 439, 440, -1, 442, 443, 444, 445, 446, 447, 448, - -1, 450, 451, 452, 453, 454, 455, 456, -1, -1, - 459, -1, -1, 462, 463, 464, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, -1, -1, -1, -1, -1, - -1, 490, 491, -1, -1, -1, -1, -1, 497, -1, - 499, -1, -1, -1, -1, 504, 505, 506, 3, 4, + -1, -1, -1, -1, -1, -1, 3142, -1, -1, -1, + -1, 3, 4, 5, 6, 7, 8, 9, 10, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, + 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, + 32, -1, -1, -1, -1, 37, 3182, -1, 40, 41, + -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, -1, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, -1, 70, 71, + 72, 73, 74, -1, 76, -1, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 3232, 89, 90, 91, + 92, 93, 94, -1, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, -1, 120, 121, + 122, 123, 124, 125, -1, 127, 128, 129, 130, 131, + -1, -1, 134, 135, 136, 137, 138, -1, 140, 141, + 142, -1, 144, 145, 146, -1, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, 160, -1, + 162, 163, 164, 165, -1, 167, -1, 169, 170, 171, + 172, 173, 174, 175, 176, 177, -1, 179, -1, 181, + 182, 183, -1, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, -1, 198, 199, 200, 201, + 202, 203, -1, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, -1, 216, -1, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, -1, -1, 231, + 232, 233, 234, -1, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, -1, 285, 286, -1, -1, 289, 290, 291, + -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, + 312, 313, 314, 315, 316, 317, 318, 319, 320, -1, + 322, 323, 324, 325, 326, 327, -1, 329, 330, 331, + 332, 333, 334, 335, 336, -1, 338, 339, 340, 341, + 342, 343, 344, 345, 346, 347, 348, 349, 350, -1, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, + 382, 383, 384, 385, 386, -1, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, + 402, 403, -1, 405, 406, 407, 408, 409, 410, 411, + 412, 413, 414, -1, 416, 417, -1, -1, 420, 421, + 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, + 432, 433, -1, -1, 436, 437, 438, 439, 440, 441, + 442, -1, 444, 445, 446, 447, 448, 449, 450, -1, + 452, 453, 454, 455, 456, 457, 458, -1, -1, 461, + -1, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, + 482, 483, 484, 485, -1, 487, -1, -1, -1, -1, + 492, 493, -1, -1, -1, -1, -1, 499, -1, 501, + 502, -1, -1, -1, 506, 507, 508, 509, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, - -1, 36, 37, -1, -1, 40, 41, -1, 43, 44, + -1, -1, 37, -1, -1, 40, 41, -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, -1, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, @@ -304595,7 +318542,7 @@ static const yytype_int16 yycheck[] = -1, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, -1, 120, 121, 122, 123, 124, - 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, + 125, -1, 127, 128, 129, 130, 131, 132, -1, 134, 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, -1, 162, 163, 164, @@ -304614,31 +318561,82 @@ static const yytype_int16 yycheck[] = 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, 313, 314, - 315, 316, 317, 318, 319, -1, 321, 322, 323, 324, - 325, 326, -1, 328, 329, 330, 331, 332, 333, 334, - 335, -1, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, + 315, 316, 317, 318, 319, 320, -1, 322, 323, 324, + 325, 326, 327, -1, 329, 330, 331, 332, 333, 334, + 335, 336, -1, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, -1, 370, 371, 372, 373, 374, + 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, -1, 404, - 405, -1, 407, 408, 409, 410, 411, 412, 413, -1, - 415, 416, -1, -1, 419, 420, 421, 422, 423, 424, - 425, 426, 427, 428, 429, 430, 431, 432, -1, -1, - 435, 436, 437, 438, 439, 440, -1, 442, 443, 444, - 445, 446, 447, 448, -1, 450, 451, 452, 453, 454, - 455, 456, -1, -1, 459, -1, -1, 462, 463, 464, + 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, -1, + 405, 406, -1, 408, 409, 410, 411, 412, 413, 414, + -1, 416, 417, -1, -1, 420, 421, 422, 423, 424, + 425, 426, 427, 428, 429, 430, 431, 432, 433, -1, + -1, 436, 437, 438, 439, 440, 441, 442, -1, 444, + 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, + 455, 456, 457, 458, -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 483, -1, - -1, -1, -1, -1, -1, 490, 491, -1, -1, -1, - -1, -1, 497, -1, 499, -1, -1, -1, -1, 504, - 505, 506, 3, 4, 5, 6, 7, 8, 9, 10, + 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 485, -1, -1, -1, -1, -1, -1, 492, 493, 494, + -1, -1, -1, -1, 499, -1, 501, 502, -1, -1, + -1, 506, 507, 508, 509, 3, 4, 5, 6, 7, + 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, + 28, -1, 30, 31, 32, -1, -1, -1, -1, 37, + -1, -1, 40, 41, -1, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, -1, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, -1, 70, 71, 72, 73, 74, -1, 76, -1, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + -1, 89, 90, 91, 92, 93, 94, -1, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, -1, 120, 121, 122, 123, 124, 125, -1, 127, + 128, 129, 130, 131, -1, -1, 134, 135, 136, 137, + 138, -1, 140, 141, 142, -1, 144, 145, 146, -1, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, -1, 162, 163, 164, 165, -1, 167, + -1, 169, 170, 171, 172, 173, 174, 175, 176, 177, + -1, 179, -1, 181, 182, 183, -1, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, -1, + 198, 199, 200, 201, 202, 203, -1, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, -1, 216, -1, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, -1, -1, 231, 232, 233, 234, -1, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, -1, 285, 286, -1, + -1, 289, 290, 291, -1, -1, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, -1, 311, 312, 313, 314, 315, 316, 317, + 318, 319, 320, -1, 322, 323, 324, 325, 326, 327, + -1, 329, 330, 331, 332, 333, 334, 335, 336, -1, + 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, + 348, 349, 350, -1, 352, 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, 383, 384, 385, 386, -1, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, -1, 405, 406, 407, + 408, 409, 410, 411, 412, 413, 414, -1, 416, 417, + -1, -1, 420, 421, 422, 423, 424, 425, 426, 427, + 428, 429, 430, 431, 432, 433, -1, -1, 436, 437, + 438, 439, 440, 441, 442, -1, 444, 445, 446, 447, + 448, 449, 450, -1, 452, 453, 454, 455, 456, 457, + 458, -1, -1, 461, -1, 463, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, + 478, 479, 480, 481, 482, 483, 484, 485, -1, 487, + -1, -1, -1, -1, 492, 493, -1, -1, -1, -1, + -1, 499, -1, 501, -1, -1, -1, -1, 506, 507, + 508, 509, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, 37, -1, -1, 40, 41, -1, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, -1, 56, 57, 58, 59, 60, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, 90, @@ -304650,12 +318648,12 @@ static const yytype_int16 yycheck[] = 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, -1, 162, 163, 164, 165, -1, 167, -1, 169, 170, - -1, 172, 173, 174, 175, 176, 177, -1, 179, -1, + 171, 172, 173, 174, 175, 176, 177, -1, 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, -1, 216, -1, 218, 219, 220, - 221, 222, 223, 224, 225, 226, 227, 228, -1, -1, + 221, 222, 223, 224, 225, 226, 227, 228, -1, 230, 231, 232, 233, 234, -1, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, @@ -304664,26 +318662,77 @@ static const yytype_int16 yycheck[] = 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, - 311, 312, 313, 314, 315, 316, 317, 318, 319, -1, - 321, 322, 323, 324, 325, 326, -1, 328, 329, 330, - 331, 332, 333, 334, 335, -1, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, -1, 370, + 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, + -1, 322, 323, 324, 325, 326, 327, -1, 329, 330, + 331, 332, 333, 334, 335, 336, -1, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, + -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 361, 362, 363, 364, 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, -1, 387, 388, 389, 390, + 381, 382, 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, -1, 404, 405, -1, 407, 408, 409, 410, - 411, 412, 413, -1, 415, 416, -1, -1, 419, 420, + 401, 402, 403, -1, 405, 406, -1, 408, 409, 410, + 411, 412, 413, 414, -1, 416, 417, -1, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, - 431, 432, -1, -1, 435, 436, 437, 438, 439, 440, - -1, 442, 443, 444, 445, 446, 447, 448, -1, 450, - 451, 452, 453, 454, 455, 456, -1, -1, 459, -1, - -1, 462, 463, 464, 465, 466, 467, 468, 469, 470, + 431, 432, 433, -1, -1, 436, 437, 438, 439, 440, + 441, 442, -1, 444, 445, 446, 447, 448, 449, 450, + -1, 452, 453, 454, 455, 456, 457, 458, -1, -1, + 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 483, -1, -1, -1, -1, -1, -1, 490, - 491, 492, -1, -1, -1, -1, 497, -1, 499, -1, - -1, -1, -1, 504, 505, 506, 3, 4, 5, 6, + 481, 482, 483, 484, 485, -1, -1, -1, -1, -1, + -1, 492, 493, -1, -1, -1, -1, -1, 499, -1, + 501, -1, -1, -1, -1, 506, 507, 508, 509, 3, + 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, + -1, -1, 36, 37, -1, -1, 40, 41, -1, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, -1, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, -1, 70, 71, 72, 73, + 74, -1, 76, -1, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, + 94, -1, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, -1, 120, 121, 122, 123, + 124, 125, -1, 127, 128, 129, 130, 131, -1, -1, + 134, 135, 136, 137, 138, -1, 140, 141, 142, -1, + 144, 145, 146, -1, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 159, 160, -1, 162, 163, + 164, 165, -1, 167, -1, 169, 170, -1, 172, 173, + 174, 175, 176, 177, -1, 179, -1, 181, 182, 183, + -1, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 194, 195, 196, -1, 198, 199, 200, 201, 202, 203, + -1, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 214, -1, 216, -1, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, -1, -1, 231, 232, 233, + 234, -1, 236, 237, 238, 239, 240, 241, 242, 243, + 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, 306, 307, 308, 309, -1, 311, 312, 313, + 314, 315, 316, 317, 318, 319, 320, -1, 322, 323, + 324, 325, 326, 327, -1, 329, 330, 331, 332, 333, + 334, 335, 336, -1, 338, 339, 340, 341, 342, 343, + 344, 345, 346, 347, 348, 349, 350, -1, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, + 364, 365, 366, 367, 368, 369, -1, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, + 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, + -1, 405, 406, -1, 408, 409, 410, 411, 412, 413, + 414, -1, 416, 417, -1, -1, 420, 421, 422, 423, + 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, + -1, -1, 436, 437, 438, 439, 440, 441, 442, -1, + 444, 445, 446, 447, 448, 449, 450, -1, 452, 453, + 454, 455, 456, 457, 458, -1, -1, 461, -1, -1, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, + 484, 485, -1, -1, -1, -1, -1, -1, 492, 493, + -1, -1, -1, -1, -1, 499, -1, 501, -1, -1, + -1, -1, 506, 507, 508, 509, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, @@ -304715,25 +318764,76 @@ static const yytype_int16 yycheck[] = -1, -1, 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, 316, - 317, 318, 319, -1, 321, 322, 323, 324, 325, 326, - -1, 328, 329, 330, 331, 332, 333, 334, 335, -1, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, 356, + 317, 318, 319, 320, -1, 322, 323, 324, 325, 326, + 327, -1, 329, 330, 331, 332, 333, 334, 335, 336, + -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - 367, 368, -1, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, 381, 382, 383, 384, 385, -1, - 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, - 397, 398, 399, 400, 401, 402, -1, 404, 405, -1, - 407, 408, 409, 410, 411, 412, 413, -1, 415, 416, - -1, -1, 419, 420, 421, 422, 423, 424, 425, 426, - 427, 428, 429, 430, 431, 432, -1, -1, 435, 436, - 437, 438, 439, 440, -1, 442, 443, 444, 445, 446, - 447, 448, -1, 450, 451, 452, 453, 454, 455, 456, - -1, -1, 459, -1, -1, 462, 463, 464, 465, 466, + 367, 368, 369, -1, 371, 372, 373, 374, 375, 376, + 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, + -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, -1, 405, 406, + -1, 408, 409, 410, 411, 412, 413, 414, -1, 416, + 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, + 427, 428, 429, 430, 431, 432, 433, -1, -1, 436, + 437, 438, 439, 440, 441, 442, -1, 444, 445, 446, + 447, 448, 449, 450, -1, 452, 453, 454, 455, 456, + 457, 458, -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 483, -1, -1, -1, - -1, -1, -1, 490, 491, 492, -1, -1, -1, -1, - 497, -1, 499, -1, -1, -1, -1, 504, 505, 506, + 477, 478, 479, 480, 481, 482, 483, 484, 485, -1, + -1, -1, -1, -1, -1, 492, 493, 494, -1, -1, + -1, -1, 499, -1, 501, -1, -1, -1, -1, 506, + 507, 508, 509, 3, 4, 5, 6, 7, 8, 9, + 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, -1, -1, -1, -1, 37, -1, -1, + 40, 41, -1, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, -1, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, -1, + 70, 71, 72, 73, 74, -1, 76, -1, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, + 90, 91, 92, 93, 94, -1, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, -1, + 120, 121, 122, 123, 124, 125, -1, 127, 128, 129, + 130, 131, -1, -1, 134, 135, 136, 137, 138, -1, + 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, -1, 162, 163, 164, 165, -1, 167, -1, 169, + 170, -1, 172, 173, 174, 175, 176, 177, -1, 179, + -1, 181, 182, 183, -1, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, -1, 198, 199, + 200, 201, 202, 203, -1, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, -1, 216, -1, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, -1, + -1, 231, 232, 233, 234, -1, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, -1, 285, 286, -1, -1, 289, + 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + -1, 311, 312, 313, 314, 315, 316, 317, 318, 319, + 320, -1, 322, 323, 324, 325, 326, 327, -1, 329, + 330, 331, 332, 333, 334, 335, 336, -1, 338, 339, + 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, + 350, -1, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, + -1, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 380, 381, 382, 383, 384, 385, 386, -1, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, + 400, 401, 402, 403, -1, 405, 406, -1, 408, 409, + 410, 411, 412, 413, 414, -1, 416, 417, -1, -1, + 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, + 430, 431, 432, 433, -1, -1, 436, 437, 438, 439, + 440, 441, 442, -1, 444, 445, 446, 447, 448, 449, + 450, -1, 452, 453, 454, 455, 456, 457, 458, -1, + -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, + 480, 481, 482, 483, 484, 485, -1, -1, -1, -1, + -1, -1, 492, 493, 494, -1, -1, -1, -1, 499, + -1, 501, -1, -1, -1, -1, 506, 507, 508, 509, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, @@ -304765,29 +318865,80 @@ static const yytype_int16 yycheck[] = 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, - 313, 314, 315, 316, 317, 318, 319, -1, 321, 322, - 323, 324, 325, 326, -1, 328, 329, 330, 331, 332, - 333, 334, 335, -1, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, + 313, 314, 315, 316, 317, 318, 319, 320, -1, 322, + 323, 324, 325, 326, 327, -1, 329, 330, 331, 332, + 333, 334, 335, 336, -1, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, -1, 370, 371, 372, + 363, 364, 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, -1, 387, 388, 389, 390, 391, 392, + 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, - -1, 404, 405, -1, 407, 408, 409, 410, 411, 412, - 413, -1, 415, 416, -1, -1, 419, 420, 421, 422, + 403, -1, 405, 406, -1, 408, 409, 410, 411, 412, + 413, 414, -1, 416, 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, - -1, -1, 435, 436, 437, 438, 439, 440, -1, 442, - 443, 444, 445, 446, 447, 448, -1, 450, 451, 452, - 453, 454, 455, 456, -1, -1, 459, -1, -1, 462, - 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 433, -1, -1, 436, 437, 438, 439, 440, 441, 442, + -1, 444, 445, 446, 447, 448, 449, 450, -1, 452, + 453, 454, 455, 456, 457, 458, -1, -1, 461, -1, + -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 483, -1, -1, -1, -1, -1, -1, 490, 491, 492, - -1, -1, -1, -1, 497, -1, 499, -1, -1, -1, - -1, 504, 505, 506, 3, 4, 5, 6, 7, 8, + 483, 484, 485, -1, -1, -1, -1, -1, -1, 492, + 493, 494, -1, -1, -1, -1, 499, -1, 501, -1, + -1, -1, -1, 506, 507, 508, 509, 3, 4, 5, + 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, + -1, 37, -1, -1, 40, 41, -1, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, -1, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, + 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, -1, 120, 121, 122, 123, 124, 125, + -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, + 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, + 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 157, 158, 159, 160, -1, 162, 163, 164, 165, + -1, 167, -1, 169, 170, -1, 172, 173, 174, 175, + 176, 177, -1, 179, -1, 181, 182, 183, -1, 185, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, + 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, -1, + 216, -1, 218, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 228, -1, -1, 231, 232, 233, 234, -1, + 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, + 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, + 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, -1, 285, + 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, + 316, 317, 318, 319, 320, -1, 322, 323, 324, 325, + 326, 327, -1, 329, 330, 331, 332, 333, 334, 335, + 336, -1, 338, 339, 340, 341, 342, 343, 344, 345, + 346, 347, 348, 349, 350, -1, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, + 366, 367, 368, 369, -1, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, + 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 403, -1, 405, + 406, -1, 408, 409, 410, 411, 412, 413, 414, -1, + 416, 417, -1, -1, 420, 421, 422, 423, 424, 425, + 426, 427, 428, 429, 430, 431, 432, 433, -1, -1, + 436, 437, 438, 439, 440, 441, 442, -1, 444, 445, + 446, 447, 448, 449, 450, -1, 452, 453, 454, 455, + 456, 457, 458, -1, -1, 461, -1, -1, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, + -1, -1, -1, -1, -1, -1, 492, 493, -1, -1, + -1, -1, -1, 499, -1, 501, -1, -1, -1, -1, + 506, 507, 508, 509, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, -1, -1, -1, -1, 37, -1, + -1, 30, 31, 32, -1, -1, -1, -1, 37, -1, -1, 40, 41, -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, -1, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, @@ -304801,7 +318952,7 @@ static const yytype_int16 yycheck[] = -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, -1, 162, 163, 164, 165, -1, 167, -1, - 169, 170, -1, 172, 173, 174, 175, 176, 177, -1, + 169, 170, 171, 172, 173, 174, 175, 176, 177, -1, 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, 206, 207, 208, @@ -304816,25 +318967,76 @@ static const yytype_int16 yycheck[] = 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, 316, 317, 318, - 319, -1, 321, 322, 323, 324, 325, 326, -1, 328, - 329, 330, 331, 332, 333, 334, 335, -1, 337, 338, + 319, 320, -1, 322, 323, 324, 325, 326, 327, -1, + 329, 330, 331, 332, 333, 334, 335, 336, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, 356, 357, 358, + 349, 350, -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, - -1, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, -1, 387, 388, + 369, -1, 371, 372, 373, 374, 375, 376, 377, 378, + 379, 380, 381, 382, 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 402, -1, 404, 405, -1, 407, 408, - 409, 410, 411, 412, 413, -1, 415, 416, -1, -1, - 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, - 429, 430, 431, 432, -1, -1, 435, 436, 437, 438, - 439, 440, -1, 442, 443, 444, 445, 446, 447, 448, - -1, 450, 451, 452, 453, 454, 455, 456, -1, -1, - 459, -1, -1, 462, 463, 464, 465, 466, 467, 468, + 399, 400, 401, 402, 403, -1, 405, 406, -1, 408, + 409, 410, 411, 412, 413, 414, -1, 416, 417, -1, + -1, 420, 421, 422, 423, 424, 425, 426, 427, 428, + 429, 430, 431, 432, 433, -1, -1, 436, 437, 438, + 439, 440, 441, 442, -1, 444, 445, 446, 447, 448, + 449, 450, -1, 452, 453, 454, 455, 456, 457, 458, + -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, -1, -1, -1, -1, -1, - -1, 490, 491, -1, -1, -1, -1, -1, 497, -1, - 499, -1, -1, -1, -1, 504, 505, 506, 3, 4, + 479, 480, 481, 482, 483, 484, 485, -1, -1, -1, + -1, -1, -1, 492, 493, -1, -1, -1, -1, -1, + 499, -1, 501, -1, -1, -1, -1, 506, 507, 508, + 509, 3, 4, 5, 6, 7, 8, 9, 10, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, + 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, + 32, -1, -1, -1, -1, 37, -1, -1, 40, 41, + -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, -1, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, -1, 70, 71, + 72, 73, 74, -1, 76, -1, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, -1, 89, 90, 91, + 92, 93, 94, -1, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, -1, 120, 121, + 122, 123, 124, 125, -1, 127, 128, 129, 130, 131, + -1, -1, 134, 135, 136, 137, 138, -1, 140, 141, + 142, -1, 144, 145, 146, -1, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, 160, -1, + 162, 163, 164, 165, -1, 167, -1, 169, 170, -1, + 172, 173, 174, 175, 176, 177, -1, 179, -1, 181, + 182, 183, -1, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, -1, 198, 199, 200, 201, + 202, 203, -1, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, -1, 216, -1, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, -1, -1, 231, + 232, 233, 234, -1, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, -1, 285, 286, -1, -1, 289, 290, 291, + -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, + 312, 313, 314, 315, 316, 317, 318, 319, 320, -1, + 322, 323, 324, 325, 326, 327, -1, 329, 330, 331, + 332, 333, 334, 335, 336, -1, 338, 339, 340, 341, + 342, 343, 344, 345, 346, 347, 348, 349, 350, -1, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, 365, 366, 367, 368, 369, -1, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, + 382, 383, 384, 385, 386, -1, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, + 402, 403, -1, 405, 406, -1, 408, 409, 410, 411, + 412, 413, 414, -1, 416, 417, -1, -1, 420, 421, + 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, + 432, 433, -1, -1, 436, 437, 438, 439, 440, 441, + 442, -1, 444, 445, 446, 447, 448, 449, 450, -1, + 452, 453, 454, 455, 456, 457, 458, -1, -1, 461, + -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, + 482, 483, 484, 485, -1, -1, -1, -1, -1, -1, + 492, 493, -1, -1, -1, -1, -1, 499, -1, 501, + 502, -1, -1, -1, 506, 507, 508, 509, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, @@ -304851,7 +319053,7 @@ static const yytype_int16 yycheck[] = 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, -1, 162, 163, 164, - 165, -1, 167, -1, 169, 170, 171, 172, 173, 174, + 165, -1, 167, -1, 169, 170, -1, 172, 173, 174, 175, 176, 177, -1, 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, @@ -304866,26 +319068,77 @@ static const yytype_int16 yycheck[] = 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, 313, 314, - 315, 316, 317, 318, 319, -1, 321, 322, 323, 324, - 325, 326, -1, 328, 329, 330, 331, 332, 333, 334, - 335, -1, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, + 315, 316, 317, 318, 319, 320, -1, 322, 323, 324, + 325, 326, 327, -1, 329, 330, 331, 332, 333, 334, + 335, 336, -1, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, -1, 370, 371, 372, 373, 374, + 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, -1, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, -1, 404, - 405, -1, 407, 408, 409, 410, 411, 412, 413, -1, - 415, 416, -1, -1, 419, 420, 421, 422, 423, 424, - 425, 426, 427, 428, 429, 430, 431, 432, -1, -1, - 435, 436, 437, 438, 439, 440, -1, 442, 443, 444, - 445, 446, 447, 448, -1, 450, 451, 452, 453, 454, - 455, 456, -1, -1, 459, -1, -1, 462, 463, 464, + 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, -1, + 405, 406, -1, 408, 409, 410, 411, 412, 413, 414, + -1, 416, 417, -1, -1, 420, 421, 422, 423, 424, + 425, 426, 427, 428, 429, 430, 431, 432, 433, -1, + -1, 436, 437, 438, 439, 440, 441, 442, -1, 444, + 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, + 455, 456, 457, 458, -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 483, -1, - -1, -1, -1, -1, -1, 490, 491, -1, -1, -1, - -1, -1, 497, -1, 499, -1, -1, -1, -1, 504, - 505, 506, 3, 4, 5, 6, 7, 8, 9, 10, + 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 485, -1, -1, -1, -1, -1, -1, 492, 493, -1, + -1, -1, -1, -1, 499, -1, 501, -1, -1, -1, + -1, 506, 507, 508, 509, 3, 4, 5, 6, 7, + 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, + 28, -1, 30, 31, 32, -1, -1, -1, -1, 37, + -1, -1, 40, 41, -1, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, -1, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, -1, 70, 71, 72, 73, 74, -1, 76, -1, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + -1, 89, 90, 91, 92, 93, 94, -1, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, -1, 120, 121, 122, 123, 124, 125, -1, 127, + 128, 129, 130, 131, -1, -1, 134, 135, 136, 137, + 138, -1, 140, 141, 142, -1, 144, 145, 146, -1, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, -1, 162, 163, 164, 165, -1, 167, + -1, 169, 170, -1, 172, 173, 174, 175, 176, 177, + -1, 179, -1, 181, 182, 183, -1, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, -1, + 198, 199, 200, 201, 202, 203, -1, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, -1, 216, -1, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, -1, -1, 231, 232, 233, 234, -1, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, -1, 285, 286, -1, + -1, 289, 290, 291, -1, -1, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, -1, 311, 312, 313, 314, 315, 316, 317, + 318, 319, 320, -1, 322, 323, 324, 325, 326, 327, + -1, 329, 330, 331, 332, 333, 334, 335, 336, -1, + 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, + 348, 349, 350, -1, 352, 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, + 368, 369, -1, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, 383, 384, 385, 386, -1, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, -1, 405, 406, -1, + 408, 409, 410, 411, 412, 413, 414, -1, 416, 417, + -1, -1, 420, 421, 422, 423, 424, 425, 426, 427, + 428, 429, 430, 431, 432, 433, -1, -1, 436, 437, + 438, 439, 440, 441, 442, -1, 444, 445, 446, 447, + 448, 449, 450, -1, 452, 453, 454, 455, 456, 457, + 458, -1, -1, 461, -1, -1, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, + 478, 479, 480, 481, 482, 483, 484, 485, -1, -1, + -1, -1, -1, -1, 492, 493, -1, -1, -1, -1, + -1, 499, -1, 501, 502, -1, -1, -1, 506, 507, + 508, 509, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, 37, -1, -1, 40, @@ -304916,26 +319169,77 @@ static const yytype_int16 yycheck[] = 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, - 311, 312, 313, 314, 315, 316, 317, 318, 319, -1, - 321, 322, 323, 324, 325, 326, -1, 328, 329, 330, - 331, 332, 333, 334, 335, -1, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, -1, 370, + 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, + -1, 322, 323, 324, 325, 326, 327, -1, 329, 330, + 331, 332, 333, 334, 335, 336, -1, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, + -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 361, 362, 363, 364, 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, -1, 387, 388, 389, 390, + 381, 382, 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, -1, 404, 405, -1, 407, 408, 409, 410, - 411, 412, 413, -1, 415, 416, -1, -1, 419, 420, + 401, 402, 403, -1, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, -1, 416, 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, - 431, 432, -1, -1, 435, 436, 437, 438, 439, 440, - -1, 442, 443, 444, 445, 446, 447, 448, -1, 450, - 451, 452, 453, 454, 455, 456, -1, -1, 459, -1, - -1, 462, 463, 464, 465, 466, 467, 468, 469, 470, + 431, 432, 433, -1, -1, 436, 437, 438, 439, 440, + 441, 442, -1, 444, 445, 446, 447, 448, 449, 450, + -1, 452, 453, 454, 455, 456, 457, 458, -1, -1, + 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 483, -1, -1, -1, -1, -1, -1, 490, - 491, -1, -1, -1, -1, -1, 497, -1, 499, 500, - -1, -1, -1, 504, 505, 506, 3, 4, 5, 6, + 481, 482, 483, 484, 485, -1, -1, -1, -1, -1, + -1, 492, 493, -1, -1, -1, -1, -1, 499, -1, + 501, -1, -1, -1, -1, 506, 507, 508, 509, 3, + 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, + 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, + -1, -1, -1, 37, -1, -1, 40, 41, -1, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, -1, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, -1, 70, 71, 72, 73, + 74, -1, 76, -1, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, + 94, -1, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, -1, 120, 121, 122, 123, + 124, 125, -1, 127, 128, 129, 130, 131, -1, -1, + 134, 135, 136, 137, 138, -1, 140, 141, 142, -1, + 144, 145, 146, -1, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 159, 160, -1, 162, 163, + 164, 165, -1, 167, -1, 169, 170, -1, 172, 173, + 174, 175, 176, 177, -1, 179, -1, 181, 182, 183, + -1, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 194, 195, 196, -1, 198, 199, 200, 201, 202, 203, + -1, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 214, -1, 216, -1, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, -1, -1, 231, 232, 233, + 234, -1, 236, 237, 238, 239, 240, 241, 242, 243, + 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, 306, 307, 308, 309, -1, 311, 312, 313, + 314, 315, 316, 317, 318, 319, 320, -1, 322, 323, + 324, 325, 326, 327, -1, 329, 330, 331, 332, 333, + 334, 335, 336, -1, 338, 339, 340, 341, 342, 343, + 344, 345, 346, 347, 348, 349, 350, -1, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, + 364, 365, 366, 367, 368, 369, -1, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, + 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, + -1, 405, 406, -1, 408, 409, 410, 411, 412, 413, + 414, -1, 416, 417, -1, -1, 420, 421, 422, 423, + 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, + -1, -1, 436, 437, 438, 439, 440, 441, 442, -1, + 444, 445, 446, 447, 448, 449, 450, -1, 452, 453, + 454, 455, 456, 457, 458, -1, 460, 461, -1, -1, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, + 484, 485, -1, -1, -1, -1, -1, -1, 492, 493, + -1, -1, -1, -1, -1, 499, -1, 501, -1, -1, + -1, -1, 506, 507, 508, 509, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, @@ -304967,25 +319271,76 @@ static const yytype_int16 yycheck[] = -1, -1, 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, 316, - 317, 318, 319, -1, 321, 322, 323, 324, 325, 326, - -1, 328, 329, 330, 331, 332, 333, 334, 335, -1, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, 356, + 317, 318, 319, 320, -1, 322, 323, 324, 325, 326, + 327, -1, 329, 330, 331, 332, 333, 334, 335, 336, + -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - 367, 368, -1, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, 381, 382, 383, 384, 385, -1, - 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, - 397, 398, 399, 400, 401, 402, -1, 404, 405, -1, - 407, 408, 409, 410, 411, 412, 413, -1, 415, 416, - -1, -1, 419, 420, 421, 422, 423, 424, 425, 426, - 427, 428, 429, 430, 431, 432, -1, -1, 435, 436, - 437, 438, 439, 440, -1, 442, 443, 444, 445, 446, - 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, - -1, -1, 459, -1, -1, 462, 463, 464, 465, 466, + 367, 368, 369, -1, 371, 372, 373, 374, 375, 376, + 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, + -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, -1, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, -1, 416, + 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, + 427, 428, 429, 430, 431, 432, 433, -1, -1, 436, + 437, 438, 439, 440, 441, 442, -1, 444, 445, 446, + 447, 448, 449, 450, -1, 452, 453, 454, 455, 456, + 457, 458, -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 483, -1, -1, -1, - -1, -1, -1, 490, 491, -1, -1, -1, -1, -1, - 497, -1, 499, -1, -1, -1, -1, 504, 505, 506, + 477, 478, 479, 480, 481, 482, 483, 484, 485, -1, + -1, -1, -1, -1, -1, 492, 493, -1, -1, -1, + -1, -1, 499, -1, 501, -1, -1, -1, -1, 506, + 507, 508, 509, 3, 4, 5, 6, 7, 8, 9, + 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, + 30, 31, 32, -1, -1, -1, -1, 37, -1, -1, + 40, 41, -1, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, -1, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, -1, + 70, 71, 72, 73, 74, -1, 76, -1, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, + 90, 91, 92, 93, 94, -1, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, -1, + 120, 121, 122, 123, 124, 125, -1, 127, 128, 129, + 130, 131, -1, -1, 134, 135, 136, 137, 138, -1, + 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, -1, 162, 163, 164, 165, -1, 167, -1, 169, + 170, -1, 172, 173, 174, 175, 176, 177, -1, 179, + -1, 181, 182, 183, -1, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, -1, 198, 199, + 200, 201, 202, 203, -1, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, -1, 216, -1, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, -1, + -1, 231, 232, 233, 234, -1, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, -1, 285, 286, -1, -1, 289, + 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + -1, 311, 312, 313, 314, 315, 316, 317, 318, 319, + 320, -1, 322, 323, 324, 325, 326, 327, -1, 329, + 330, 331, 332, 333, 334, 335, 336, -1, 338, 339, + 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, + 350, -1, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, + -1, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 380, 381, 382, 383, 384, 385, 386, -1, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, + 400, 401, 402, 403, -1, 405, 406, 407, 408, 409, + 410, 411, 412, 413, 414, -1, 416, 417, -1, -1, + 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, + 430, 431, 432, 433, -1, -1, 436, 437, 438, 439, + 440, 441, 442, -1, 444, 445, 446, 447, 448, 449, + 450, -1, 452, 453, 454, 455, 456, 457, 458, -1, + -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, + 480, 481, 482, 483, 484, 485, -1, -1, -1, -1, + -1, -1, 492, 493, -1, -1, -1, -1, -1, 499, + -1, 501, -1, -1, -1, -1, 506, 507, 508, 509, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, @@ -305017,26 +319372,77 @@ static const yytype_int16 yycheck[] = 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, - 313, 314, 315, 316, 317, 318, 319, -1, 321, 322, - 323, 324, 325, 326, -1, 328, 329, 330, 331, 332, - 333, 334, 335, -1, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, + 313, 314, 315, 316, 317, 318, 319, 320, -1, 322, + 323, 324, 325, 326, 327, -1, 329, 330, 331, 332, + 333, 334, 335, 336, -1, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, -1, 370, 371, 372, + 363, 364, 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, -1, 387, 388, 389, 390, 391, 392, + 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, - -1, 404, 405, -1, 407, 408, 409, 410, 411, 412, - 413, -1, 415, 416, -1, -1, 419, 420, 421, 422, + 403, -1, 405, 406, -1, 408, 409, 410, 411, 412, + 413, 414, -1, 416, 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, - -1, -1, 435, 436, 437, 438, 439, 440, -1, 442, - 443, 444, 445, 446, 447, 448, -1, 450, 451, 452, - 453, 454, 455, 456, -1, -1, 459, -1, -1, 462, - 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 433, -1, -1, 436, 437, 438, 439, 440, 441, 442, + -1, 444, 445, 446, 447, 448, 449, 450, -1, 452, + 453, 454, 455, 456, 457, 458, -1, -1, 461, -1, + -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 483, -1, -1, -1, -1, -1, -1, 490, 491, -1, - -1, -1, -1, -1, 497, -1, 499, 500, -1, -1, - -1, 504, 505, 506, 3, 4, 5, 6, 7, 8, + 483, 484, 485, -1, -1, -1, -1, -1, -1, 492, + 493, -1, -1, -1, -1, -1, 499, -1, 501, -1, + -1, -1, -1, 506, 507, 508, 509, 3, 4, 5, + 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, + 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, + -1, 37, -1, -1, 40, 41, -1, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, -1, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, + 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, -1, 120, 121, 122, 123, 124, 125, + -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, + 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, + 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 157, 158, 159, 160, -1, 162, 163, 164, 165, + -1, 167, -1, 169, 170, -1, 172, 173, 174, 175, + 176, 177, -1, 179, -1, 181, 182, 183, -1, 185, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, + 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, -1, + 216, -1, 218, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 228, -1, -1, 231, 232, 233, 234, -1, + 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, + 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, + 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, -1, 285, + 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, + 316, 317, 318, 319, 320, -1, 322, 323, 324, 325, + 326, 327, -1, 329, 330, 331, 332, 333, 334, 335, + 336, -1, 338, 339, 340, 341, 342, 343, 344, 345, + 346, 347, 348, 349, 350, -1, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, + 366, 367, 368, 369, -1, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, + 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 403, -1, 405, + 406, -1, 408, 409, 410, 411, 412, 413, 414, -1, + 416, 417, -1, -1, 420, 421, 422, 423, 424, 425, + 426, 427, 428, 429, 430, 431, 432, 433, -1, -1, + 436, 437, 438, 439, 440, 441, 442, -1, 444, 445, + 446, 447, 448, 449, 450, -1, 452, 453, 454, 455, + 456, 457, 458, -1, -1, 461, -1, -1, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, + -1, -1, -1, -1, -1, -1, 492, 493, -1, -1, + -1, -1, -1, 499, -1, 501, -1, -1, -1, -1, + 506, 507, 508, 509, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, 37, -1, @@ -305068,25 +319474,76 @@ static const yytype_int16 yycheck[] = 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, 316, 317, 318, - 319, -1, 321, 322, 323, 324, 325, 326, -1, 328, - 329, 330, 331, 332, 333, 334, 335, -1, 337, 338, + 319, 320, -1, 322, 323, 324, 325, 326, 327, -1, + 329, 330, 331, 332, 333, 334, 335, 336, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, 356, 357, 358, + 349, 350, -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, - -1, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, -1, 387, 388, + 369, -1, 371, 372, 373, 374, 375, 376, 377, 378, + 379, 380, 381, 382, 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, 411, 412, 413, -1, 415, 416, -1, -1, - 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, - 429, 430, 431, 432, -1, -1, 435, 436, 437, 438, - 439, 440, -1, 442, 443, 444, 445, 446, 447, 448, - -1, 450, 451, 452, 453, 454, 455, 456, -1, -1, - 459, -1, -1, 462, 463, 464, 465, 466, 467, 468, + 399, 400, 401, 402, 403, -1, 405, 406, -1, 408, + 409, 410, 411, 412, 413, 414, -1, 416, 417, -1, + -1, 420, 421, 422, 423, 424, 425, 426, 427, 428, + 429, 430, 431, 432, 433, -1, -1, 436, 437, 438, + 439, 440, 441, 442, -1, 444, 445, 446, 447, 448, + 449, 450, -1, 452, 453, 454, 455, 456, 457, 458, + -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, -1, -1, -1, -1, -1, - -1, 490, 491, -1, -1, -1, -1, -1, 497, -1, - 499, -1, -1, -1, -1, 504, 505, 506, 3, 4, + 479, 480, 481, 482, 483, 484, 485, -1, -1, -1, + -1, -1, -1, 492, 493, -1, -1, -1, -1, -1, + 499, -1, 501, -1, -1, -1, -1, 506, 507, 508, + 509, 3, 4, 5, 6, 7, 8, 9, 10, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, + 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, + 32, -1, -1, -1, -1, 37, -1, -1, 40, 41, + -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, -1, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, -1, 70, 71, + 72, 73, 74, -1, 76, -1, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, -1, 89, 90, 91, + 92, 93, 94, -1, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, 117, 118, -1, 120, 121, + 122, 123, 124, 125, -1, 127, 128, 129, 130, 131, + -1, -1, 134, 135, 136, 137, 138, -1, 140, 141, + 142, -1, 144, 145, 146, -1, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, 160, -1, + 162, 163, 164, 165, -1, 167, -1, 169, 170, -1, + 172, 173, 174, 175, 176, 177, -1, 179, -1, 181, + 182, 183, -1, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, -1, 198, 199, 200, 201, + 202, 203, -1, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, -1, 216, -1, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, -1, -1, 231, + 232, 233, 234, -1, 236, 237, 238, 239, 240, 241, + 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, -1, 285, 286, -1, -1, 289, 290, 291, + -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, + 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, + 312, 313, 314, 315, 316, 317, 318, 319, 320, -1, + 322, 323, 324, 325, 326, 327, -1, 329, 330, 331, + 332, 333, 334, 335, 336, -1, 338, 339, 340, 341, + 342, 343, 344, 345, 346, 347, 348, 349, 350, -1, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, 365, 366, 367, 368, 369, -1, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, + 382, 383, 384, 385, 386, -1, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, + 402, 403, -1, 405, 406, -1, 408, 409, 410, 411, + 412, 413, 414, -1, 416, 417, -1, -1, 420, 421, + 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, + 432, 433, -1, -1, 436, 437, 438, 439, 440, 441, + 442, -1, 444, 445, 446, 447, 448, 449, 450, -1, + 452, 453, 454, 455, 456, 457, 458, -1, -1, 461, + -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, + 482, 483, 484, 485, -1, -1, -1, -1, -1, -1, + 492, 493, -1, -1, -1, -1, -1, 499, -1, 501, + -1, -1, -1, -1, 506, 507, 508, 509, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, @@ -305118,26 +319575,77 @@ static const yytype_int16 yycheck[] = 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, 313, 314, - 315, 316, 317, 318, 319, -1, 321, 322, 323, 324, - 325, 326, -1, 328, 329, 330, 331, 332, 333, 334, - 335, -1, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, + 315, 316, 317, 318, 319, 320, -1, 322, 323, 324, + 325, 326, 327, -1, 329, 330, 331, 332, 333, 334, + 335, 336, -1, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, -1, 370, 371, 372, 373, 374, + 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, -1, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, -1, 404, - 405, -1, 407, 408, 409, 410, 411, 412, 413, -1, - 415, 416, -1, -1, 419, 420, 421, 422, 423, 424, - 425, 426, 427, 428, 429, 430, 431, 432, -1, -1, - 435, 436, 437, 438, 439, 440, -1, 442, 443, 444, - 445, 446, 447, 448, -1, 450, 451, 452, 453, 454, - 455, 456, -1, 458, 459, -1, -1, 462, 463, 464, + 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, -1, + 405, 406, -1, 408, 409, 410, 411, 412, 413, 414, + -1, 416, 417, -1, -1, 420, 421, 422, 423, 424, + 425, 426, 427, 428, 429, 430, 431, 432, 433, -1, + -1, 436, 437, 438, 439, 440, 441, 442, -1, 444, + 445, 446, 447, 448, 449, 450, -1, 452, 453, 454, + 455, 456, 457, 458, -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 483, -1, - -1, -1, -1, -1, -1, 490, 491, -1, -1, -1, - -1, -1, 497, -1, 499, -1, -1, -1, -1, 504, - 505, 506, 3, 4, 5, 6, 7, 8, 9, 10, + 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 485, -1, -1, -1, -1, -1, -1, 492, 493, -1, + -1, -1, -1, -1, 499, -1, 501, -1, -1, -1, + -1, 506, 507, 508, 509, 3, 4, 5, 6, 7, + 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, + 28, -1, 30, 31, 32, -1, -1, -1, -1, 37, + -1, -1, 40, 41, -1, 43, 44, 45, 46, 47, + 48, 49, 50, 51, 52, 53, 54, -1, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, + 68, -1, 70, 71, 72, 73, 74, -1, 76, -1, + 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, + -1, 89, 90, 91, 92, 93, 94, -1, 96, 97, + 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, -1, 120, 121, 122, 123, 124, 125, -1, 127, + 128, 129, 130, 131, -1, -1, 134, 135, 136, 137, + 138, -1, 140, 141, 142, -1, 144, 145, 146, -1, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, 159, 160, -1, 162, 163, 164, 165, -1, 167, + -1, 169, 170, -1, 172, 173, 174, 175, 176, 177, + -1, 179, -1, 181, 182, 183, -1, 185, 186, 187, + 188, 189, 190, 191, 192, 193, 194, 195, 196, -1, + 198, 199, 200, 201, 202, 203, -1, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, -1, 216, -1, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, -1, -1, 231, 232, 233, 234, -1, 236, 237, + 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, -1, 285, 286, -1, + -1, 289, 290, 291, -1, -1, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, -1, 311, 312, 313, 314, 315, 316, 317, + 318, 319, 320, -1, 322, 323, 324, 325, 326, 327, + -1, 329, 330, 331, 332, 333, 334, 335, 336, -1, + 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, + 348, 349, 350, -1, 352, 353, 354, 355, 356, 357, + 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, + 368, 369, -1, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, 383, 384, 385, 386, -1, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, -1, 405, 406, -1, + 408, 409, 410, 411, 412, 413, 414, -1, 416, 417, + -1, -1, 420, 421, 422, 423, 424, 425, 426, 427, + 428, 429, 430, 431, 432, 433, -1, -1, 436, 437, + 438, 439, 440, 441, 442, -1, 444, 445, 446, 447, + 448, 449, 450, -1, 452, 453, 454, 455, 456, 457, + 458, -1, -1, 461, -1, -1, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, + 478, 479, 480, 481, 482, 483, 484, 485, -1, -1, + -1, -1, -1, -1, 492, 493, -1, -1, -1, -1, + -1, 499, -1, 501, -1, -1, -1, -1, 506, 507, + 508, 509, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, 37, -1, -1, 40, @@ -305168,26 +319676,77 @@ static const yytype_int16 yycheck[] = 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, - 311, 312, 313, 314, 315, 316, 317, 318, 319, -1, - 321, 322, 323, 324, 325, 326, -1, 328, 329, 330, - 331, 332, 333, 334, 335, -1, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, -1, 370, + 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, + -1, 322, 323, 324, 325, 326, 327, -1, 329, 330, + 331, 332, 333, 334, 335, 336, -1, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, + -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 361, 362, 363, 364, 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, -1, 387, 388, 389, 390, + 381, 382, 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, - 411, 412, 413, -1, 415, 416, -1, -1, 419, 420, + 401, 402, 403, -1, 405, 406, -1, 408, 409, 410, + 411, 412, 413, 414, -1, 416, 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, - 431, 432, -1, -1, 435, 436, 437, 438, 439, 440, - -1, 442, 443, 444, 445, 446, 447, 448, -1, 450, - 451, 452, 453, 454, 455, 456, -1, -1, 459, -1, - -1, 462, 463, 464, 465, 466, 467, 468, 469, 470, + 431, 432, 433, -1, -1, 436, 437, 438, 439, 440, + 441, 442, -1, 444, 445, 446, 447, 448, 449, 450, + -1, 452, 453, 454, 455, 456, 457, 458, -1, -1, + 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 483, -1, -1, -1, -1, -1, -1, 490, - 491, -1, -1, -1, -1, -1, 497, -1, 499, -1, - -1, -1, -1, 504, 505, 506, 3, 4, 5, 6, + 481, 482, 483, 484, 485, -1, -1, -1, -1, -1, + -1, 492, 493, -1, -1, -1, -1, -1, 499, -1, + 501, -1, -1, -1, -1, 506, 507, 508, 509, 3, + 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, + 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, + -1, -1, -1, 37, -1, -1, 40, 41, -1, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, -1, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, -1, 70, 71, 72, 73, + 74, -1, 76, -1, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, + 94, -1, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, -1, 120, 121, 122, 123, + 124, 125, -1, 127, 128, 129, 130, 131, -1, -1, + 134, 135, 136, 137, 138, -1, 140, 141, 142, -1, + 144, 145, 146, -1, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, 159, 160, -1, 162, 163, + 164, 165, -1, 167, -1, 169, 170, -1, 172, 173, + 174, 175, 176, 177, -1, 179, -1, 181, 182, 183, + -1, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 194, 195, 196, -1, 198, 199, 200, 201, 202, 203, + -1, 205, 206, 207, 208, 209, 210, 211, 212, 213, + 214, -1, 216, -1, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, -1, -1, 231, 232, 233, + 234, -1, 236, 237, 238, 239, 240, 241, 242, 243, + 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, + -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, + 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, 306, 307, 308, 309, -1, 311, 312, 313, + 314, 315, 316, 317, 318, 319, 320, -1, 322, 323, + 324, 325, 326, 327, -1, 329, 330, 331, 332, 333, + 334, 335, 336, -1, 338, 339, 340, 341, 342, 343, + 344, 345, 346, 347, 348, 349, 350, -1, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, + 364, 365, 366, 367, 368, 369, -1, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, + 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, + -1, 405, 406, -1, 408, 409, 410, 411, 412, 413, + 414, -1, 416, 417, -1, -1, 420, 421, 422, 423, + 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, + -1, -1, 436, 437, 438, 439, 440, 441, 442, -1, + 444, 445, 446, 447, 448, 449, 450, -1, 452, 453, + 454, 455, 456, 457, 458, -1, -1, 461, -1, -1, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, + 484, 485, -1, -1, -1, -1, -1, -1, 492, 493, + -1, -1, -1, -1, -1, 499, -1, 501, -1, -1, + -1, -1, 506, 507, 508, 509, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, @@ -305199,7 +319758,7 @@ static const yytype_int16 yycheck[] = 87, -1, 89, 90, 91, 92, 93, 94, -1, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, -1, 120, 121, 122, 123, 124, 125, -1, + -1, 118, -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, 156, @@ -305214,30 +319773,81 @@ static const yytype_int16 yycheck[] = 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 267, 268, 269, 270, 271, -1, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, 316, - 317, 318, 319, -1, 321, 322, 323, 324, 325, 326, - -1, 328, 329, 330, 331, 332, 333, 334, 335, -1, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, 356, + 317, 318, 319, 320, -1, 322, 323, 324, 325, 326, + 327, -1, 329, 330, 331, 332, 333, 334, 335, 336, + -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - 367, 368, -1, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, 381, 382, 383, 384, 385, -1, - 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, - 397, 398, 399, 400, 401, 402, -1, 404, 405, 406, - 407, 408, 409, 410, 411, 412, 413, -1, 415, 416, - -1, -1, 419, 420, 421, 422, 423, 424, 425, 426, - 427, 428, 429, 430, 431, 432, -1, -1, 435, 436, - 437, 438, 439, 440, -1, 442, 443, 444, 445, 446, - 447, 448, -1, 450, 451, 452, 453, 454, 455, 456, - -1, -1, 459, -1, -1, 462, 463, 464, 465, 466, + 367, 368, 369, -1, 371, 372, 373, 374, 375, 376, + 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, + -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, -1, 405, 406, + -1, 408, 409, 410, 411, 412, 413, 414, -1, 416, + 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, + 427, 428, 429, 430, 431, 432, 433, -1, -1, 436, + 437, 438, 439, 440, 441, 442, -1, 444, 445, 446, + 447, 448, 449, 450, -1, 452, 453, 454, 455, 456, + 457, 458, -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 483, -1, -1, -1, - -1, -1, -1, 490, 491, -1, -1, -1, -1, -1, - 497, -1, 499, -1, -1, -1, -1, 504, 505, 506, + 477, 478, 479, 480, 481, 482, 483, 484, -1, -1, + -1, -1, -1, -1, -1, 492, 493, -1, -1, -1, + -1, -1, 499, -1, 501, -1, -1, -1, -1, 506, + 507, 508, 509, 3, 4, 5, 6, 7, -1, 9, + 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, + 30, 31, 32, -1, -1, -1, -1, 37, -1, -1, + 40, 41, -1, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, -1, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, -1, + 70, 71, 72, 73, 74, -1, 76, -1, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, + 90, 91, 92, 93, 94, -1, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, -1, 118, -1, + 120, 121, 122, 123, 124, 125, -1, 127, 128, 129, + 130, 131, -1, -1, 134, 135, 136, 137, 138, -1, + 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, -1, 162, 163, 164, 165, -1, 167, -1, 169, + 170, -1, 172, 173, 174, 175, 176, 177, -1, 179, + -1, 181, 182, 183, -1, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, -1, 198, 199, + 200, 201, 202, 203, -1, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, -1, 216, -1, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, -1, + -1, 231, 232, 233, 234, -1, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, -1, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, -1, 285, 286, -1, -1, 289, + 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + -1, 311, 312, 313, 314, 315, 316, 317, 318, 319, + 320, -1, 322, 323, 324, 325, 326, 327, -1, 329, + 330, 331, 332, 333, 334, 335, 336, -1, 338, 339, + 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, + 350, -1, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, + -1, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 380, 381, 382, 383, 384, 385, 386, -1, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, + 400, 401, 402, 403, -1, 405, 406, -1, 408, 409, + 410, 411, 412, 413, 414, -1, 416, 417, -1, -1, + 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, + 430, 431, 432, 433, -1, -1, 436, 437, 438, 439, + 440, 441, 442, -1, 444, 445, 446, 447, 448, 449, + 450, -1, 452, 453, 454, 455, 456, 457, 458, -1, + -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, + 480, 481, 482, 483, 484, -1, -1, -1, -1, -1, + -1, -1, 492, 493, -1, -1, -1, -1, -1, 499, + -1, 501, -1, -1, -1, -1, 506, 507, 508, 509, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, @@ -305249,7 +319859,7 @@ static const yytype_int16 yycheck[] = 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, -1, 120, 121, 122, + 113, 114, 115, 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, 151, 152, @@ -305259,41 +319869,92 @@ static const yytype_int16 yycheck[] = 183, -1, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, 206, 207, 208, 209, 210, 211, 212, - 213, 214, -1, 216, -1, 218, 219, 220, 221, 222, + 213, 214, -1, 216, -1, 218, -1, 220, 221, 222, 223, 224, 225, 226, 227, 228, -1, -1, 231, 232, 233, 234, -1, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, - 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 263, 264, 265, 266, 267, 268, 269, 270, 271, -1, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, - 313, 314, 315, 316, 317, 318, 319, -1, 321, 322, - 323, 324, 325, 326, -1, 328, 329, 330, 331, 332, - 333, 334, 335, -1, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, + 313, 314, 315, 316, 317, 318, 319, 320, -1, 322, + 323, 324, 325, 326, 327, -1, 329, 330, 331, 332, + 333, 334, 335, 336, -1, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, -1, 370, 371, 372, + 363, 364, 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, -1, 387, 388, 389, 390, 391, 392, + 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, - -1, 404, 405, -1, 407, 408, 409, 410, 411, 412, - 413, -1, 415, 416, -1, -1, 419, 420, 421, 422, + 403, -1, 405, 406, -1, 408, 409, 410, 411, 412, + 413, 414, -1, 416, 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, - -1, -1, 435, 436, 437, 438, 439, 440, -1, 442, - 443, 444, 445, 446, 447, 448, -1, 450, 451, 452, - 453, 454, 455, 456, -1, -1, 459, -1, -1, 462, - 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 433, -1, -1, 436, 437, 438, 439, 440, 441, 442, + -1, 444, 445, 446, 447, 448, 449, 450, -1, 452, + 453, 454, 455, 456, 457, 458, -1, -1, 461, -1, + -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 483, -1, -1, -1, -1, -1, -1, 490, 491, -1, - -1, -1, -1, -1, 497, -1, 499, -1, -1, -1, - -1, 504, 505, 506, 3, 4, 5, 6, 7, 8, + 483, 484, -1, -1, -1, -1, -1, -1, -1, 492, + 493, -1, -1, -1, -1, -1, 499, -1, 501, -1, + -1, -1, -1, 506, 507, 508, 509, 3, 4, 5, + 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, + 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, + -1, 37, -1, -1, 40, 41, -1, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, -1, + 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, + 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, -1, 120, 121, 122, 123, 124, 125, + -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, + 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, + 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 157, 158, 159, 160, -1, 162, 163, 164, 165, + -1, 167, -1, 169, 170, -1, 172, 173, 174, 175, + 176, 177, -1, 179, -1, 181, 182, 183, -1, 185, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, + 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, -1, + 216, -1, 218, -1, -1, 221, 222, 223, 224, 225, + 226, 227, 228, -1, -1, 231, 232, 233, 234, -1, + 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, + 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, + 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, + 266, 267, 268, 269, 270, 271, -1, 273, 274, -1, + 276, 277, 278, 279, 280, 281, 282, 283, -1, 285, + 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, + 316, 317, 318, 319, 320, -1, 322, 323, 324, 325, + 326, 327, -1, 329, 330, 331, 332, 333, 334, 335, + 336, -1, 338, 339, 340, 341, 342, 343, 344, 345, + 346, 347, 348, 349, 350, -1, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, + 366, 367, 368, 369, -1, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, + 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 403, -1, 405, + 406, -1, 408, 409, 410, 411, 412, 413, 414, -1, + 416, 417, -1, -1, 420, 421, 422, 423, 424, 425, + 426, 427, 428, 429, 430, 431, 432, 433, -1, -1, + 436, 437, 438, 439, 440, 441, 442, -1, 444, 445, + 446, 447, 448, 449, 450, -1, 452, 453, 454, 455, + 456, 457, 458, -1, -1, 461, -1, -1, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, + -1, -1, -1, -1, -1, -1, 492, 493, -1, -1, + -1, -1, -1, 499, -1, 501, -1, -1, -1, -1, + 506, 507, 508, 509, 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, 37, -1, -1, 40, 41, -1, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, -1, 56, 57, 58, + 49, -1, 51, 52, 53, 54, -1, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, @@ -305302,105 +319963,150 @@ static const yytype_int16 yycheck[] = 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, - -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, + -1, 140, 141, 142, -1, 144, -1, 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, -1, 162, 163, 164, 165, -1, 167, -1, - 169, 170, -1, 172, 173, 174, 175, 176, 177, -1, + 169, 170, -1, 172, 173, 174, 175, -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, -1, 198, + 189, 190, 191, -1, 193, 194, 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, -1, 216, -1, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - -1, -1, 231, 232, 233, 234, -1, 236, 237, 238, + -1, -1, 221, 222, 223, 224, 225, 226, 227, 228, + -1, -1, 231, 232, 233, -1, -1, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 269, 270, 271, -1, 273, 274, -1, 276, 277, 278, 279, 280, 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, 316, 317, 318, - 319, -1, 321, 322, 323, 324, 325, 326, -1, 328, - 329, 330, 331, 332, 333, 334, 335, -1, 337, 338, + 319, 320, -1, 322, 323, 324, 325, 326, 327, -1, + 329, 330, 331, 332, 333, 334, 335, 336, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, 356, 357, 358, + 349, 350, -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, - -1, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, -1, 387, 388, + 369, -1, 371, 372, 373, 374, 375, 376, 377, 378, + 379, 380, 381, -1, 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 402, -1, 404, 405, -1, 407, 408, - 409, 410, 411, 412, 413, -1, 415, 416, -1, -1, - 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, - 429, 430, 431, 432, -1, -1, 435, 436, 437, 438, - 439, 440, -1, 442, 443, 444, 445, 446, 447, 448, - -1, 450, 451, 452, 453, 454, 455, 456, -1, -1, - 459, -1, -1, 462, 463, 464, 465, 466, 467, 468, + 399, 400, 401, 402, 403, -1, 405, 406, -1, 408, + 409, 410, 411, 412, 413, 414, -1, 416, 417, -1, + -1, 420, 421, 422, 423, 424, 425, 426, 427, 428, + 429, 430, 431, 432, 433, -1, -1, 436, 437, 438, + 439, 440, 441, 442, -1, 444, 445, 446, 447, 448, + 449, 450, -1, 452, 453, 454, 455, 456, 457, 458, + -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, -1, -1, -1, -1, -1, - -1, 490, 491, -1, -1, -1, -1, -1, 497, -1, - 499, -1, -1, -1, -1, 504, 505, 506, 3, 4, - 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, - 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, - -1, -1, 37, -1, -1, 40, 41, -1, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - -1, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, - -1, 76, -1, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, - -1, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, -1, 120, 121, 122, 123, 124, - 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, - 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, - 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, -1, 162, 163, 164, - 165, -1, 167, -1, 169, 170, -1, 172, 173, 174, - 175, 176, 177, -1, 179, -1, 181, 182, 183, -1, - 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, - 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, - 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, - -1, 216, -1, 218, 219, 220, 221, 222, 223, 224, - 225, 226, 227, 228, -1, -1, 231, 232, 233, 234, - -1, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, -1, - 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, -1, 311, 312, 313, 314, - 315, 316, 317, 318, 319, -1, 321, 322, 323, 324, - 325, 326, -1, 328, 329, 330, 331, 332, 333, 334, - 335, -1, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, -1, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, -1, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, -1, 404, - 405, -1, 407, 408, 409, 410, 411, 412, 413, -1, - 415, 416, -1, -1, 419, 420, 421, 422, 423, 424, - 425, 426, 427, 428, 429, 430, 431, 432, -1, -1, - 435, 436, 437, 438, 439, 440, -1, 442, 443, 444, - 445, 446, 447, 448, -1, 450, 451, 452, 453, 454, - 455, 456, -1, -1, 459, -1, -1, 462, 463, 464, - 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 483, -1, - -1, -1, -1, -1, -1, 490, 491, -1, -1, -1, - -1, -1, 497, -1, 499, -1, -1, -1, -1, 504, - 505, 506, 3, 4, 5, 6, 7, 8, 9, 10, + 479, 480, 481, 482, 483, 484, -1, -1, -1, -1, + -1, -1, -1, 492, 493, 3, -1, -1, -1, -1, + 499, -1, 501, -1, -1, -1, -1, 506, 507, 508, + 509, -1, -1, 21, 22, 23, 24, 25, 26, 27, + 28, -1, 30, 31, 32, -1, -1, -1, -1, -1, + 38, -1, 40, 41, -1, 43, 44, 45, -1, 47, + 48, 49, 50, 51, -1, 53, 54, -1, 56, 57, + 58, 59, 60, 61, -1, -1, 64, 65, 66, 67, + 68, -1, 70, 71, 72, 73, 74, -1, -1, -1, + 78, 79, 80, 81, 82, 83, -1, 85, 86, 87, + -1, 89, 90, 91, 92, 93, 94, -1, -1, 97, + 98, 99, -1, -1, -1, -1, -1, -1, -1, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, -1, + 118, -1, 120, 121, 122, 123, 124, 125, -1, 127, + 128, 129, 130, 131, -1, -1, 134, 135, 136, 137, + 138, -1, 140, 141, 142, -1, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, -1, 160, 161, 162, 163, 164, 165, 166, 167, + -1, 169, -1, -1, -1, 173, 174, 175, -1, 177, + -1, 179, -1, 181, 182, 183, -1, 185, 186, 187, + 188, 189, 190, 191, -1, 193, 194, 195, 196, -1, + 198, 199, 200, 201, 202, 203, -1, 205, -1, 207, + 208, 209, 210, 211, 212, 213, 214, 215, 216, -1, + 218, -1, -1, 221, -1, 223, 224, 225, 226, 227, + 228, -1, -1, 231, -1, 233, -1, 235, 236, 237, + 238, -1, -1, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, -1, 267, + 268, 269, 270, 271, -1, 273, 274, -1, 276, -1, + 278, 279, 280, 281, 282, 283, 284, 285, 286, -1, + -1, 289, 290, 291, -1, 293, 294, 295, -1, 297, + -1, 299, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, -1, 311, 312, 313, -1, 315, 316, 317, + 318, 319, 320, -1, 322, 323, 324, 325, 326, 327, + -1, 329, 330, 331, 332, 333, 334, 335, 336, -1, + 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, + 348, 349, 350, -1, 352, 353, -1, 355, 356, 357, + 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, + 368, 369, -1, 371, 372, 373, 374, 375, -1, 377, + 378, 379, 380, 381, -1, 383, 384, 385, 386, -1, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, -1, 405, 406, -1, + 408, -1, 410, 411, 412, 413, 414, -1, 416, 417, + -1, -1, 420, 421, 422, 423, 424, -1, 426, 427, + 428, 429, 430, 431, 432, 433, 434, -1, 436, 437, + 438, 439, 440, 441, -1, -1, 444, 445, 446, 447, + 448, 449, 450, -1, 452, -1, 454, 455, 456, 457, + 458, -1, -1, 461, -1, -1, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, + 478, 479, 480, 481, 482, 483, 484, 3, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 502, 21, 22, 23, 24, 25, + 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, + -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, -1, + 56, 57, 58, 59, 60, 61, -1, 63, 64, 65, + 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, + 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, + 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, + -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, + 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, + 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, + 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, + -1, 167, -1, 169, 170, 171, 172, 173, 174, 175, + 176, 177, -1, 179, -1, 181, 182, 183, -1, 185, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, + 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, + 206, 207, 208, 209, 210, 211, 212, 213, 214, -1, + 216, -1, 218, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 228, 229, -1, 231, 232, 233, 234, -1, + 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, + 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, + 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, + 266, 267, 268, 269, 270, 271, -1, 273, 274, 275, + 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, + 286, -1, 288, 289, 290, 291, -1, -1, 294, 295, + 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, + 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, + 316, 317, 318, 319, 320, -1, 322, 323, 324, 325, + 326, 327, -1, 329, 330, 331, 332, 333, 334, 335, + 336, -1, 338, 339, 340, 341, 342, 343, 344, 345, + 346, 347, 348, 349, 350, -1, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, + 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 403, -1, 405, + 406, 407, 408, 409, 410, 411, 412, 413, 414, -1, + 416, 417, -1, -1, 420, 421, 422, 423, 424, -1, + 426, 427, 428, 429, 430, 431, 432, 433, -1, -1, + 436, 437, 438, 439, 440, 441, 442, -1, 444, 445, + 446, 447, 448, 449, 450, -1, 452, 453, 454, 455, + 456, 457, 458, -1, -1, 461, -1, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 476, 477, 478, 479, 480, 481, 482, 483, 484, -1, + -1, 487, 3, 4, 5, -1, -1, -1, 9, -1, + -1, -1, -1, -1, -1, 501, -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, - 31, 32, -1, -1, -1, -1, 37, -1, -1, 40, + 31, 32, -1, -1, -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, -1, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, -1, 70, + 61, -1, -1, 64, 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, 117, 118, -1, 120, + 101, 102, 103, -1, -1, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, @@ -305412,201 +320118,144 @@ static const yytype_int16 yycheck[] = 201, 202, 203, -1, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, -1, 216, -1, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, -1, -1, - 231, 232, 233, 234, -1, 236, 237, 238, 239, 240, + 231, 232, 233, 234, -1, 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, - 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, + 271, -1, 273, 274, 275, 276, -1, 278, 279, 280, + 281, 282, 283, -1, 285, 286, 287, -1, 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, - 311, 312, 313, 314, 315, 316, 317, 318, 319, -1, - 321, 322, 323, 324, 325, 326, -1, 328, 329, 330, - 331, 332, 333, 334, 335, -1, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, -1, 370, + 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, + -1, 322, 323, 324, 325, 326, 327, -1, 329, 330, + 331, 332, 333, 334, 335, 336, -1, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, + -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 361, 362, 363, 364, 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, -1, 387, 388, 389, 390, + 381, 382, 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, -1, 404, 405, -1, 407, 408, 409, 410, - 411, 412, 413, -1, 415, 416, -1, -1, 419, 420, + 401, 402, 403, -1, 405, 406, -1, 408, 409, 410, + 411, 412, 413, 414, -1, 416, 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, - 431, 432, -1, -1, 435, 436, 437, 438, 439, 440, - -1, 442, 443, 444, 445, 446, 447, 448, -1, 450, - 451, 452, 453, 454, 455, 456, -1, -1, 459, -1, - -1, 462, 463, 464, 465, 466, 467, 468, 469, 470, + 431, 432, 433, -1, -1, 436, 437, 438, 439, 440, + 441, 442, -1, 444, 445, 446, 447, 448, 449, 450, + -1, 452, 453, 454, 455, 456, 457, 458, -1, -1, + 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 483, -1, -1, -1, -1, -1, -1, 490, - 491, -1, -1, -1, -1, -1, 497, -1, 499, -1, - -1, -1, -1, 504, 505, 506, 3, 4, 5, 6, - 7, 8, 9, 10, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, - 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, - 37, -1, -1, 40, 41, -1, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, -1, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, -1, 70, 71, 72, 73, 74, -1, 76, - -1, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, -1, 89, 90, 91, 92, 93, 94, -1, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, -1, 120, 121, 122, 123, 124, 125, -1, - 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, - 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, - -1, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, -1, 162, 163, 164, 165, -1, - 167, -1, 169, 170, -1, 172, 173, 174, 175, 176, - 177, -1, 179, -1, 181, 182, 183, -1, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - -1, 198, 199, 200, 201, 202, 203, -1, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, -1, 216, - -1, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, -1, -1, 231, 232, 233, 234, -1, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, -1, 285, 286, - -1, -1, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, - 307, 308, 309, -1, 311, 312, 313, 314, 315, 316, - 317, 318, 319, -1, 321, 322, 323, 324, 325, 326, - -1, 328, 329, 330, 331, 332, 333, 334, 335, -1, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, 356, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - 367, 368, -1, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, 381, 382, 383, 384, 385, -1, - 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, - 397, 398, 399, 400, 401, 402, -1, 404, 405, -1, - 407, 408, 409, 410, 411, 412, 413, -1, 415, 416, - -1, -1, 419, 420, 421, 422, 423, 424, 425, 426, - 427, 428, 429, 430, 431, 432, -1, -1, 435, 436, - 437, 438, 439, 440, -1, 442, 443, 444, 445, 446, - 447, 448, -1, 450, 451, 452, 453, 454, 455, 456, - -1, -1, 459, -1, -1, 462, 463, 464, 465, 466, - 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 483, -1, -1, -1, - -1, -1, -1, 490, 491, -1, -1, -1, -1, -1, - 497, -1, 499, -1, -1, -1, -1, 504, 505, 506, - 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, - 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, - -1, -1, -1, -1, 37, -1, -1, 40, 41, -1, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, -1, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, -1, 70, 71, 72, - 73, 74, -1, 76, -1, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, - 93, 94, -1, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, -1, 120, 121, 122, - 123, 124, 125, -1, 127, 128, 129, 130, 131, -1, - -1, 134, 135, 136, 137, 138, -1, 140, 141, 142, - -1, 144, 145, 146, -1, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, 158, 159, 160, -1, 162, - 163, 164, 165, -1, 167, -1, 169, 170, -1, 172, - 173, 174, 175, 176, 177, -1, 179, -1, 181, 182, - 183, -1, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, -1, 198, 199, 200, 201, 202, - 203, -1, 205, 206, 207, 208, 209, 210, 211, 212, - 213, 214, -1, 216, -1, 218, 219, 220, 221, 222, - 223, 224, 225, 226, 227, 228, -1, -1, 231, 232, - 233, 234, -1, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, - 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, - -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, - 313, 314, 315, 316, 317, 318, 319, -1, 321, 322, - 323, 324, 325, 326, -1, 328, 329, 330, 331, 332, - 333, 334, 335, -1, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, -1, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, -1, 387, 388, 389, 390, 391, 392, - 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, - -1, 404, 405, -1, 407, 408, 409, 410, 411, 412, - 413, -1, 415, 416, -1, -1, 419, 420, 421, 422, - 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, - -1, -1, 435, 436, 437, 438, 439, 440, -1, 442, - 443, 444, 445, 446, 447, 448, -1, 450, 451, 452, - 453, 454, 455, 456, -1, -1, 459, -1, -1, 462, - 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 483, -1, -1, -1, -1, -1, -1, 490, 491, -1, - -1, -1, -1, -1, 497, -1, 499, -1, -1, -1, - -1, 504, 505, 506, 3, 4, 5, 6, 7, 8, - 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, - -1, 30, 31, 32, -1, -1, -1, -1, 37, -1, + 481, 482, 483, 484, 3, -1, 5, -1, -1, -1, + -1, 492, 493, 494, -1, -1, -1, -1, -1, -1, + 501, -1, 21, 22, 23, 24, 25, 26, 27, 28, + -1, 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, -1, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 59, 60, 61, -1, 63, 64, 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 109, 110, 111, 112, 113, 114, 115, 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, -1, 162, 163, 164, 165, -1, 167, -1, + -1, 160, -1, 162, 163, 164, 165, -1, 167, -1, 169, 170, -1, 172, 173, 174, 175, 176, 177, -1, 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, -1, 216, -1, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - -1, -1, 231, 232, 233, 234, -1, 236, 237, 238, + 229, -1, 231, 232, 233, 234, -1, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, -1, 285, 286, -1, -1, + 269, 270, 271, -1, 273, 274, 275, 276, -1, 278, + 279, 280, 281, 282, 283, -1, 285, 286, -1, 288, 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, 316, 317, 318, - 319, -1, 321, 322, 323, 324, 325, 326, -1, 328, - 329, 330, 331, 332, 333, 334, 335, -1, 337, 338, + 319, 320, -1, 322, 323, 324, 325, 326, 327, -1, + 329, 330, 331, 332, 333, 334, 335, 336, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, 356, 357, 358, + 349, 350, -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, - -1, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, -1, 387, 388, + 369, -1, 371, 372, 373, 374, 375, 376, 377, 378, + 379, 380, 381, 382, 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 402, -1, 404, 405, -1, 407, 408, - 409, 410, 411, 412, 413, -1, 415, 416, -1, -1, - 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, - 429, 430, 431, 432, -1, -1, 435, 436, 437, 438, - 439, 440, -1, 442, 443, 444, 445, 446, 447, 448, - -1, 450, 451, 452, 453, 454, 455, 456, -1, -1, - 459, -1, -1, 462, 463, 464, 465, 466, 467, 468, + 399, 400, 401, 402, 403, -1, 405, 406, -1, 408, + 409, 410, 411, 412, 413, 414, -1, 416, 417, -1, + -1, 420, 421, 422, 423, 424, -1, 426, 427, 428, + 429, 430, 431, 432, 433, -1, -1, 436, 437, 438, + 439, 440, 441, 442, -1, 444, 445, 446, 447, 448, + 449, 450, -1, 452, 453, 454, 455, 456, 457, 458, + -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, -1, -1, -1, -1, -1, - -1, 490, 491, -1, -1, -1, -1, -1, 497, -1, - 499, -1, -1, -1, -1, 504, 505, 506, 3, 4, - 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, + 479, 480, 481, 482, 483, 484, 3, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 501, -1, 21, 22, 23, 24, 25, 26, + 27, 28, -1, 30, 31, 32, 33, 34, -1, -1, + -1, -1, -1, 40, 41, -1, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, -1, 56, + 57, 58, 59, 60, 61, -1, -1, 64, 65, 66, + 67, 68, -1, 70, 71, 72, 73, 74, -1, 76, + -1, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, -1, 89, 90, 91, 92, 93, 94, -1, 96, + 97, 98, 99, 100, 101, 102, 103, -1, -1, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + -1, 118, -1, 120, 121, 122, 123, 124, 125, -1, + 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, + 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, + -1, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, -1, 160, -1, 162, 163, 164, 165, -1, + 167, -1, 169, 170, 171, 172, 173, 174, 175, 176, + 177, -1, 179, -1, 181, 182, 183, -1, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + -1, 198, 199, 200, 201, 202, 203, -1, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, -1, 216, + -1, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, -1, -1, 231, 232, 233, 234, -1, 236, + 237, 238, -1, -1, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, -1, 273, 274, 275, 276, + -1, 278, 279, 280, 281, 282, 283, -1, 285, 286, + -1, -1, 289, 290, 291, -1, -1, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, -1, 311, 312, 313, 314, 315, 316, + 317, 318, 319, 320, -1, 322, 323, 324, 325, 326, + 327, -1, 329, 330, 331, 332, 333, 334, 335, 336, + -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, -1, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, + 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, + 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, + -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, -1, 405, 406, + 407, 408, 409, 410, 411, 412, 413, 414, -1, 416, + 417, -1, -1, 420, 421, 422, 423, 424, -1, 426, + 427, 428, 429, 430, 431, 432, 433, -1, -1, 436, + 437, 438, 439, 440, 441, 442, -1, 444, 445, 446, + 447, 448, 449, 450, -1, 452, 453, 454, 455, 456, + 457, 458, -1, -1, 461, -1, 463, 464, 465, 466, + 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, + 477, 478, 479, 480, 481, 482, 483, 484, 3, -1, + 487, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 501, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, - -1, -1, 37, -1, -1, 40, 41, -1, 43, 44, + -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - -1, 56, 57, 58, 59, 60, 61, 62, 63, 64, + -1, 56, 57, 58, 59, 60, 61, -1, 63, 64, 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, -1, 120, 121, 122, 123, 124, + 115, 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, -1, 162, 163, 164, + 155, 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, -1, 167, -1, 169, 170, -1, 172, 173, 174, 175, 176, 177, -1, 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, @@ -305617,137 +320266,34 @@ static const yytype_int16 yycheck[] = -1, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, -1, + 265, 266, 267, 268, 269, 270, 271, -1, 273, 274, + 275, 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, 313, 314, - 315, 316, 317, 318, 319, -1, 321, 322, 323, 324, - 325, 326, -1, 328, 329, 330, 331, 332, 333, 334, - 335, -1, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, + 315, 316, 317, 318, 319, 320, -1, 322, 323, 324, + 325, 326, 327, -1, 329, 330, 331, 332, 333, 334, + 335, 336, -1, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, -1, 370, 371, 372, 373, 374, + 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, -1, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, -1, 404, - 405, -1, 407, 408, 409, 410, 411, 412, 413, -1, - 415, 416, -1, -1, 419, 420, 421, 422, 423, 424, - 425, 426, 427, 428, 429, 430, 431, 432, -1, -1, - 435, 436, 437, 438, 439, 440, -1, 442, 443, 444, - 445, 446, 447, 448, -1, 450, 451, 452, 453, 454, - 455, 456, -1, -1, 459, -1, -1, 462, 463, 464, + 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, -1, + 405, 406, -1, 408, 409, 410, 411, 412, 413, 414, + -1, 416, 417, -1, -1, 420, 421, 422, 423, 424, + -1, 426, 427, 428, 429, 430, 431, 432, 433, -1, + -1, 436, 437, 438, 439, 440, 441, 442, -1, 444, + 445, 446, 447, 448, 449, 450, -1, 452, 453, 454, + 455, 456, 457, 458, -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 483, -1, - -1, -1, -1, -1, -1, 490, 491, -1, -1, -1, - -1, -1, 497, -1, 499, -1, -1, -1, -1, 504, - 505, 506, 3, 4, 5, 6, 7, 8, 9, 10, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, - 31, 32, -1, -1, -1, -1, 37, -1, -1, 40, - 41, -1, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, -1, 56, 57, 58, 59, 60, - 61, 62, 63, 64, 65, 66, 67, 68, -1, 70, - 71, 72, 73, 74, -1, 76, -1, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, -1, 89, 90, - 91, 92, 93, 94, -1, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, -1, 118, -1, 120, - 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, - 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, - 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, - -1, 162, 163, 164, 165, -1, 167, -1, 169, 170, - -1, 172, 173, 174, 175, 176, 177, -1, 179, -1, - 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, - 191, 192, 193, 194, 195, 196, -1, 198, 199, 200, - 201, 202, 203, -1, 205, 206, 207, 208, 209, 210, - 211, 212, 213, 214, -1, 216, -1, 218, 219, 220, - 221, 222, 223, 224, 225, 226, 227, 228, -1, -1, - 231, 232, 233, 234, -1, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, -1, 273, 274, 275, 276, 277, 278, 279, 280, - 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, - 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, - 311, 312, 313, 314, 315, 316, 317, 318, 319, -1, - 321, 322, 323, 324, 325, 326, -1, 328, 329, 330, - 331, 332, 333, 334, 335, -1, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, -1, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, -1, 387, 388, 389, 390, - 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, -1, 404, 405, -1, 407, 408, 409, 410, - 411, 412, 413, -1, 415, 416, -1, -1, 419, 420, - 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, - 431, 432, -1, -1, 435, 436, 437, 438, 439, 440, - -1, 442, 443, 444, 445, 446, 447, 448, -1, 450, - 451, 452, 453, 454, 455, 456, -1, -1, 459, -1, - -1, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, -1, -1, -1, -1, -1, -1, -1, 490, - 491, -1, -1, -1, -1, -1, 497, -1, 499, -1, - -1, -1, -1, 504, 505, 506, 3, 4, 5, 6, - 7, -1, 9, 10, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, - 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, - 37, -1, -1, 40, 41, -1, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, -1, 56, - 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, - 67, 68, -1, 70, 71, 72, 73, 74, -1, 76, - -1, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, -1, 89, 90, 91, 92, 93, 94, -1, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - -1, 118, -1, 120, 121, 122, 123, 124, 125, -1, - 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, - 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, - -1, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, -1, 162, 163, 164, 165, -1, - 167, -1, 169, 170, -1, 172, 173, 174, 175, 176, - 177, -1, 179, -1, 181, 182, 183, -1, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - -1, 198, 199, 200, 201, 202, 203, -1, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, -1, 216, - -1, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, -1, -1, 231, 232, 233, 234, -1, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, -1, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, -1, 285, 286, - -1, -1, 289, 290, 291, -1, -1, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, - 307, 308, 309, -1, 311, 312, 313, 314, 315, 316, - 317, 318, 319, -1, 321, 322, 323, 324, 325, 326, - -1, 328, 329, 330, 331, 332, 333, 334, 335, -1, - 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, - 347, 348, 349, -1, 351, 352, 353, 354, 355, 356, - 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, - 367, 368, -1, 370, 371, 372, 373, 374, 375, 376, - 377, 378, 379, 380, 381, 382, 383, 384, 385, -1, - 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, - 397, 398, 399, 400, 401, 402, -1, 404, 405, -1, - 407, 408, 409, 410, 411, 412, 413, -1, 415, 416, - -1, -1, 419, 420, 421, 422, 423, 424, 425, 426, - 427, 428, 429, 430, 431, 432, -1, -1, 435, 436, - 437, 438, 439, 440, -1, 442, 443, 444, 445, 446, - 447, 448, -1, 450, 451, 452, 453, 454, 455, 456, - -1, -1, 459, -1, -1, 462, 463, 464, 465, 466, - 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, -1, -1, -1, -1, - -1, -1, -1, 490, 491, -1, -1, -1, -1, -1, - 497, -1, 499, -1, -1, -1, -1, 504, 505, 506, - 3, 4, 5, 6, 7, 8, 9, 10, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, + 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 501, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, - -1, -1, -1, -1, 37, -1, -1, 40, 41, -1, + -1, -1, -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, -1, 56, 57, 58, 59, 60, 61, 62, + 53, 54, -1, 56, 57, 58, 59, 60, 61, -1, 63, 64, 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, @@ -305757,527 +320303,138 @@ static const yytype_int16 yycheck[] = 123, 124, 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, 158, 159, 160, -1, 162, + 153, 154, 155, 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, -1, 167, -1, 169, 170, -1, 172, 173, 174, 175, 176, 177, -1, 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, 206, 207, 208, 209, 210, 211, 212, - 213, 214, -1, 216, -1, 218, -1, 220, 221, 222, + 213, 214, -1, 216, -1, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, -1, -1, 231, 232, 233, 234, -1, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, -1, - 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 273, 274, 275, 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, - 313, 314, 315, 316, 317, 318, 319, -1, 321, 322, - 323, 324, 325, 326, -1, 328, 329, 330, 331, 332, - 333, 334, 335, -1, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, -1, 351, 352, + 313, 314, 315, 316, 317, 318, 319, 320, -1, 322, + 323, 324, 325, 326, 327, -1, 329, 330, 331, 332, + 333, 334, 335, 336, -1, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, -1, 370, 371, 372, + 363, 364, 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, -1, 387, 388, 389, 390, 391, 392, + 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, - -1, 404, 405, -1, 407, 408, 409, 410, 411, 412, - 413, -1, 415, 416, -1, -1, 419, 420, 421, 422, - 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, - -1, -1, 435, 436, 437, 438, 439, 440, -1, 442, - 443, 444, 445, 446, 447, 448, -1, 450, 451, 452, - 453, 454, 455, 456, -1, -1, 459, -1, -1, 462, - 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 403, -1, 405, 406, -1, 408, 409, 410, 411, 412, + 413, 414, -1, 416, 417, -1, -1, 420, 421, 422, + 423, 424, -1, 426, 427, 428, 429, 430, 431, 432, + 433, -1, -1, 436, 437, 438, 439, 440, 441, 442, + -1, 444, 445, 446, 447, 448, 449, 450, -1, 452, + 453, 454, 455, 456, 457, 458, -1, -1, 461, -1, + -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - -1, -1, -1, -1, -1, -1, -1, 490, 491, -1, - -1, -1, -1, -1, 497, -1, 499, -1, -1, -1, - -1, 504, 505, 506, 3, 4, 5, 6, 7, 8, - 9, 10, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, - -1, 30, 31, 32, -1, -1, -1, -1, 37, -1, - -1, 40, 41, -1, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, -1, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, - -1, 70, 71, 72, 73, 74, -1, 76, -1, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, - 89, 90, 91, 92, 93, 94, -1, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 483, 484, 3, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 501, -1, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, -1, -1, -1, -1, -1, -1, -1, 40, + 41, -1, 43, 44, 45, -1, 47, 48, 49, 50, + 51, -1, 53, 54, -1, 56, 57, 58, 59, 60, + 61, -1, -1, 64, 65, 66, 67, 68, -1, 70, + 71, 72, 73, 74, -1, -1, -1, 78, 79, 80, + 81, 82, 83, -1, 85, 86, 87, -1, 89, 90, + 91, 92, 93, 94, -1, -1, 97, 98, 99, -1, + -1, -1, -1, -1, -1, -1, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, -1, 118, -1, 120, + 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, + 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, + 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, -1, 160, + -1, 162, 163, 164, 165, -1, 167, -1, 169, -1, + 171, -1, 173, 174, 175, -1, 177, -1, 179, -1, + 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, + 191, -1, 193, 194, 195, 196, -1, 198, 199, 200, + 201, 202, 203, -1, 205, -1, 207, 208, 209, 210, + 211, 212, 213, 214, -1, 216, -1, 218, -1, -1, + 221, -1, 223, 224, 225, 226, 227, 228, -1, -1, + 231, -1, 233, -1, -1, 236, 237, 238, -1, -1, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, -1, 267, 268, 269, 270, + 271, -1, 273, 274, -1, 276, -1, 278, 279, 280, + 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, + 291, -1, -1, 294, 295, -1, 297, -1, 299, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, + 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, + -1, 322, 323, 324, 325, 326, 327, -1, 329, 330, + 331, 332, 333, 334, 335, 336, -1, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, + -1, 352, 353, -1, 355, 356, 357, 358, 359, 360, + 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, + 371, 372, 373, 374, 375, -1, 377, 378, 379, 380, + 381, -1, 383, 384, 385, 386, -1, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, -1, 405, 406, 407, 408, -1, 410, + 411, 412, 413, 414, -1, 416, 417, -1, -1, 420, + 421, 422, 423, 424, -1, 426, 427, 428, 429, 430, + 431, 432, 433, -1, -1, 436, 437, 438, 439, 440, + 441, -1, -1, 444, 445, 446, 447, 448, 449, 450, + -1, 452, -1, 454, 455, 456, 457, 458, -1, -1, + 461, -1, 463, 464, 465, 466, 467, 468, 469, 470, + 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 3, -1, 487, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 501, -1, 21, 22, 23, 24, 25, 26, 27, 28, + -1, 30, 31, 32, -1, -1, -1, -1, -1, -1, + -1, 40, 41, -1, 43, 44, 45, -1, 47, 48, + 49, 50, 51, -1, 53, 54, -1, 56, 57, 58, + 59, 60, 61, -1, -1, 64, 65, 66, 67, 68, + -1, 70, 71, 72, 73, 74, -1, -1, -1, 78, + 79, 80, 81, 82, 83, -1, 85, 86, 87, -1, + 89, 90, 91, 92, 93, 94, -1, -1, 97, 98, + 99, -1, -1, -1, -1, -1, -1, -1, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, -1, 162, 163, 164, 165, -1, 167, -1, - 169, 170, -1, 172, 173, 174, 175, 176, 177, -1, + -1, 160, -1, 162, 163, 164, 165, -1, 167, -1, + 169, -1, 171, -1, 173, 174, 175, -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, -1, 198, - 199, 200, 201, 202, 203, -1, 205, 206, 207, 208, + 189, 190, 191, -1, 193, 194, 195, 196, -1, 198, + 199, 200, 201, 202, 203, -1, 205, -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, 216, -1, 218, - -1, -1, 221, 222, 223, 224, 225, 226, 227, 228, - -1, -1, 231, 232, 233, 234, -1, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, + -1, -1, 221, -1, 223, 224, 225, 226, 227, 228, + -1, -1, 231, -1, 233, -1, -1, 236, 237, 238, + -1, -1, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, -1, 273, 274, -1, 276, 277, 278, + 259, 260, 261, 262, 263, 264, 265, -1, 267, 268, + 269, 270, 271, -1, 273, 274, -1, 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, 286, -1, -1, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, + 289, 290, 291, -1, -1, 294, 295, -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, -1, 311, 312, 313, 314, 315, 316, 317, 318, - 319, -1, 321, 322, 323, 324, 325, 326, -1, 328, - 329, 330, 331, 332, 333, 334, 335, -1, 337, 338, + 309, -1, 311, 312, 313, -1, 315, 316, 317, 318, + 319, 320, -1, 322, 323, 324, 325, 326, 327, -1, + 329, 330, 331, 332, 333, 334, 335, 336, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, 356, 357, 358, + 349, 350, -1, 352, 353, -1, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, - -1, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, -1, 387, 388, + 369, 370, 371, 372, 373, 374, 375, -1, 377, 378, + 379, 380, 381, -1, 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 402, -1, 404, 405, -1, 407, 408, - 409, 410, 411, 412, 413, -1, 415, 416, -1, -1, - 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, - 429, 430, 431, 432, -1, -1, 435, 436, 437, 438, - 439, 440, -1, 442, 443, 444, 445, 446, 447, 448, - -1, 450, 451, 452, 453, 454, 455, 456, -1, -1, - 459, -1, -1, 462, 463, 464, 465, 466, 467, 468, + 399, 400, 401, 402, 403, -1, 405, 406, 407, 408, + -1, 410, 411, 412, 413, 414, -1, 416, 417, -1, + -1, 420, 421, 422, 423, 424, -1, 426, 427, 428, + 429, 430, 431, 432, 433, -1, -1, 436, 437, 438, + 439, 440, 441, -1, -1, 444, 445, 446, 447, 448, + 449, 450, -1, 452, -1, 454, 455, 456, 457, 458, + -1, -1, 461, -1, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 483, -1, -1, -1, -1, -1, - -1, 490, 491, -1, -1, -1, -1, -1, 497, -1, - 499, -1, -1, -1, -1, 504, 505, 506, 3, 4, - 5, 6, 7, 8, 9, 10, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, - 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, - -1, -1, 37, -1, -1, 40, 41, -1, 43, 44, - 45, 46, 47, 48, 49, -1, 51, 52, 53, 54, - -1, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, - -1, 76, -1, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, - -1, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, -1, 120, 121, 122, 123, 124, - 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, - 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, - -1, 146, -1, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, -1, 162, 163, 164, - 165, -1, 167, -1, 169, 170, -1, 172, 173, 174, - 175, -1, 177, -1, 179, -1, 181, 182, 183, -1, - 185, 186, 187, 188, 189, 190, 191, -1, 193, 194, - 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, - 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, - -1, 216, -1, 218, -1, -1, 221, 222, 223, 224, - 225, 226, 227, 228, -1, -1, 231, 232, 233, -1, - -1, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, -1, 273, 274, - -1, 276, 277, 278, 279, 280, 281, 282, 283, -1, - 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, -1, 311, 312, 313, 314, - 315, 316, 317, 318, 319, -1, 321, 322, 323, 324, - 325, 326, -1, 328, 329, 330, 331, 332, 333, 334, - 335, -1, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, -1, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, -1, 382, 383, 384, - 385, -1, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, -1, 404, - 405, -1, 407, 408, 409, 410, 411, 412, 413, -1, - 415, 416, -1, -1, 419, 420, 421, 422, 423, 424, - 425, 426, 427, 428, 429, 430, 431, 432, -1, -1, - 435, 436, 437, 438, 439, 440, -1, 442, 443, 444, - 445, 446, 447, 448, -1, 450, 451, 452, 453, 454, - 455, 456, -1, -1, 459, -1, -1, 462, 463, 464, - 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, -1, -1, - -1, -1, -1, -1, 3, 490, 491, -1, -1, -1, - -1, -1, 497, -1, 499, -1, -1, -1, -1, 504, - 505, 506, 21, 22, 23, 24, 25, 26, 27, 28, - -1, 30, 31, 32, -1, -1, -1, -1, -1, 38, - -1, 40, 41, -1, 43, 44, 45, -1, 47, 48, - 49, 50, 51, -1, 53, 54, -1, 56, 57, 58, - 59, 60, 61, -1, -1, 64, 65, 66, 67, 68, - -1, 70, 71, 72, 73, 74, -1, -1, -1, 78, - 79, 80, 81, 82, 83, -1, 85, 86, 87, -1, - 89, 90, 91, 92, 93, 94, -1, 96, 97, 98, - 99, -1, -1, -1, -1, -1, -1, -1, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, -1, 118, - -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, - 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, - -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - -1, 160, -1, 162, 163, 164, 165, -1, 167, -1, - 169, -1, -1, 172, 173, 174, 175, -1, 177, -1, - 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, - 189, 190, 191, -1, 193, 194, 195, 196, -1, 198, - 199, 200, 201, 202, 203, -1, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, -1, 216, -1, 218, - -1, -1, 221, 222, 223, 224, 225, 226, 227, 228, - -1, -1, 231, 232, 233, -1, -1, 236, 237, 238, - -1, -1, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, -1, 273, 274, -1, 276, -1, 278, - 279, 280, 281, 282, 283, -1, 285, 286, -1, -1, - 289, 290, 291, -1, -1, 294, 295, -1, 297, -1, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, -1, 311, 312, 313, 314, 315, 316, 317, 318, - 319, -1, 321, 322, 323, 324, 325, 326, -1, 328, - 329, 330, 331, 332, 333, 334, 335, -1, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, 356, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, - -1, 370, 371, 372, 373, 374, -1, 376, 377, 378, - 379, 380, -1, 382, 383, 384, 385, -1, 387, 388, - 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 402, -1, 404, 405, -1, 407, 408, - 409, 410, 411, 412, 413, -1, 415, 416, -1, -1, - 419, 420, 421, 422, 423, -1, 425, 426, 427, 428, - 429, 430, 431, 432, -1, -1, 435, 436, 437, 438, - 439, -1, -1, 442, 443, 444, 445, 446, 447, 448, - -1, 450, -1, 452, 453, 454, 455, 456, -1, -1, - 459, -1, -1, 462, 463, 464, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, 3, -1, 5, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 500, 21, 22, 23, 24, 25, 26, 27, 28, - -1, 30, 31, 32, -1, -1, -1, -1, -1, -1, - -1, 40, 41, -1, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, -1, 56, 57, 58, - 59, 60, 61, -1, 63, 64, 65, 66, 67, 68, - -1, 70, 71, 72, 73, 74, -1, 76, -1, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, - 89, 90, 91, 92, 93, 94, -1, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, -1, 118, - -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, - 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, - -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - -1, 160, -1, 162, 163, 164, 165, -1, 167, -1, - 169, 170, 171, 172, 173, 174, 175, 176, 177, -1, - 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, -1, 198, - 199, 200, 201, 202, 203, -1, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, -1, 216, -1, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, -1, 231, 232, 233, 234, -1, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, -1, 273, 274, 275, 276, -1, 278, - 279, 280, 281, 282, 283, -1, 285, 286, -1, 288, - 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, -1, 311, 312, 313, 314, 315, 316, 317, 318, - 319, -1, 321, 322, 323, 324, 325, 326, -1, 328, - 329, 330, 331, 332, 333, 334, 335, -1, 337, 338, - 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, - 349, -1, 351, 352, 353, 354, 355, 356, 357, 358, - 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, - 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, - 379, 380, 381, 382, 383, 384, 385, -1, 387, 388, - 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, - 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, - 409, 410, 411, 412, 413, -1, 415, 416, -1, -1, - 419, 420, 421, 422, 423, -1, 425, 426, 427, 428, - 429, 430, 431, 432, -1, -1, 435, 436, 437, 438, - 439, 440, -1, 442, 443, 444, 445, 446, 447, 448, - -1, 450, 451, 452, 453, 454, 455, 456, -1, -1, - 459, -1, 461, 462, 463, 464, 465, 466, 467, 468, - 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, - 479, 480, 481, 482, -1, -1, 485, 3, 4, 5, - -1, -1, -1, 9, -1, -1, -1, -1, -1, -1, - 499, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - 96, 97, 98, 99, 100, 101, 102, 103, -1, -1, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, 170, -1, 172, 173, 174, 175, - 176, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, -1, -1, 231, 232, 233, 234, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, -1, 273, 274, 275, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, 287, -1, 289, 290, 291, -1, -1, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, 408, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, 424, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, 440, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, 451, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, 5, - -1, -1, -1, -1, 490, 491, 492, -1, -1, -1, - -1, -1, -1, 499, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, 63, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, 170, -1, 172, 173, 174, 175, - 176, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, 229, -1, 231, 232, 233, 234, -1, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, -1, 273, 274, 275, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, 288, 289, 290, 291, -1, -1, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, 408, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, 440, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, 451, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 499, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, 33, 34, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - 96, 97, 98, 99, 100, 101, 102, 103, -1, -1, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, 170, 171, 172, 173, 174, 175, - 176, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, -1, -1, 231, 232, 233, 234, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, -1, 273, 274, 275, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, 440, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, 451, 452, 453, 454, 455, - 456, -1, -1, 459, -1, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, 485, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 499, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, 63, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, 170, -1, 172, 173, 174, 175, - 176, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, -1, -1, 231, 232, 233, 234, -1, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, -1, 273, 274, 275, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, 408, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, 440, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, 451, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 499, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, 63, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, 170, -1, 172, 173, 174, 175, - 176, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, -1, -1, 231, 232, 233, 234, -1, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, -1, 273, 274, 275, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, 408, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, 440, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, 451, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 499, -1, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, 171, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - 406, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, 485, + 479, 480, 481, 482, 483, 484, -1, 3, 487, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 499, -1, 21, 22, 23, 24, 25, + -1, -1, 501, -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, @@ -306292,7 +320449,7 @@ static const yytype_int16 yycheck[] = 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, 171, -1, 173, 174, 175, + -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, @@ -306306,314 +320463,74 @@ static const yytype_int16 yycheck[] = 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, + 306, 307, 308, 309, -1, 311, 312, 313, -1, 315, + 316, 317, 318, 319, 320, -1, 322, 323, 324, 325, + 326, 327, -1, 329, 330, 331, 332, 333, 334, 335, + 336, -1, 338, 339, 340, 341, 342, 343, 344, 345, + 346, 347, 348, 349, 350, -1, 352, 353, -1, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - 406, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, 461, 462, 463, 464, 465, + 366, 367, 368, 369, -1, 371, 372, 373, 374, 375, + -1, 377, 378, 379, 380, 381, -1, 383, 384, 385, + 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 403, -1, 405, + 406, -1, 408, -1, 410, 411, 412, 413, 414, -1, + 416, 417, -1, -1, 420, 421, 422, 423, 424, -1, + 426, 427, 428, 429, 430, 431, 432, 433, -1, -1, + 436, 437, 438, 439, 440, 441, -1, -1, 444, 445, + 446, 447, 448, 449, 450, -1, 452, -1, 454, 455, + 456, 457, 458, -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, -1, 3, 485, - 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 499, -1, -1, 21, 22, 23, 24, - 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, - -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, - 45, -1, 47, 48, 49, 50, 51, -1, 53, 54, - -1, 56, 57, 58, 59, 60, 61, -1, -1, 64, - 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, - -1, -1, -1, 78, 79, 80, 81, 82, 83, -1, - 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, - -1, -1, 97, 98, 99, -1, -1, -1, -1, -1, - -1, -1, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, -1, 118, -1, 120, 121, 122, 123, 124, - 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, - 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, - 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, -1, 160, -1, 162, 163, 164, - 165, -1, 167, -1, 169, -1, -1, -1, 173, 174, - 175, -1, 177, -1, 179, -1, 181, 182, 183, -1, - 185, 186, 187, 188, 189, 190, 191, -1, 193, 194, - 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, - 205, -1, 207, 208, 209, 210, 211, 212, 213, 214, - -1, 216, -1, 218, -1, -1, 221, -1, 223, 224, - 225, 226, 227, 228, -1, -1, 231, -1, 233, -1, - -1, 236, 237, 238, -1, -1, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, -1, 267, 268, 269, 270, 271, -1, 273, 274, - -1, 276, -1, 278, 279, 280, 281, 282, 283, -1, - 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, - 295, -1, 297, -1, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, -1, 311, 312, 313, 314, - 315, 316, 317, 318, 319, -1, 321, 322, 323, 324, - 325, 326, -1, 328, 329, 330, 331, 332, 333, 334, - 335, -1, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, -1, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, -1, 370, 371, 372, 373, 374, - -1, 376, 377, 378, 379, 380, -1, 382, 383, 384, - 385, -1, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, -1, 404, - 405, -1, 407, -1, 409, 410, 411, 412, 413, -1, - 415, 416, -1, -1, 419, 420, 421, 422, 423, -1, - 425, 426, 427, 428, 429, 430, 431, 432, -1, -1, - 435, 436, 437, 438, 439, -1, -1, 442, 443, 444, - 445, 446, 447, 448, -1, 450, -1, 452, 453, 454, - 455, 456, -1, -1, 459, -1, -1, 462, 463, 464, - 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 3, -1, - 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 499, -1, 21, 22, 23, 24, - 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, - -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, - 45, -1, 47, 48, 49, 50, 51, -1, 53, 54, - -1, 56, 57, 58, 59, 60, 61, -1, -1, 64, - 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, - -1, -1, -1, 78, 79, 80, 81, 82, 83, -1, - 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, - -1, -1, 97, 98, 99, -1, -1, -1, -1, -1, - -1, -1, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, -1, 118, -1, 120, 121, 122, 123, 124, - 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, - 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, - 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, -1, 160, -1, 162, 163, 164, - 165, -1, 167, -1, 169, -1, -1, -1, 173, 174, - 175, -1, 177, -1, 179, -1, 181, 182, 183, -1, - 185, 186, 187, 188, 189, 190, 191, -1, 193, 194, - 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, - 205, -1, 207, 208, 209, 210, 211, 212, 213, 214, - -1, 216, -1, 218, -1, -1, 221, -1, 223, 224, - 225, 226, 227, 228, -1, -1, 231, -1, 233, -1, - -1, 236, 237, 238, -1, -1, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, -1, 267, 268, 269, 270, 271, -1, 273, 274, - -1, 276, -1, 278, 279, 280, 281, 282, 283, -1, - 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, - 295, -1, 297, -1, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, -1, 311, 312, 313, 314, - 315, 316, 317, 318, 319, -1, 321, 322, 323, 324, - 325, 326, -1, 328, 329, 330, 331, 332, 333, 334, - 335, -1, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, -1, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, -1, 370, 371, 372, 373, 374, - -1, 376, 377, 378, 379, 380, -1, 382, 383, 384, - 385, -1, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, -1, 404, - 405, -1, 407, -1, 409, 410, 411, 412, 413, -1, - 415, 416, -1, -1, 419, 420, 421, 422, 423, -1, - 425, 426, 427, 428, 429, 430, 431, 432, -1, -1, - 435, 436, 437, 438, 439, -1, -1, 442, 443, 444, - 445, 446, 447, 448, -1, 450, -1, 452, 453, 454, - 455, 456, -1, -1, 459, -1, -1, 462, 463, 464, - 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 499, -1, 21, 22, 23, 24, - 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, - -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, - 45, -1, 47, 48, 49, 50, 51, -1, 53, 54, - -1, 56, 57, 58, 59, 60, 61, -1, -1, 64, - 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, - -1, -1, -1, 78, 79, 80, 81, 82, 83, -1, - 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, - -1, -1, 97, 98, 99, -1, -1, -1, -1, -1, - -1, -1, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, -1, 118, -1, 120, 121, 122, 123, 124, - 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, - 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, - 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, -1, 160, -1, 162, 163, 164, - 165, -1, 167, -1, 169, -1, -1, -1, 173, 174, - 175, -1, 177, -1, 179, -1, 181, 182, 183, -1, - 185, 186, 187, 188, 189, 190, 191, -1, 193, 194, - 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, - 205, -1, 207, 208, 209, 210, 211, 212, 213, 214, - -1, 216, -1, 218, -1, -1, 221, -1, 223, 224, - 225, 226, 227, 228, -1, -1, 231, -1, 233, -1, - -1, 236, 237, 238, -1, -1, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, -1, 267, 268, 269, 270, 271, -1, 273, 274, - -1, 276, -1, 278, 279, 280, 281, 282, 283, -1, - 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, - 295, -1, 297, -1, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, -1, 311, 312, 313, 314, - 315, 316, 317, 318, 319, -1, 321, 322, 323, 324, - 325, 326, -1, 328, 329, 330, 331, 332, 333, 334, - 335, -1, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, -1, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, -1, 370, 371, 372, 373, 374, - -1, 376, 377, 378, 379, 380, -1, 382, 383, 384, - 385, -1, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, -1, 404, - 405, -1, 407, -1, 409, 410, 411, 412, 413, -1, - 415, 416, -1, -1, 419, 420, 421, 422, 423, -1, - 425, 426, 427, 428, 429, 430, 431, 432, -1, -1, - 435, 436, 437, 438, 439, -1, -1, 442, 443, 444, - 445, 446, 447, 448, -1, 450, -1, 452, 453, 454, - 455, 456, -1, -1, 459, -1, -1, 462, 463, 464, - 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 499, -1, 21, 22, 23, 24, - 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, - -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, - 45, -1, 47, 48, 49, 50, 51, -1, 53, 54, - -1, 56, 57, 58, 59, 60, 61, -1, -1, 64, - 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, - -1, -1, -1, 78, 79, 80, 81, 82, 83, -1, - 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, - -1, -1, 97, 98, 99, -1, -1, -1, -1, -1, - -1, -1, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, -1, 118, -1, 120, 121, 122, 123, 124, - 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, - 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, - 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, -1, 160, -1, 162, 163, 164, - 165, -1, 167, -1, 169, -1, -1, -1, 173, 174, - 175, -1, 177, -1, 179, -1, 181, 182, 183, -1, - 185, 186, 187, 188, 189, 190, 191, -1, 193, 194, - 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, - 205, -1, 207, 208, 209, 210, 211, 212, 213, 214, - -1, 216, -1, 218, -1, -1, 221, -1, 223, 224, - 225, 226, 227, 228, -1, -1, 231, -1, 233, -1, - -1, 236, 237, 238, -1, -1, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, -1, 267, 268, 269, 270, 271, -1, 273, 274, - -1, 276, -1, 278, 279, 280, 281, 282, 283, -1, - 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, - 295, -1, 297, -1, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, -1, 311, 312, 313, 314, - 315, 316, 317, 318, 319, -1, 321, 322, 323, 324, - 325, 326, -1, 328, 329, 330, 331, 332, 333, 334, - 335, -1, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, -1, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, -1, 370, 371, 372, 373, 374, - -1, 376, 377, 378, 379, 380, -1, 382, 383, 384, - 385, -1, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, -1, 404, - 405, -1, 407, -1, 409, 410, 411, 412, 413, -1, - 415, 416, -1, -1, 419, 420, 421, 422, 423, -1, - 425, 426, 427, 428, 429, 430, 431, 432, -1, -1, - 435, 436, 437, 438, 439, -1, -1, 442, 443, 444, - 445, 446, 447, 448, -1, 450, -1, 452, 453, 454, - 455, 456, -1, -1, 459, -1, -1, 462, 463, 464, - 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 3, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 499, -1, 21, 22, 23, 24, - 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, - -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, - 45, -1, 47, 48, 49, 50, 51, -1, 53, 54, - -1, 56, 57, 58, 59, 60, 61, -1, -1, 64, - 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, - -1, -1, -1, 78, 79, 80, 81, 82, 83, -1, - 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, - -1, -1, 97, 98, 99, -1, -1, -1, -1, -1, - -1, -1, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, -1, 118, -1, 120, 121, 122, 123, 124, - 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, - 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, - 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, -1, 160, -1, 162, 163, 164, - 165, -1, 167, -1, 169, -1, -1, -1, 173, 174, - 175, -1, 177, -1, 179, -1, 181, 182, 183, -1, - 185, 186, 187, 188, 189, 190, 191, -1, 193, 194, - 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, - 205, -1, 207, 208, 209, 210, 211, 212, 213, 214, - -1, 216, -1, 218, -1, -1, 221, -1, 223, 224, - 225, 226, 227, 228, -1, -1, 231, -1, 233, -1, - -1, 236, 237, 238, -1, -1, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, -1, 267, 268, 269, 270, 271, -1, 273, 274, - -1, 276, -1, 278, 279, 280, 281, 282, 283, -1, - 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, - 295, -1, 297, -1, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, -1, 311, 312, 313, 314, - 315, 316, 317, 318, 319, -1, 321, 322, 323, 324, - 325, 326, -1, 328, 329, 330, 331, 332, 333, 334, - 335, -1, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, -1, 351, 352, -1, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, -1, 370, 371, 372, 373, 374, - -1, 376, 377, 378, 379, 380, -1, 382, 383, 384, - 385, -1, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, -1, 404, - 405, -1, 407, -1, 409, 410, 411, 412, 413, -1, - 415, 416, -1, -1, 419, 420, 421, 422, 423, -1, - 425, 426, 427, 428, 429, 430, 431, 432, -1, -1, - 435, 436, 437, 438, 439, -1, -1, 442, 443, 444, - 445, 446, 447, 448, -1, 450, -1, 452, 453, 454, - 455, 456, -1, -1, 459, -1, -1, 462, 463, 464, - 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, -1, -1, - 3, 4, 5, -1, -1, 8, 9, -1, -1, -1, - -1, -1, 15, -1, 499, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, -1, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, -1, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, - 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, - 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 151, -1, - 153, 154, 155, 156, 157, -1, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, -1, -1, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, - 203, 204, 205, 206, -1, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, - 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, - 273, 274, 275, 276, 277, -1, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, - 293, 294, -1, 296, 297, 298, -1, 300, 301, 302, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - -1, 314, 315, -1, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, - 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, - 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, - 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, - 393, 394, 395, 396, 397, 398, 399, 400, -1, 402, - 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 416, 417, 418, 419, 420, -1, 422, - -1, 424, 425, 426, 427, 428, 429, 430, 431, 432, - 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, - 443, 444, 445, 446, -1, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, - 463, 464, 465, 466, 467, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 479, 480, 481, 482, - -1, 3, -1, 486, 487, 488, 8, 490, 491, 492, - 493, 494, 495, 15, -1, -1, 18, 19, 20, 21, + 476, 477, 478, 479, 480, 481, 482, 483, 484, 3, + -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 501, -1, 21, 22, 23, + 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, + -1, -1, -1, -1, -1, -1, 40, 41, -1, 43, + 44, 45, -1, 47, 48, 49, 50, 51, -1, 53, + 54, -1, 56, 57, 58, 59, 60, 61, -1, -1, + 64, 65, 66, 67, 68, -1, 70, 71, 72, 73, + 74, -1, -1, -1, 78, 79, 80, 81, 82, 83, + -1, 85, 86, 87, -1, 89, 90, 91, 92, 93, + 94, -1, -1, 97, 98, 99, -1, -1, -1, -1, + -1, -1, -1, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, -1, 118, -1, 120, 121, 122, 123, + 124, 125, -1, 127, 128, 129, 130, 131, -1, -1, + 134, 135, 136, 137, 138, -1, 140, 141, 142, -1, + 144, 145, 146, -1, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, -1, 160, -1, 162, 163, + 164, 165, -1, 167, -1, 169, -1, -1, -1, 173, + 174, 175, -1, 177, -1, 179, -1, 181, 182, 183, + -1, 185, 186, 187, 188, 189, 190, 191, -1, 193, + 194, 195, 196, -1, 198, 199, 200, 201, 202, 203, + -1, 205, -1, 207, 208, 209, 210, 211, 212, 213, + 214, -1, 216, -1, 218, -1, -1, 221, -1, 223, + 224, 225, 226, 227, 228, -1, -1, 231, -1, 233, + -1, -1, 236, 237, 238, -1, -1, 241, 242, 243, + 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, + 264, 265, -1, 267, 268, 269, 270, 271, -1, 273, + 274, -1, 276, -1, 278, 279, 280, 281, 282, 283, + -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, + 294, 295, -1, 297, -1, 299, 300, 301, 302, 303, + 304, 305, 306, 307, 308, 309, -1, 311, 312, 313, + -1, 315, 316, 317, 318, 319, 320, -1, 322, 323, + 324, 325, 326, 327, -1, 329, 330, 331, 332, 333, + 334, 335, 336, -1, 338, 339, 340, 341, 342, 343, + 344, 345, 346, 347, 348, 349, 350, -1, 352, 353, + -1, 355, 356, 357, 358, 359, 360, 361, 362, 363, + 364, 365, 366, 367, 368, 369, -1, 371, 372, 373, + 374, 375, -1, 377, 378, 379, 380, 381, -1, 383, + 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, + -1, 405, 406, -1, 408, -1, 410, 411, 412, 413, + 414, -1, 416, 417, -1, -1, 420, 421, 422, 423, + 424, -1, 426, 427, 428, 429, 430, 431, 432, 433, + -1, -1, 436, 437, 438, 439, 440, 441, -1, -1, + 444, 445, 446, 447, 448, 449, 450, -1, 452, -1, + 454, 455, 456, 457, 458, -1, -1, 461, -1, -1, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, + 484, 3, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 501, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, -1, 47, 48, 49, 50, 51, @@ -306643,254 +320560,25 @@ static const yytype_int16 yycheck[] = 282, 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, - 312, 313, 314, 315, 316, 317, 318, 319, -1, 321, - 322, 323, 324, 325, 326, -1, 328, 329, 330, 331, - 332, 333, 334, 335, -1, 337, 338, 339, 340, 341, - 342, 343, 344, 345, 346, 347, 348, 349, -1, 351, - 352, -1, 354, 355, 356, 357, 358, 359, 360, 361, - 362, 363, 364, 365, 366, 367, 368, -1, 370, 371, - 372, 373, 374, -1, 376, 377, 378, 379, 380, -1, - 382, 383, 384, 385, -1, 387, 388, 389, 390, 391, + 312, 313, -1, 315, 316, 317, 318, 319, 320, -1, + 322, 323, 324, 325, 326, 327, -1, 329, 330, 331, + 332, 333, 334, 335, 336, -1, 338, 339, 340, 341, + 342, 343, 344, 345, 346, 347, 348, 349, 350, -1, + 352, 353, -1, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, 365, 366, 367, 368, 369, -1, 371, + 372, 373, 374, 375, -1, 377, 378, 379, 380, 381, + -1, 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, - 402, -1, 404, 405, -1, 407, -1, 409, 410, 411, - 412, 413, -1, 415, 416, -1, -1, 419, 420, 421, - 422, 423, -1, 425, 426, 427, 428, 429, 430, 431, - 432, -1, -1, 435, 436, 437, 438, 439, -1, -1, - 442, 443, 444, 445, 446, 447, 448, -1, 450, -1, - 452, 453, 454, 455, 456, -1, -1, 459, -1, -1, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, + 402, 403, -1, 405, 406, -1, 408, -1, 410, 411, + 412, 413, 414, -1, 416, 417, -1, -1, 420, 421, + 422, 423, 424, -1, 426, 427, 428, 429, 430, 431, + 432, 433, -1, -1, 436, 437, 438, 439, 440, 441, + -1, -1, 444, 445, 446, 447, 448, 449, 450, -1, + 452, -1, 454, 455, 456, 457, 458, -1, -1, 461, + -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, - 482, -1, -1, -1, 486, 487, 488, -1, 490, 491, - 492, 493, 494, 495, 8, -1, -1, 11, -1, -1, - -1, 15, 16, 17, 18, 19, 20, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 35, -1, 8, -1, -1, 11, -1, -1, 43, - 15, 16, 17, 18, 19, 20, 50, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 35, -1, -1, -1, -1, -1, -1, -1, 43, 8, - -1, 75, 11, -1, -1, 50, 15, 16, 17, 18, - 19, 20, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 35, -1, 8, -1, - 75, 11, -1, -1, 43, 15, 16, 17, 18, 19, - 20, 50, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 35, -1, -1, -1, -1, - -1, -1, -1, 43, -1, -1, 75, -1, -1, -1, - 50, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 75, -1, -1, -1, -1, - -1, -1, 176, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 192, -1, - -1, -1, -1, 197, -1, -1, 8, -1, -1, 11, - -1, 176, -1, 15, 16, 17, 18, 19, 20, -1, - -1, -1, -1, -1, -1, 219, 220, 192, -1, -1, - -1, -1, 197, 35, -1, -1, -1, -1, -1, -1, - 234, 43, -1, -1, -1, -1, -1, 176, 50, -1, - -1, -1, -1, -1, 219, 220, -1, -1, -1, -1, - -1, -1, -1, 192, -1, -1, -1, -1, 197, 234, - -1, -1, -1, 75, -1, -1, 176, -1, 272, -1, - -1, 275, -1, -1, -1, -1, -1, -1, -1, -1, - 219, 220, 192, -1, -1, 289, -1, 197, 292, -1, - -1, -1, -1, -1, -1, 234, -1, 272, -1, -1, - 275, -1, -1, -1, -1, -1, -1, -1, -1, 219, - 220, -1, -1, -1, 289, -1, -1, 292, -1, -1, - -1, -1, -1, -1, 234, -1, -1, -1, -1, -1, - -1, -1, -1, 272, -1, -1, 275, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 289, -1, -1, 292, -1, -1, -1, -1, -1, -1, - -1, -1, 272, -1, 176, 275, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 381, -1, 289, - 192, -1, 292, -1, -1, 197, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 381, 219, 220, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 234, -1, -1, -1, 8, -1, -1, 11, - -1, -1, -1, 15, 16, 17, 18, 19, 20, -1, - -1, -1, 381, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 35, -1, -1, -1, -1, -1, -1, - 272, 43, -1, 275, -1, -1, -1, -1, 50, -1, - -1, 381, -1, -1, -1, -1, -1, 289, -1, 483, - 292, -1, 486, 487, 488, -1, 490, 491, 492, 493, - 494, 495, -1, 75, -1, -1, 500, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 483, -1, - -1, 486, 487, 488, -1, 490, 491, 492, 493, 494, - 495, -1, -1, -1, -1, 500, -1, -1, -1, -1, - 8, -1, -1, 11, -1, -1, -1, 15, 16, 17, - 18, 19, 20, -1, 483, -1, -1, 486, 487, 488, - -1, 490, 491, 492, 493, 494, 495, 35, -1, -1, - -1, 500, -1, -1, -1, 43, -1, -1, -1, 381, - -1, -1, 50, 483, -1, -1, 486, 487, 488, -1, - 490, 491, 492, 493, 494, 495, -1, -1, -1, -1, - 500, -1, 8, -1, 176, 11, -1, 75, -1, 15, - 16, 17, 18, 19, 20, -1, -1, -1, -1, -1, - 192, -1, -1, -1, -1, 197, -1, -1, -1, 35, - -1, -1, -1, -1, -1, -1, -1, 43, -1, -1, - -1, -1, -1, -1, 50, -1, -1, 219, 220, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 234, -1, -1, -1, -1, 8, -1, 75, - 11, -1, -1, -1, 15, 16, 17, 18, 19, 20, - -1, 483, -1, -1, 486, 487, 488, -1, 490, 491, - 492, 493, 494, 495, 35, -1, -1, -1, 500, -1, - 272, -1, 43, 275, -1, -1, -1, -1, 176, 50, - -1, -1, -1, -1, -1, -1, -1, 289, -1, -1, - 292, -1, -1, -1, 192, -1, -1, -1, -1, 197, - -1, -1, -1, -1, 75, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 219, 220, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 234, -1, -1, -1, - 176, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 8, 192, -1, 11, -1, - -1, 197, 15, 16, 17, 18, 19, 20, -1, -1, - -1, -1, -1, -1, 272, -1, -1, 275, -1, 381, - -1, -1, 35, 219, 220, -1, -1, -1, -1, -1, - 43, 289, -1, -1, 292, -1, -1, 50, 234, -1, - -1, -1, -1, -1, -1, 176, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 192, 75, -1, -1, -1, 197, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 272, -1, -1, 275, - -1, -1, -1, -1, -1, -1, -1, -1, 219, 220, - -1, -1, -1, 289, -1, -1, 292, -1, -1, -1, - -1, -1, -1, 234, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 483, -1, 381, 486, 487, 488, -1, 490, 491, - 492, 493, 494, 495, -1, -1, -1, -1, 500, -1, - -1, 272, -1, -1, 275, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 289, 8, - -1, 292, 11, 176, -1, -1, 15, 16, 17, 18, - 19, 20, -1, -1, -1, -1, -1, -1, -1, 192, - -1, -1, -1, -1, 197, 381, 35, -1, -1, -1, - -1, -1, -1, -1, 43, -1, -1, -1, -1, -1, - -1, 50, -1, -1, -1, -1, 219, 220, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 234, -1, -1, -1, 483, 75, -1, 486, 487, - 488, -1, 490, 491, 492, 493, 494, 495, -1, -1, - -1, -1, 500, -1, -1, -1, 8, -1, -1, 11, - 381, -1, -1, 15, 16, 17, 18, 19, 20, 272, - -1, -1, 275, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 35, -1, -1, 289, -1, -1, 292, - -1, 43, -1, -1, -1, -1, -1, 483, 50, -1, - 486, 487, 488, -1, 490, 491, 492, 493, 494, 495, - -1, -1, -1, -1, 500, -1, -1, -1, -1, -1, - -1, -1, -1, 75, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 8, -1, -1, 11, 176, -1, -1, - 15, 16, 17, 18, 19, 20, -1, -1, -1, -1, - -1, -1, -1, 192, -1, -1, -1, -1, 197, -1, - 35, -1, 483, -1, -1, 486, 487, 488, 43, 490, - 491, 492, 493, 494, 495, 50, -1, -1, 381, 500, - 219, 220, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 234, 8, -1, -1, 11, - 75, -1, -1, 15, 16, 17, 18, 19, 20, 8, - -1, -1, 11, -1, -1, -1, 15, -1, -1, 18, - 19, 20, -1, 35, 176, -1, -1, -1, -1, -1, - -1, 43, -1, 272, -1, -1, 275, -1, 50, -1, - 192, -1, -1, -1, 43, 197, -1, -1, -1, -1, - 289, 50, -1, 292, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 75, -1, -1, -1, 219, 220, -1, - -1, -1, -1, -1, -1, -1, 75, -1, -1, -1, - 483, -1, 234, 486, 487, 488, -1, 490, 491, 492, - 493, 494, 495, -1, -1, -1, -1, 500, -1, 8, - -1, 176, 11, -1, -1, -1, 15, 16, 17, 18, - 19, 20, -1, -1, -1, -1, -1, 192, -1, -1, - 272, -1, 197, 275, -1, -1, 35, -1, -1, -1, - -1, -1, -1, -1, 43, -1, -1, 289, -1, -1, - 292, 50, 381, -1, 219, 220, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 234, - 8, -1, -1, 11, 176, -1, 75, 15, 16, 17, - 18, 19, 20, -1, -1, -1, -1, 176, -1, -1, - 192, -1, -1, -1, -1, 197, -1, 35, -1, -1, - -1, -1, -1, 192, -1, 43, -1, 272, 197, -1, - 275, -1, 50, -1, -1, -1, -1, 219, 220, -1, - -1, -1, -1, -1, 289, -1, -1, 292, -1, -1, - 219, 220, 234, -1, -1, -1, -1, 75, -1, 381, - -1, -1, -1, -1, -1, 234, -1, -1, -1, -1, - -1, -1, -1, -1, 483, -1, -1, 486, 487, 488, - -1, 490, 491, 492, 493, 494, 495, -1, -1, -1, - 272, 500, -1, 275, -1, -1, -1, 176, -1, -1, - -1, -1, -1, 272, -1, -1, 275, 289, -1, -1, - 292, -1, -1, 192, -1, -1, -1, -1, 197, -1, - 289, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 381, -1, -1, -1, - 219, 220, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 234, -1, -1, 176, -1, - -1, 483, -1, -1, 486, 487, 488, -1, 490, 491, - 492, 493, 494, 495, 192, -1, -1, -1, 500, 197, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 272, -1, -1, 275, -1, -1, 381, - -1, 219, 220, -1, -1, -1, -1, -1, -1, -1, - 289, -1, 381, 292, -1, -1, 234, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 483, -1, - -1, 486, 487, 488, -1, 490, 491, 492, 493, 494, - 495, -1, -1, -1, 272, 500, -1, 275, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 289, -1, -1, 292, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 483, 381, -1, 486, 487, 488, -1, 490, 491, - 492, 493, 494, 495, 483, -1, 498, 486, 487, 488, - -1, 490, 491, 492, 493, 494, 495, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 381, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 483, -1, -1, 486, 487, 488, - -1, 490, 491, 492, 493, 494, 495, -1, -1, 498, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 3, -1, 483, -1, -1, 486, 487, - 488, -1, 490, 491, 492, 493, 494, 495, -1, -1, - 498, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, - 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, - 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, - 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, - 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, - 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, - 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, - 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, - 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, - 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, - 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, - 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, - 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, - 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, - 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, 3, -1, -1, -1, -1, -1, -1, - -1, -1, 492, -1, -1, -1, -1, -1, -1, -1, + 482, 483, 484, 3, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 501, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, -1, 47, 48, 49, @@ -306920,850 +320608,123 @@ static const yytype_int16 yycheck[] = 280, 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - -1, 311, 312, 313, 314, 315, 316, 317, 318, 319, - -1, 321, 322, 323, 324, 325, 326, -1, 328, 329, - 330, 331, 332, 333, 334, 335, -1, 337, 338, 339, - 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, - -1, 351, 352, -1, 354, 355, 356, 357, 358, 359, - 360, 361, 362, 363, 364, 365, 366, 367, 368, -1, - 370, 371, 372, 373, 374, -1, 376, 377, 378, 379, - 380, -1, 382, 383, 384, 385, -1, 387, 388, 389, - 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, - 400, 401, 402, -1, 404, 405, -1, 407, -1, 409, - 410, 411, 412, 413, -1, 415, 416, -1, -1, 419, - 420, 421, 422, 423, -1, 425, 426, 427, 428, 429, - 430, 431, 432, -1, -1, 435, 436, 437, 438, 439, - -1, -1, 442, 443, 444, 445, 446, 447, 448, -1, - 450, -1, 452, 453, 454, 455, 456, -1, -1, 459, - -1, -1, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, 3, 4, 5, -1, -1, -1, 9, - -1, -1, 492, -1, -1, -1, -1, -1, -1, -1, - -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, - 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, - 40, 41, -1, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, -1, 56, 57, 58, 59, - 60, 61, -1, -1, 64, 65, 66, 67, 68, -1, - 70, 71, 72, 73, 74, -1, 76, -1, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, - 90, 91, 92, 93, 94, -1, 96, 97, 98, 99, - 100, 101, 102, 103, -1, -1, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, -1, - 120, 121, 122, 123, 124, 125, -1, 127, 128, 129, - 130, 131, -1, -1, 134, 135, 136, 137, 138, -1, - 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, -1, 162, 163, 164, 165, -1, 167, -1, 169, - 170, -1, 172, 173, 174, 175, 176, 177, -1, 179, - -1, 181, 182, 183, -1, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, -1, 198, 199, - 200, 201, 202, 203, -1, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, -1, 216, -1, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228, -1, - -1, 231, 232, 233, 234, -1, 236, 237, 238, -1, - -1, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, -1, 273, 274, 275, 276, -1, 278, 279, - 280, 281, 282, 283, -1, 285, 286, 287, -1, 289, - 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - -1, 311, 312, 313, 314, 315, 316, 317, 318, 319, - -1, 321, 322, 323, 324, 325, 326, -1, 328, 329, - 330, 331, 332, 333, 334, 335, -1, 337, 338, 339, - 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, - -1, 351, 352, 353, 354, 355, 356, 357, 358, 359, - 360, 361, 362, 363, 364, 365, 366, 367, 368, -1, - 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, - 380, 381, 382, 383, 384, 385, -1, 387, 388, 389, - 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, - 400, 401, 402, -1, 404, 405, -1, 407, 408, 409, - 410, 411, 412, 413, -1, 415, 416, -1, -1, 419, - 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, - 430, 431, 432, -1, -1, 435, 436, 437, 438, 439, - 440, -1, 442, 443, 444, 445, 446, 447, 448, -1, - 450, 451, 452, 453, 454, 455, 456, -1, -1, 459, - -1, -1, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, 3, 4, 5, -1, -1, -1, 9, - 490, 491, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, - 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, - 40, 41, -1, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, -1, 56, 57, 58, 59, - 60, 61, -1, -1, 64, 65, 66, 67, 68, -1, - 70, 71, 72, 73, 74, -1, 76, -1, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, - 90, 91, 92, 93, 94, -1, 96, 97, 98, 99, - 100, 101, 102, 103, -1, -1, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, -1, - 120, 121, 122, 123, 124, 125, -1, 127, 128, 129, - 130, 131, -1, -1, 134, 135, 136, 137, 138, -1, - 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, -1, 162, 163, 164, 165, -1, 167, -1, 169, - 170, -1, 172, 173, 174, 175, 176, 177, -1, 179, - -1, 181, 182, 183, -1, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, -1, 198, 199, - 200, 201, 202, 203, -1, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, -1, 216, -1, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228, -1, - -1, 231, 232, 233, 234, -1, 236, 237, 238, -1, - -1, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, -1, 273, 274, 275, 276, -1, 278, 279, - 280, 281, 282, 283, -1, 285, 286, 287, -1, 289, - 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - -1, 311, 312, 313, 314, 315, 316, 317, 318, 319, - -1, 321, 322, 323, 324, 325, 326, -1, 328, 329, - 330, 331, 332, 333, 334, 335, -1, 337, 338, 339, - 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, - -1, 351, 352, 353, 354, 355, 356, 357, 358, 359, - 360, 361, 362, 363, 364, 365, 366, 367, 368, -1, - 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, - 380, 381, 382, 383, 384, 385, -1, 387, 388, 389, - 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, - 400, 401, 402, -1, 404, 405, -1, 407, 408, 409, - 410, 411, 412, 413, -1, 415, 416, -1, -1, 419, - 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, - 430, 431, 432, -1, -1, 435, 436, 437, 438, 439, - 440, -1, 442, 443, 444, 445, 446, 447, 448, -1, - 450, 451, 452, 453, 454, 455, 456, -1, -1, 459, - -1, -1, 462, 463, 464, 465, 466, 467, 468, 469, - 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, 3, 4, 5, -1, -1, -1, 9, - 490, 491, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, - 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, - 40, 41, -1, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, -1, 56, 57, 58, 59, - 60, 61, -1, -1, 64, 65, 66, 67, 68, -1, - 70, 71, 72, 73, 74, -1, 76, -1, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, - 90, 91, 92, 93, 94, -1, 96, 97, 98, 99, - 100, 101, 102, 103, -1, -1, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, -1, 118, -1, - 120, 121, 122, 123, 124, 125, -1, 127, 128, 129, - 130, 131, -1, -1, 134, 135, 136, 137, 138, -1, - 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, -1, 162, 163, 164, 165, -1, 167, -1, 169, - 170, -1, 172, 173, 174, 175, 176, 177, -1, 179, - -1, 181, 182, 183, -1, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, -1, 198, 199, - 200, 201, 202, 203, -1, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, -1, 216, -1, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228, -1, - -1, 231, 232, 233, 234, -1, 236, 237, 238, -1, - -1, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, -1, 273, 274, 275, 276, -1, 278, 279, - 280, 281, 282, 283, -1, 285, 286, 287, -1, 289, - 290, 291, -1, -1, 294, 295, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - -1, 311, 312, 313, 314, 315, 316, 317, 318, 319, - -1, 321, 322, 323, 324, 325, 326, -1, 328, 329, - 330, 331, 332, 333, 334, 335, -1, 337, 338, 339, + -1, 311, 312, 313, -1, 315, 316, 317, 318, 319, + 320, -1, 322, 323, 324, 325, 326, 327, -1, 329, + 330, 331, 332, 333, 334, 335, 336, -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, - -1, 351, 352, 353, 354, 355, 356, 357, 358, 359, - 360, 361, 362, 363, 364, 365, 366, 367, 368, -1, - 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, - 380, 381, 382, 383, 384, 385, -1, 387, 388, 389, + 350, -1, 352, 353, -1, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, + -1, 371, 372, 373, 374, 375, -1, 377, 378, 379, + 380, 381, -1, 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, - 400, 401, 402, -1, 404, 405, -1, 407, 408, 409, - 410, 411, 412, 413, -1, 415, 416, -1, -1, 419, - 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, - 430, 431, 432, -1, -1, 435, 436, 437, 438, 439, - 440, -1, 442, 443, 444, 445, 446, 447, 448, -1, - 450, 451, 452, 453, 454, 455, 456, -1, -1, 459, - -1, -1, 462, 463, 464, 465, 466, 467, 468, 469, + 400, 401, 402, 403, -1, 405, 406, -1, 408, -1, + 410, 411, 412, 413, 414, -1, 416, 417, -1, -1, + 420, 421, 422, 423, 424, -1, 426, 427, 428, 429, + 430, 431, 432, 433, -1, -1, 436, 437, 438, 439, + 440, 441, -1, -1, 444, 445, 446, 447, 448, 449, + 450, -1, 452, -1, 454, 455, 456, 457, 458, -1, + -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, - 480, 481, 482, -1, -1, 8, -1, -1, 11, -1, - 490, 491, 15, 16, 17, 18, 19, 20, 8, -1, - -1, 11, -1, -1, -1, 15, 16, 17, 18, 19, - 20, -1, 35, -1, -1, -1, 39, -1, -1, -1, - 43, -1, -1, -1, -1, 35, -1, 50, -1, -1, - -1, -1, -1, 43, 8, -1, -1, 11, -1, -1, - 50, 15, 16, 17, 18, 19, 20, 8, -1, -1, - 11, -1, 75, -1, 15, 16, 17, 18, 19, 20, - -1, 35, -1, -1, -1, 75, -1, -1, -1, 43, - -1, -1, -1, -1, 35, -1, 50, 38, -1, -1, - -1, -1, 43, 8, -1, -1, 11, -1, -1, 50, - 15, 16, 17, 18, 19, 20, -1, -1, -1, -1, - -1, 75, -1, 126, -1, -1, -1, -1, -1, -1, - 35, -1, -1, -1, 75, -1, -1, -1, 43, -1, - -1, -1, -1, -1, -1, 50, -1, -1, 8, -1, - -1, 11, -1, -1, -1, 15, 16, 17, 18, 19, - 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 75, -1, -1, 176, -1, 35, 166, -1, 38, -1, - -1, 171, -1, 43, -1, -1, 176, -1, -1, 192, - 50, -1, -1, -1, 197, -1, -1, -1, -1, -1, - -1, -1, 192, -1, -1, -1, -1, 197, -1, -1, - -1, 165, -1, -1, -1, 75, 219, 220, -1, -1, - -1, -1, 176, -1, -1, -1, -1, -1, -1, 219, - 220, 234, -1, -1, -1, 176, -1, -1, 192, -1, - -1, -1, -1, 197, 234, -1, -1, -1, -1, -1, - -1, 192, -1, -1, -1, -1, 197, -1, -1, -1, - -1, -1, -1, -1, -1, 219, 220, -1, -1, 272, - -1, 176, 275, -1, -1, -1, -1, -1, 219, 220, - 234, -1, 272, -1, -1, 275, 289, 192, -1, 292, - -1, -1, 197, 234, -1, -1, -1, -1, -1, 289, - -1, -1, 292, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 219, 220, 176, -1, 272, -1, - -1, 275, -1, -1, -1, -1, -1, -1, -1, 234, - -1, 272, 192, -1, 275, 289, -1, 197, 292, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 289, -1, - -1, 292, -1, -1, -1, -1, -1, -1, -1, 219, - 220, 315, -1, -1, -1, -1, -1, 272, -1, -1, - 275, -1, -1, -1, 234, -1, -1, -1, 381, -1, - -1, -1, -1, -1, 289, -1, -1, 292, -1, -1, - -1, 381, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 310, -1, -1, -1, -1, - -1, -1, 272, -1, -1, 275, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 381, -1, 289, - -1, -1, 292, -1, -1, -1, -1, -1, 441, -1, - 381, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 381, -1, -1, -1, - 483, -1, -1, 486, 487, 488, -1, 490, 491, 492, - 493, 494, 495, 483, -1, -1, 486, 487, 488, -1, - 490, 491, 492, 493, 494, 495, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 381, -1, -1, -1, -1, -1, -1, -1, 483, - -1, -1, 486, 487, 488, -1, 490, 491, 492, 493, - 494, 495, 483, -1, -1, 486, 487, 488, -1, 490, - 491, 492, 493, 494, 495, -1, -1, 8, -1, -1, - 11, -1, -1, -1, 15, 16, 17, 18, 19, 20, - -1, -1, -1, -1, -1, -1, -1, -1, 483, -1, - -1, 486, 487, 488, 35, 490, 491, 492, 493, 494, - 495, -1, 43, -1, -1, -1, -1, -1, -1, 50, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 483, 75, -1, 486, 487, 488, -1, - 490, 491, 492, 493, 494, 495, 8, -1, -1, 11, - -1, -1, -1, 15, 16, 17, 18, 19, 20, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 35, -1, 8, 38, -1, 11, -1, - -1, 43, 15, 16, 17, 18, 19, 20, 50, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 35, -1, -1, -1, -1, -1, -1, -1, - 43, -1, -1, 75, -1, -1, -1, 50, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 171, -1, -1, -1, -1, 176, -1, -1, -1, -1, - -1, -1, 75, -1, -1, -1, -1, -1, -1, -1, - -1, 192, -1, -1, -1, -1, 197, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 219, 220, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 234, 8, -1, -1, 11, -1, -1, - -1, 15, 16, 17, 18, 19, 20, -1, -1, -1, - -1, -1, -1, -1, 176, -1, -1, -1, -1, -1, - -1, 35, -1, -1, -1, -1, -1, -1, -1, 43, - 192, 272, -1, 166, 275, 197, 50, -1, -1, -1, - -1, -1, -1, 176, -1, -1, -1, -1, 289, -1, - -1, 292, -1, -1, -1, -1, -1, 219, 220, 192, - -1, 75, -1, -1, 197, -1, -1, -1, -1, -1, - -1, -1, 234, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 219, 220, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 234, -1, -1, -1, -1, -1, -1, -1, -1, - 272, -1, -1, 275, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 8, -1, 289, 11, -1, - 292, -1, 15, 16, 17, 18, 19, 20, -1, 272, - 381, -1, 275, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 35, -1, 8, 38, 289, 11, -1, 292, - 43, 15, 176, -1, 18, 19, 20, 50, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 192, -1, - -1, -1, -1, 197, -1, -1, -1, -1, -1, 43, - -1, -1, 75, -1, -1, -1, 50, -1, -1, -1, - -1, 8, -1, -1, 11, 219, 220, -1, 15, 16, - 17, 18, 19, 20, -1, -1, -1, -1, -1, 381, - 234, 75, -1, -1, -1, -1, -1, -1, 35, -1, - -1, -1, -1, -1, -1, -1, 43, -1, -1, -1, - -1, -1, 483, 50, -1, 486, 487, 488, 381, 490, - 491, 492, 493, 494, 495, -1, -1, -1, 272, -1, - -1, 275, -1, -1, -1, -1, -1, -1, 75, -1, - -1, -1, -1, -1, -1, 289, -1, 8, 292, -1, - 11, -1, -1, -1, 15, 16, 17, 18, 19, 20, - -1, -1, -1, 176, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 35, -1, -1, -1, -1, 192, - -1, -1, 43, -1, 197, -1, -1, -1, -1, 50, - -1, 483, 176, -1, 486, 487, 488, -1, 490, 491, - 492, 493, 494, 495, -1, -1, 219, 220, 192, -1, - -1, -1, -1, 197, 75, -1, -1, -1, -1, -1, - 483, 234, -1, 486, 487, 488, -1, 490, 491, 492, - 493, 494, 495, -1, -1, 219, 220, 381, -1, 176, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 234, -1, -1, -1, -1, 192, -1, -1, -1, 272, - 197, -1, 275, -1, -1, -1, -1, -1, -1, -1, - 414, -1, -1, -1, -1, -1, 289, -1, -1, 292, - -1, -1, 219, 220, -1, -1, -1, -1, -1, -1, - -1, 275, -1, -1, -1, -1, -1, 234, -1, -1, - -1, -1, -1, -1, -1, 289, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 176, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 192, -1, -1, -1, 272, 197, -1, 275, 483, - -1, -1, 486, 487, 488, -1, 490, 491, 492, 493, - 494, 495, 289, -1, -1, 292, -1, -1, 219, 220, - -1, -1, -1, -1, -1, -1, -1, -1, 381, -1, - -1, -1, -1, 234, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 381, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 272, -1, -1, 275, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 289, -1, - -1, 292, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 381, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 483, -1, -1, 486, 487, 488, -1, 490, 491, 492, - 493, 494, 495, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 483, - -1, -1, 486, 487, 488, -1, 490, 491, 492, 493, - 494, 495, -1, -1, -1, -1, -1, -1, -1, -1, - 381, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 483, -1, -1, 486, - 487, 488, -1, 490, 491, 492, 493, 494, 495, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 3, -1, 5, - -1, -1, 483, -1, -1, 486, 487, 488, -1, 490, - 491, 492, 493, 494, 495, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, - 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, - 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, - 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, - 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, - 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, - 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, - 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, - 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, - 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, - 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, - 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, - 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, - 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, - 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, - 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, - 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, - 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, - 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, 63, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, 170, -1, 172, 173, 174, 175, - 176, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, -1, -1, 231, 232, 233, 234, -1, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, -1, 273, 274, 275, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, 408, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, 440, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, 451, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, 5, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - 96, 97, 98, 99, 100, 101, 102, 103, -1, -1, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, 170, -1, 172, 173, 174, 175, - 176, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, -1, -1, 231, 232, 233, 234, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, -1, 273, 274, 275, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, 287, -1, 289, 290, 291, -1, -1, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, 408, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, 424, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, 440, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, 451, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, 33, 34, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - 96, 97, 98, 99, 100, 101, 102, 103, -1, -1, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, 170, -1, 172, 173, 174, 175, - 176, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, -1, -1, 231, 232, 233, 234, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, -1, 273, 274, 275, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, 408, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, 440, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, 451, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - 96, 97, 98, 99, 100, 101, 102, 103, -1, -1, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, 170, -1, 172, 173, 174, 175, - 176, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, -1, -1, 231, 232, 233, 234, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, -1, 273, 274, 275, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, 408, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, 440, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, 451, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, -1, - -1, 77, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, 168, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, 434, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, 168, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, 234, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, 434, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, + 480, 481, 482, 483, 484, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, 38, -1, 40, 41, -1, 43, 44, 45, - 46, 47, 48, 49, -1, 51, 52, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, -1, -1, - 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - 96, 97, 98, 99, 100, 101, 102, 103, -1, -1, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, -1, 153, 154, 155, - 156, 157, -1, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, 170, -1, 172, 173, 174, 175, - 176, 177, -1, 179, -1, -1, -1, 183, -1, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - 206, -1, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, -1, -1, 231, 232, 233, 234, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, -1, -1, 273, 274, 275, - 276, -1, -1, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, -1, - 296, 297, 298, -1, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, -1, 314, 315, - -1, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, -1, 402, -1, 404, 405, - -1, 407, 408, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, -1, 422, -1, -1, 425, - 426, 427, 428, 429, 430, 431, 432, 433, -1, 435, - 436, 437, 438, 439, 440, -1, 442, 443, 444, 445, - 446, -1, 448, -1, 450, 451, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 3, -1, 5, -1, -1, -1, -1, -1, - -1, -1, -1, 479, 480, 481, 482, -1, -1, -1, + -1, 501, -1, 21, 22, 23, 24, 25, 26, 27, + 28, -1, 30, 31, 32, -1, -1, -1, -1, -1, + -1, -1, 40, 41, -1, 43, 44, 45, -1, 47, + 48, 49, 50, 51, -1, 53, 54, -1, 56, 57, + 58, 59, 60, 61, -1, -1, 64, 65, 66, 67, + 68, -1, 70, 71, 72, 73, 74, -1, -1, -1, + 78, 79, 80, 81, 82, 83, -1, 85, 86, 87, + -1, 89, 90, 91, 92, 93, 94, -1, -1, 97, + 98, 99, -1, -1, -1, -1, -1, -1, -1, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, -1, + 118, -1, 120, 121, 122, 123, 124, 125, -1, 127, + 128, 129, 130, 131, -1, -1, 134, 135, 136, 137, + 138, -1, 140, 141, 142, -1, 144, 145, 146, -1, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, -1, 160, -1, 162, 163, 164, 165, -1, 167, + -1, 169, -1, -1, -1, 173, 174, 175, -1, 177, + -1, 179, -1, 181, 182, 183, -1, 185, 186, 187, + 188, 189, 190, 191, -1, 193, 194, 195, 196, -1, + 198, 199, 200, 201, 202, 203, -1, 205, -1, 207, + 208, 209, 210, 211, 212, 213, 214, -1, 216, -1, + 218, -1, -1, 221, -1, 223, 224, 225, 226, 227, + 228, -1, -1, 231, -1, 233, -1, -1, 236, 237, + 238, -1, -1, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, -1, 267, + 268, 269, 270, 271, -1, 273, 274, -1, 276, -1, + 278, 279, 280, 281, 282, 283, -1, 285, 286, -1, + -1, 289, 290, 291, -1, -1, 294, 295, -1, 297, + -1, 299, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, -1, 311, 312, 313, -1, 315, 316, 317, + 318, 319, 320, -1, 322, 323, 324, 325, 326, 327, + -1, 329, 330, 331, 332, 333, 334, 335, 336, -1, + 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, + 348, 349, 350, -1, 352, 353, -1, 355, 356, 357, + 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, + 368, 369, -1, 371, 372, 373, 374, 375, -1, 377, + 378, 379, 380, 381, -1, 383, 384, 385, 386, -1, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, -1, 405, 406, -1, + 408, -1, 410, 411, 412, 413, 414, -1, 416, 417, + -1, -1, 420, 421, 422, 423, 424, -1, 426, 427, + 428, 429, 430, 431, 432, 433, -1, -1, 436, 437, + 438, 439, 440, 441, -1, -1, 444, 445, 446, 447, + 448, 449, 450, -1, 452, -1, 454, 455, 456, 457, + 458, -1, -1, 461, -1, -1, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, + 478, 479, 480, 481, 482, 483, 484, -1, -1, 3, + 4, 5, -1, -1, 8, 9, -1, -1, -1, -1, + -1, 15, -1, 501, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, -1, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, + -1, 75, 76, 77, 78, 79, 80, 81, 82, 83, + 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, + 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, + 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, -1, 153, + 154, 155, 156, 157, -1, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, + 174, 175, 176, 177, 178, 179, 180, -1, -1, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, + 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, + 204, 205, 206, -1, 208, 209, 210, 211, 212, 213, + 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, + 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, + 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, + 274, 275, 276, 277, -1, 279, 280, 281, 282, 283, + 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, + 294, -1, 296, 297, 298, -1, 300, 301, 302, 303, + 304, 305, 306, 307, 308, 309, 310, 311, 312, -1, + 314, 315, 316, -1, 318, 319, 320, 321, 322, 323, + 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, + 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, + 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, + 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, + 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, + 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, + 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 398, 399, 400, 401, -1, 403, + 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, + 414, 415, 416, 417, 418, 419, 420, 421, -1, 423, + -1, 425, 426, 427, 428, 429, 430, 431, 432, 433, + 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, + 444, 445, 446, 447, 448, -1, 450, 451, 452, 453, + 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 465, 466, 467, 468, 469, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 481, 482, 483, + 484, -1, 3, -1, 488, 489, 490, 8, 492, 493, + 494, 495, 496, 497, 15, -1, -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, - 31, 32, 33, 34, -1, -1, -1, -1, -1, 40, - 41, -1, 43, 44, 45, -1, 47, 48, 49, 50, - 51, -1, 53, 54, -1, 56, 57, 58, 59, 60, - 61, -1, -1, 64, 65, 66, 67, 68, -1, 70, - 71, 72, 73, 74, -1, -1, -1, 78, 79, 80, - 81, 82, 83, -1, 85, 86, 87, -1, 89, 90, - 91, 92, 93, 94, -1, -1, 97, 98, 99, -1, - -1, -1, -1, -1, -1, -1, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, -1, 118, -1, 120, - 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, - 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, - 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, -1, 160, - -1, 162, 163, 164, 165, -1, 167, -1, 169, -1, - -1, -1, 173, 174, 175, -1, 177, -1, 179, -1, - 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, - 191, -1, 193, 194, 195, 196, -1, 198, 199, 200, - 201, 202, 203, -1, 205, -1, 207, 208, 209, 210, - 211, 212, 213, 214, -1, 216, -1, 218, -1, -1, - 221, -1, 223, 224, 225, 226, 227, 228, -1, -1, - 231, -1, 233, -1, -1, 236, 237, 238, -1, -1, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, -1, 267, 268, 269, 270, - 271, -1, 273, 274, -1, 276, -1, 278, 279, 280, - 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, - 291, -1, -1, 294, 295, -1, 297, -1, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, - 311, 312, 313, 314, 315, 316, 317, 318, 319, -1, - 321, 322, 323, 324, 325, 326, -1, 328, 329, 330, - 331, 332, 333, 334, 335, -1, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, -1, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, -1, 370, - 371, 372, 373, 374, -1, 376, 377, 378, 379, 380, - -1, 382, 383, 384, 385, -1, 387, 388, 389, 390, - 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, -1, 404, 405, -1, 407, -1, 409, 410, - 411, 412, 413, -1, 415, 416, -1, -1, 419, 420, - 421, 422, 423, -1, 425, 426, 427, 428, 429, 430, - 431, 432, -1, -1, 435, 436, 437, 438, 439, -1, - -1, 442, 443, 444, 445, 446, 447, 448, -1, 450, - -1, 452, 453, 454, 455, 456, -1, -1, 459, -1, - -1, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 3, -1, 5, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, 56, 57, 58, 59, 60, @@ -307792,1507 +320753,2660 @@ static const yytype_int16 yycheck[] = 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, - 311, 312, 313, 314, 315, 316, 317, 318, 319, -1, - 321, 322, 323, 324, 325, 326, -1, 328, 329, 330, - 331, 332, 333, 334, 335, -1, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, -1, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, -1, 370, - 371, 372, 373, 374, -1, 376, 377, 378, 379, 380, - -1, 382, 383, 384, 385, -1, 387, 388, 389, 390, + 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, + -1, 322, 323, 324, 325, 326, 327, -1, 329, 330, + 331, 332, 333, 334, 335, 336, -1, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, + -1, 352, 353, -1, 355, 356, 357, 358, 359, 360, + 361, 362, 363, 364, 365, 366, 367, 368, 369, -1, + 371, 372, 373, 374, 375, -1, 377, 378, 379, 380, + 381, -1, 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, -1, 404, 405, -1, 407, -1, 409, 410, - 411, 412, 413, -1, 415, 416, -1, -1, 419, 420, - 421, 422, 423, -1, 425, 426, 427, 428, 429, 430, - 431, 432, -1, -1, 435, 436, 437, 438, 439, -1, - -1, 442, 443, 444, 445, 446, 447, 448, -1, 450, - -1, 452, 453, 454, 455, 456, -1, -1, 459, -1, - -1, 462, 463, 464, 465, 466, 467, 468, 469, 470, + 401, 402, 403, -1, 405, 406, -1, 408, -1, 410, + 411, 412, 413, 414, -1, 416, 417, -1, -1, 420, + 421, 422, 423, 424, -1, 426, 427, 428, 429, 430, + 431, 432, 433, -1, -1, 436, 437, 438, 439, 440, + 441, -1, -1, 444, 445, 446, 447, 448, 449, 450, + -1, 452, -1, 454, 455, 456, 457, 458, -1, -1, + 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 3, -1, 5, -1, -1, -1, -1, -1, + 481, 482, 483, 484, -1, -1, -1, 488, 489, 490, + -1, 492, 493, 494, 495, 496, 497, 8, -1, -1, + 11, -1, -1, -1, 15, 16, 17, 18, 19, 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, - 31, 32, -1, -1, -1, -1, -1, -1, -1, 40, - 41, -1, 43, 44, 45, -1, 47, 48, 49, 50, - 51, -1, 53, 54, -1, 56, 57, 58, 59, 60, - 61, -1, -1, 64, 65, 66, 67, 68, -1, 70, - 71, 72, 73, 74, -1, -1, -1, 78, 79, 80, - 81, 82, 83, -1, 85, 86, 87, -1, 89, 90, - 91, 92, 93, 94, -1, -1, 97, 98, 99, -1, - -1, -1, -1, -1, -1, -1, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, -1, 118, -1, 120, - 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, - 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, - 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, -1, 160, - -1, 162, 163, 164, 165, -1, 167, -1, 169, -1, - -1, -1, 173, 174, 175, -1, 177, -1, 179, -1, - 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, - 191, -1, 193, 194, 195, 196, -1, 198, 199, 200, - 201, 202, 203, -1, 205, -1, 207, 208, 209, 210, - 211, 212, 213, 214, -1, 216, -1, 218, -1, -1, - 221, -1, 223, 224, 225, 226, 227, 228, -1, -1, - 231, -1, 233, -1, -1, 236, 237, 238, -1, -1, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, -1, 267, 268, 269, 270, - 271, -1, 273, 274, -1, 276, -1, 278, 279, 280, - 281, 282, 283, -1, 285, 286, -1, 288, 289, 290, - 291, -1, -1, 294, 295, -1, 297, -1, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, - 311, 312, 313, 314, 315, 316, 317, 318, 319, -1, - 321, 322, 323, 324, 325, 326, -1, 328, 329, 330, - 331, 332, 333, 334, 335, -1, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, -1, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, -1, 370, - 371, 372, 373, 374, -1, 376, 377, 378, 379, 380, - -1, 382, 383, 384, 385, -1, 387, 388, 389, 390, - 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, -1, 404, 405, -1, 407, -1, 409, 410, - 411, 412, 413, -1, 415, 416, -1, -1, 419, 420, - 421, 422, 423, -1, 425, 426, 427, 428, 429, 430, - 431, 432, -1, -1, 435, 436, 437, 438, 439, -1, - -1, 442, 443, 444, 445, 446, 447, 448, -1, 450, - -1, 452, 453, 454, 455, 456, -1, -1, 459, -1, - -1, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 3, -1, 5, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 35, -1, 8, -1, -1, 11, + -1, -1, 43, 15, 16, 17, 18, 19, 20, 50, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, - 31, 32, -1, -1, -1, -1, -1, -1, -1, 40, - 41, -1, 43, 44, 45, -1, 47, 48, 49, 50, - 51, -1, 53, 54, -1, 56, 57, 58, 59, 60, - 61, -1, -1, 64, 65, 66, 67, 68, -1, 70, - 71, 72, 73, 74, -1, -1, -1, 78, 79, 80, - 81, 82, 83, -1, 85, 86, 87, -1, 89, 90, - 91, 92, 93, 94, -1, -1, 97, 98, 99, -1, - -1, -1, -1, -1, -1, -1, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, -1, 118, -1, 120, - 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, - 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, - 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, -1, 160, - -1, 162, 163, 164, 165, -1, 167, -1, 169, -1, - -1, -1, 173, 174, 175, -1, 177, -1, 179, -1, - 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, - 191, -1, 193, 194, 195, 196, -1, 198, 199, 200, - 201, 202, 203, -1, 205, -1, 207, 208, 209, 210, - 211, 212, 213, 214, -1, 216, -1, 218, -1, -1, - 221, -1, 223, 224, 225, 226, 227, 228, -1, -1, - 231, -1, 233, -1, -1, 236, 237, 238, -1, -1, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, -1, 267, 268, 269, 270, - 271, -1, 273, 274, -1, 276, -1, 278, 279, 280, - 281, 282, 283, -1, 285, 286, -1, 288, 289, 290, - 291, -1, -1, 294, 295, -1, 297, -1, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, - 311, 312, 313, 314, 315, 316, 317, 318, 319, -1, - 321, 322, 323, 324, 325, 326, -1, 328, 329, 330, - 331, 332, 333, 334, 335, -1, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, -1, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, -1, 370, - 371, 372, 373, 374, -1, 376, 377, 378, 379, 380, - -1, 382, 383, 384, 385, -1, 387, 388, 389, 390, - 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, -1, 404, 405, -1, 407, -1, 409, 410, - 411, 412, 413, -1, 415, 416, -1, -1, 419, 420, - 421, 422, 423, -1, 425, 426, 427, 428, 429, 430, - 431, 432, -1, -1, 435, 436, 437, 438, 439, -1, - -1, 442, 443, 444, 445, 446, 447, 448, -1, 450, - -1, 452, 453, 454, 455, 456, -1, -1, 459, -1, - -1, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 3, -1, 5, -1, -1, -1, -1, -1, + -1, -1, -1, 35, -1, -1, -1, -1, -1, -1, + -1, 43, 8, -1, 75, 11, -1, -1, 50, 15, + 16, 17, 18, 19, 20, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 35, + -1, 8, -1, 75, 11, -1, -1, 43, 15, 16, + 17, 18, 19, 20, 50, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 35, -1, + -1, -1, -1, -1, -1, -1, 43, -1, -1, 75, + -1, -1, -1, 50, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, -1, -1, -1, -1, -1, -1, -1, 40, - 41, -1, 43, 44, 45, -1, 47, 48, 49, 50, - 51, -1, 53, 54, -1, 56, 57, 58, 59, 60, - 61, -1, -1, 64, 65, 66, 67, 68, -1, 70, - 71, 72, 73, 74, -1, -1, -1, 78, 79, 80, - 81, 82, 83, -1, 85, 86, 87, -1, 89, 90, - 91, 92, 93, 94, -1, -1, 97, 98, 99, -1, - -1, -1, -1, -1, -1, -1, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, -1, 118, -1, 120, - 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, - 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, - 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, -1, 160, - -1, 162, 163, 164, 165, -1, 167, -1, 169, -1, - -1, -1, 173, 174, 175, -1, 177, -1, 179, -1, - 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, - 191, -1, 193, 194, 195, 196, -1, 198, 199, 200, - 201, 202, 203, -1, 205, -1, 207, 208, 209, 210, - 211, 212, 213, 214, -1, 216, -1, 218, -1, -1, - 221, -1, 223, 224, 225, 226, 227, 228, -1, -1, - 231, -1, 233, -1, -1, 236, 237, 238, -1, -1, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, -1, 267, 268, 269, 270, - 271, -1, 273, 274, -1, 276, -1, 278, 279, 280, - 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, - 291, -1, -1, 294, 295, -1, 297, -1, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, - 311, 312, 313, 314, 315, 316, 317, 318, 319, -1, - 321, 322, 323, 324, 325, 326, -1, 328, 329, 330, - 331, 332, 333, 334, 335, -1, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, -1, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, -1, 370, - 371, 372, 373, 374, -1, 376, 377, 378, 379, 380, - -1, 382, 383, 384, 385, -1, 387, 388, 389, 390, - 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - 401, 402, -1, 404, 405, -1, 407, -1, 409, 410, - 411, 412, 413, -1, 415, 416, -1, -1, 419, 420, - 421, 422, 423, -1, 425, 426, 427, 428, 429, 430, - 431, 432, -1, -1, 435, 436, 437, 438, 439, -1, - -1, 442, 443, 444, 445, 446, 447, 448, -1, 450, - -1, 452, 453, 454, 455, 456, -1, -1, 459, -1, - -1, 462, 463, 464, 465, 466, 467, 468, 469, 470, - 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, - 481, 482, 3, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 75, -1, + -1, -1, -1, -1, -1, 176, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 192, -1, -1, -1, -1, 197, -1, -1, -1, + -1, -1, -1, -1, 176, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 219, 220, + 192, -1, -1, -1, -1, 197, -1, -1, -1, -1, + -1, -1, -1, 234, -1, -1, -1, -1, -1, -1, + 176, -1, -1, -1, -1, -1, -1, 219, 220, -1, + -1, -1, -1, -1, -1, -1, 192, -1, -1, -1, + -1, 197, 234, -1, -1, -1, -1, -1, -1, 176, + -1, 272, -1, -1, 275, -1, -1, -1, -1, -1, + -1, -1, -1, 219, 220, 192, -1, -1, 289, -1, + 197, 292, -1, -1, -1, -1, -1, -1, 234, -1, + 272, -1, -1, 275, -1, -1, -1, -1, -1, -1, + -1, -1, 219, 220, -1, -1, -1, 289, -1, -1, + 292, -1, -1, -1, -1, -1, -1, 234, -1, -1, + -1, -1, -1, -1, -1, -1, 272, -1, -1, 275, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 8, -1, 289, 11, -1, 292, -1, 15, 16, + 17, 18, 19, 20, -1, 272, -1, -1, 275, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 35, -1, + 8, 382, 289, 11, -1, 292, 43, 15, 16, 17, + 18, 19, 20, 50, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 35, -1, -1, + 382, -1, -1, -1, -1, 43, 8, -1, 75, 11, + -1, -1, 50, 15, 16, 17, 18, 19, 20, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 35, -1, -1, 382, 75, -1, -1, + -1, 43, -1, -1, -1, -1, -1, -1, 50, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 382, -1, -1, -1, -1, + -1, -1, -1, 75, 485, -1, -1, 488, 489, 490, + -1, 492, 493, 494, 495, 496, 497, -1, -1, -1, + -1, 502, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 485, -1, -1, 488, 489, 490, 176, + 492, 493, 494, 495, 496, 497, -1, -1, -1, -1, + 502, -1, -1, -1, -1, 192, -1, -1, -1, -1, + 197, -1, -1, -1, -1, -1, -1, -1, 176, 485, + -1, -1, 488, 489, 490, -1, 492, 493, 494, 495, + 496, 497, 219, 220, 192, -1, 502, -1, -1, 197, + -1, -1, -1, -1, -1, -1, -1, 234, 485, -1, + -1, 488, 489, 490, 176, 492, 493, 494, 495, 496, + 497, 219, 220, -1, -1, 502, -1, -1, -1, -1, + 192, -1, -1, -1, -1, 197, 234, -1, -1, -1, + -1, -1, -1, -1, -1, 272, -1, -1, 275, -1, + -1, -1, -1, -1, -1, -1, -1, 219, 220, -1, + -1, -1, 289, -1, -1, 292, -1, -1, -1, -1, + -1, -1, 234, -1, 272, -1, -1, 275, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 8, + -1, 289, 11, -1, 292, -1, 15, 16, 17, 18, + 19, 20, -1, -1, -1, -1, -1, -1, -1, -1, + 272, -1, -1, 275, -1, -1, 35, -1, -1, -1, + -1, -1, -1, -1, 43, 8, -1, 289, 11, -1, + 292, 50, 15, 16, 17, 18, 19, 20, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 35, -1, 8, 382, 75, 11, -1, -1, + 43, 15, 16, 17, 18, 19, 20, 50, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 35, -1, -1, 382, -1, -1, -1, -1, 43, + -1, -1, 75, -1, -1, -1, 50, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 382, 75, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 176, 485, -1, + -1, 488, 489, 490, -1, 492, 493, 494, 495, 496, + 497, -1, -1, 192, -1, 502, -1, -1, 197, -1, + -1, -1, -1, -1, -1, -1, -1, 485, -1, -1, + 488, 489, 490, 176, 492, 493, 494, 495, 496, 497, + 219, 220, -1, -1, 502, -1, -1, -1, -1, 192, + -1, -1, -1, -1, 197, 234, -1, -1, -1, -1, + -1, -1, 176, 485, -1, -1, 488, 489, 490, -1, + 492, 493, 494, 495, 496, 497, 219, 220, 192, -1, + 502, -1, -1, 197, -1, -1, -1, -1, -1, -1, + -1, 234, -1, 272, -1, -1, 275, -1, -1, -1, + -1, -1, -1, -1, -1, 219, 220, -1, -1, -1, + 289, -1, -1, 292, -1, -1, -1, -1, -1, -1, + 234, -1, -1, -1, -1, -1, -1, -1, -1, 272, + -1, -1, 275, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8, -1, 289, 11, -1, 292, + -1, 15, 16, 17, 18, 19, 20, -1, 272, -1, + -1, 275, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 35, -1, 8, -1, 289, 11, -1, 292, 43, + 15, 16, 17, 18, 19, 20, 50, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 35, -1, -1, 382, -1, -1, -1, -1, 43, 8, + -1, 75, 11, -1, -1, 50, 15, 16, 17, 18, + 19, 20, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 35, -1, -1, 382, + 75, -1, -1, -1, 43, -1, -1, -1, -1, -1, + -1, 50, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 382, -1, + -1, -1, -1, -1, -1, -1, 75, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 485, -1, -1, 488, + 489, 490, 176, 492, 493, 494, 495, 496, 497, -1, + -1, -1, -1, 502, -1, -1, -1, -1, 192, -1, + -1, -1, -1, 197, -1, -1, -1, -1, -1, -1, + -1, 176, 485, -1, -1, 488, 489, 490, -1, 492, + 493, 494, 495, 496, 497, 219, 220, 192, -1, 502, + -1, -1, 197, -1, -1, -1, -1, -1, -1, -1, + 234, 485, -1, -1, 488, 489, 490, 176, 492, 493, + 494, 495, 496, 497, 219, 220, -1, -1, 502, -1, + -1, -1, -1, 192, -1, -1, -1, -1, 197, 234, + -1, -1, -1, -1, -1, -1, -1, -1, 272, -1, + -1, 275, -1, -1, -1, -1, -1, -1, -1, -1, + 219, 220, -1, -1, -1, 289, -1, -1, 292, -1, + -1, -1, -1, -1, -1, 234, -1, 272, -1, -1, + 275, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 289, -1, -1, 292, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 272, -1, -1, 275, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 289, -1, -1, 292, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 382, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 382, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 382, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 485, -1, -1, 488, 489, 490, -1, 492, 493, + 494, 495, 496, 497, -1, -1, 500, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 485, -1, -1, 488, 489, 490, -1, 492, 493, 494, + 495, 496, 497, -1, -1, 500, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 3, -1, 485, -1, -1, 488, + 489, 490, -1, 492, 493, 494, 495, 496, 497, -1, + -1, 500, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, + 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, + 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, + 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, + 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, + 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, + 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, + 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, + 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, + 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, + 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, + 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, + 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, + 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, + 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, + 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, + 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, + 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, + 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, + 479, 480, 481, 482, 483, 484, 3, -1, -1, -1, + -1, -1, -1, -1, -1, 494, -1, -1, -1, -1, + -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, + 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, + -1, -1, -1, 40, 41, -1, 43, 44, 45, -1, + 47, 48, 49, 50, 51, -1, 53, 54, -1, 56, + 57, 58, 59, 60, 61, -1, -1, 64, 65, 66, + 67, 68, -1, 70, 71, 72, 73, 74, -1, -1, + -1, 78, 79, 80, 81, 82, 83, -1, 85, 86, + 87, -1, 89, 90, 91, 92, 93, 94, -1, -1, + 97, 98, 99, -1, -1, -1, -1, -1, -1, -1, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + -1, 118, -1, 120, 121, 122, 123, 124, 125, -1, + 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, + 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, + -1, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, -1, 160, -1, 162, 163, 164, 165, -1, + 167, -1, 169, -1, -1, -1, 173, 174, 175, -1, + 177, -1, 179, -1, 181, 182, 183, -1, 185, 186, + 187, 188, 189, 190, 191, -1, 193, 194, 195, 196, + -1, 198, 199, 200, 201, 202, 203, -1, 205, -1, + 207, 208, 209, 210, 211, 212, 213, 214, -1, 216, + -1, 218, -1, -1, 221, -1, 223, 224, 225, 226, + 227, 228, -1, -1, 231, -1, 233, -1, -1, 236, + 237, 238, -1, -1, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, -1, + 267, 268, 269, 270, 271, -1, 273, 274, -1, 276, + -1, 278, 279, 280, 281, 282, 283, -1, 285, 286, + -1, -1, 289, 290, 291, -1, -1, 294, 295, -1, + 297, -1, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, -1, 311, 312, 313, -1, 315, 316, + 317, 318, 319, 320, -1, 322, 323, 324, 325, 326, + 327, -1, 329, 330, 331, 332, 333, 334, 335, 336, + -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, -1, 352, 353, -1, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, + 367, 368, 369, -1, 371, 372, 373, 374, 375, -1, + 377, 378, 379, 380, 381, -1, 383, 384, 385, 386, + -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, -1, 405, 406, + -1, 408, -1, 410, 411, 412, 413, 414, -1, 416, + 417, -1, -1, 420, 421, 422, 423, 424, -1, 426, + 427, 428, 429, 430, 431, 432, 433, -1, -1, 436, + 437, 438, 439, 440, 441, -1, -1, 444, 445, 446, + 447, 448, 449, 450, -1, 452, -1, 454, 455, 456, + 457, 458, -1, -1, 461, -1, -1, 464, 465, 466, + 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, + 477, 478, 479, 480, 481, 482, 483, 484, 3, -1, + -1, -1, -1, -1, -1, -1, -1, 494, -1, -1, + -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, + 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, + -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, + 45, -1, 47, 48, 49, 50, 51, -1, 53, 54, + -1, 56, 57, 58, 59, 60, 61, -1, -1, 64, + 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, + -1, -1, -1, 78, 79, 80, 81, 82, 83, -1, + 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, + -1, -1, 97, 98, 99, -1, -1, -1, -1, -1, + -1, -1, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, -1, 118, -1, 120, 121, 122, 123, 124, + 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, + 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, + 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, -1, 160, -1, 162, 163, 164, + 165, -1, 167, -1, 169, -1, -1, -1, 173, 174, + 175, -1, 177, -1, 179, -1, 181, 182, 183, -1, + 185, 186, 187, 188, 189, 190, 191, -1, 193, 194, + 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, + 205, -1, 207, 208, 209, 210, 211, 212, 213, 214, + -1, 216, -1, 218, -1, -1, 221, -1, 223, 224, + 225, 226, 227, 228, -1, -1, 231, -1, 233, -1, + -1, 236, 237, 238, -1, -1, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, -1, 267, 268, 269, 270, 271, -1, 273, 274, + -1, 276, -1, 278, 279, 280, 281, 282, 283, -1, + 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, + 295, -1, 297, -1, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, -1, 311, 312, 313, -1, + 315, 316, 317, 318, 319, 320, -1, 322, 323, 324, + 325, 326, 327, -1, 329, 330, 331, 332, 333, 334, + 335, 336, -1, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, -1, 352, 353, -1, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, + 375, -1, 377, 378, 379, 380, 381, -1, 383, 384, + 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, -1, + 405, 406, -1, 408, -1, 410, 411, 412, 413, 414, + -1, 416, 417, -1, -1, 420, 421, 422, 423, 424, + -1, 426, 427, 428, 429, 430, 431, 432, 433, -1, + -1, 436, 437, 438, 439, 440, 441, -1, -1, 444, + 445, 446, 447, 448, 449, 450, -1, 452, -1, 454, + 455, 456, 457, 458, -1, -1, 461, -1, -1, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, + 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 3, 4, 5, -1, -1, -1, 9, -1, -1, 494, + -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, + 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, + -1, -1, -1, -1, -1, -1, -1, 40, 41, -1, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, -1, 56, 57, 58, 59, 60, 61, -1, + -1, 64, 65, 66, 67, 68, -1, 70, 71, 72, + 73, 74, -1, 76, -1, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, + 93, 94, -1, 96, 97, 98, 99, 100, 101, 102, + 103, -1, -1, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, -1, 120, 121, 122, + 123, 124, 125, -1, 127, 128, 129, 130, 131, -1, + -1, 134, 135, 136, 137, 138, -1, 140, 141, 142, + -1, 144, 145, 146, -1, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, -1, 162, + 163, 164, 165, -1, 167, -1, 169, 170, -1, 172, + 173, 174, 175, 176, 177, -1, 179, -1, 181, 182, + 183, -1, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, -1, 198, 199, 200, 201, 202, + 203, -1, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, -1, 216, -1, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, -1, -1, 231, 232, + 233, 234, -1, 236, 237, 238, -1, -1, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, -1, + 273, 274, 275, 276, -1, 278, 279, 280, 281, 282, + 283, -1, 285, 286, 287, -1, 289, 290, 291, -1, + -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, + 313, 314, 315, 316, 317, 318, 319, 320, -1, 322, + 323, 324, 325, 326, 327, -1, 329, 330, 331, 332, + 333, 334, 335, 336, -1, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, -1, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 368, 369, -1, 371, 372, + 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, + 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, -1, 405, 406, -1, 408, 409, 410, 411, 412, + 413, 414, -1, 416, 417, -1, -1, 420, 421, 422, + 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, + 433, -1, -1, 436, 437, 438, 439, 440, 441, 442, + -1, 444, 445, 446, 447, 448, 449, 450, -1, 452, + 453, 454, 455, 456, 457, 458, -1, -1, 461, -1, + -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, + 483, 484, 3, 4, 5, -1, -1, -1, 9, 492, + 493, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, 40, - 41, -1, 43, 44, 45, 46, 47, 48, 49, -1, - 51, 52, 53, 54, -1, 56, 57, 58, 59, 60, - 61, -1, -1, 64, 65, 66, 67, 68, -1, 70, - 71, 72, 73, -1, -1, 76, -1, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, -1, 89, 90, - 91, 92, 93, 94, -1, 96, 97, 98, 99, 100, - 101, 102, 103, -1, -1, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, -1, 118, -1, 120, - 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, - 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, - 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, - 151, -1, 153, 154, 155, 156, 157, -1, -1, 160, - -1, 162, 163, 164, 165, -1, 167, -1, 169, 170, - -1, 172, 173, 174, -1, 176, 177, -1, 179, -1, - -1, -1, 183, -1, 185, 186, 187, 188, 189, 190, - 191, 192, 193, 194, 195, 196, -1, 198, 199, 200, - 201, 202, 203, -1, 205, 206, -1, 208, 209, 210, - 211, 212, 213, 214, -1, 216, -1, 218, 219, 220, - 221, 222, 223, 224, 225, 226, 227, 228, -1, -1, - 231, 232, 233, 234, -1, 236, 237, 238, -1, -1, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - -1, -1, 273, 274, 275, 276, -1, -1, 279, 280, - 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, - 291, -1, -1, 294, -1, 296, 297, 298, -1, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, - 311, 312, -1, 314, 315, -1, 317, 318, 319, -1, - 321, 322, 323, 324, 325, 326, -1, 328, 329, 330, - 331, 332, 333, 334, 335, -1, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, -1, 370, - 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, -1, 387, 388, 389, 390, - 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - -1, 402, -1, 404, 405, -1, 407, 408, 409, 410, - 411, 412, 413, -1, 415, 416, -1, -1, 419, 420, - -1, 422, -1, -1, 425, 426, 427, 428, 429, 430, - 431, 432, 433, -1, 435, 436, 437, 438, 439, 440, - -1, 442, 443, 444, 445, 446, -1, 448, -1, 450, - 451, 452, 453, 454, 455, 456, -1, -1, 459, -1, - -1, 462, 463, 464, 465, 466, 467, 3, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 479, 480, - 481, 482, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - 46, 47, 48, 49, -1, 51, 52, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, -1, -1, - 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - 96, 97, 98, 99, 100, 101, 102, 103, -1, -1, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, -1, 153, 154, 155, - 156, 157, -1, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, 170, -1, 172, 173, 174, -1, - 176, 177, -1, 179, -1, -1, -1, 183, -1, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - 206, -1, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, -1, -1, 231, 232, 233, 234, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, -1, -1, 273, 274, 275, - 276, -1, -1, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, -1, - 296, 297, 298, -1, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, -1, 314, 315, - -1, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, 353, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, 375, - 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, -1, 402, -1, 404, 405, - -1, 407, 408, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, -1, 422, -1, -1, 425, - 426, 427, 428, 429, 430, 431, 432, 433, -1, 435, - 436, 437, 438, 439, 440, -1, 442, 443, 444, 445, - 446, -1, 448, -1, 450, 451, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 479, 480, 481, 482, -1, -1, -1, - 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, - 31, 32, -1, -1, -1, -1, -1, -1, -1, 40, - 41, -1, 43, 44, 45, 46, 47, 48, 49, -1, + 41, -1, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, -1, 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, 66, 67, 68, -1, 70, - 71, 72, 73, -1, -1, 76, -1, 78, 79, 80, + 71, 72, 73, 74, -1, 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, 96, 97, 98, 99, 100, 101, 102, 103, -1, -1, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, -1, 118, -1, 120, + 111, 112, 113, 114, 115, 116, 117, 118, -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, - 151, -1, 153, 154, 155, 156, 157, -1, -1, 160, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, -1, 162, 163, 164, 165, -1, 167, -1, 169, 170, - -1, 172, 173, 174, -1, 176, 177, -1, 179, -1, - -1, -1, 183, -1, 185, 186, 187, 188, 189, 190, + -1, 172, 173, 174, 175, 176, 177, -1, 179, -1, + 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, -1, 198, 199, 200, - 201, 202, 203, -1, 205, 206, -1, 208, 209, 210, + 201, 202, 203, -1, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, -1, 216, -1, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, -1, -1, 231, 232, 233, 234, -1, 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - -1, -1, 273, 274, 275, 276, -1, -1, 279, 280, - 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, - 291, -1, -1, 294, -1, 296, 297, 298, -1, 300, + 271, -1, 273, 274, 275, 276, -1, 278, 279, 280, + 281, 282, 283, -1, 285, 286, 287, -1, 289, 290, + 291, -1, -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, - 311, 312, -1, 314, 315, -1, 317, 318, 319, -1, - 321, 322, 323, 324, 325, 326, -1, 328, 329, 330, - 331, 332, 333, 334, 335, -1, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, -1, 370, + 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, + -1, 322, 323, 324, 325, 326, 327, -1, 329, 330, + 331, 332, 333, 334, 335, 336, -1, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, + -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 361, 362, 363, 364, 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, - 381, 382, 383, 384, 385, -1, 387, 388, 389, 390, + 381, 382, 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, - -1, 402, -1, 404, 405, -1, 407, 408, 409, 410, - 411, 412, 413, -1, 415, 416, -1, -1, 419, 420, - -1, 422, -1, -1, 425, 426, 427, 428, 429, 430, - 431, 432, 433, -1, 435, 436, 437, 438, 439, 440, - -1, 442, 443, 444, 445, 446, -1, 448, -1, 450, - 451, 452, 453, 454, 455, 456, -1, -1, 459, -1, - -1, 462, 463, 464, 465, 466, 467, 3, 4, -1, - -1, -1, -1, 9, -1, -1, -1, -1, 479, 480, - 481, 482, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, 5, + 401, 402, 403, -1, 405, 406, -1, 408, 409, 410, + 411, 412, 413, 414, -1, 416, 417, -1, -1, 420, + 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, + 431, 432, 433, -1, -1, 436, 437, 438, 439, 440, + 441, 442, -1, 444, 445, 446, 447, 448, 449, 450, + -1, 452, 453, 454, 455, 456, 457, 458, -1, -1, + 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, + 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 3, 4, 5, -1, -1, -1, + 9, 492, 493, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, + -1, 30, 31, 32, -1, -1, -1, -1, -1, -1, + -1, 40, 41, -1, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, -1, 56, 57, 58, + 59, 60, 61, -1, -1, 64, 65, 66, 67, 68, + -1, 70, 71, 72, 73, 74, -1, 76, -1, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, + 89, 90, 91, 92, 93, 94, -1, 96, 97, 98, + 99, 100, 101, 102, 103, -1, -1, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, -1, 118, + -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, + 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, + -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + 159, 160, -1, 162, 163, 164, 165, -1, 167, -1, + 169, 170, -1, 172, 173, 174, 175, 176, 177, -1, + 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, -1, 198, + 199, 200, 201, 202, 203, -1, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, -1, 216, -1, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + -1, -1, 231, 232, 233, 234, -1, 236, 237, 238, + -1, -1, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, -1, 273, 274, 275, 276, -1, 278, + 279, 280, 281, 282, 283, -1, 285, 286, 287, -1, + 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, -1, 311, 312, 313, 314, 315, 316, 317, 318, + 319, 320, -1, 322, 323, 324, 325, 326, 327, -1, + 329, 330, 331, 332, 333, 334, 335, 336, -1, 338, + 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, + 349, 350, -1, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, + 369, -1, 371, 372, 373, 374, 375, 376, 377, 378, + 379, 380, 381, 382, 383, 384, 385, 386, -1, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, -1, 405, 406, -1, 408, + 409, 410, 411, 412, 413, 414, -1, 416, 417, -1, + -1, 420, 421, 422, 423, 424, 425, 426, 427, 428, + 429, 430, 431, 432, 433, -1, -1, 436, 437, 438, + 439, 440, 441, 442, -1, 444, 445, 446, 447, 448, + 449, 450, -1, 452, 453, 454, 455, 456, 457, 458, + -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, + 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, + 479, 480, 481, 482, 483, 484, -1, -1, 8, -1, + -1, 11, -1, 492, 493, 15, 16, 17, 18, 19, + 20, 8, -1, -1, 11, -1, -1, -1, 15, 16, + 17, 18, 19, 20, -1, 35, -1, -1, -1, 39, + -1, -1, -1, 43, -1, -1, -1, -1, 35, -1, + 50, -1, -1, -1, -1, -1, 43, 8, -1, -1, + 11, -1, -1, 50, 15, 16, 17, 18, 19, 20, + 8, -1, -1, 11, -1, 75, -1, 15, 16, 17, + 18, 19, 20, -1, 35, -1, -1, -1, 75, -1, + -1, -1, 43, -1, -1, -1, -1, 35, -1, 50, + 38, -1, -1, -1, -1, 43, 8, -1, -1, 11, + -1, -1, 50, 15, 16, 17, 18, 19, 20, -1, + -1, -1, -1, -1, 75, -1, 126, -1, -1, -1, + -1, -1, -1, 35, -1, -1, -1, 75, -1, -1, + -1, 43, -1, -1, -1, -1, -1, -1, 50, -1, + -1, 8, -1, -1, 11, -1, -1, -1, 15, 16, + 17, 18, 19, 20, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 75, -1, -1, 176, -1, 35, 166, + -1, 38, -1, -1, 171, -1, 43, -1, -1, 176, + -1, -1, 192, 50, -1, -1, -1, 197, -1, -1, + -1, -1, -1, -1, -1, 192, -1, -1, -1, -1, + 197, -1, -1, -1, 165, -1, -1, -1, 75, 219, + 220, -1, -1, -1, -1, 176, -1, -1, -1, -1, + -1, -1, 219, 220, 234, -1, -1, -1, 176, -1, + -1, 192, -1, -1, -1, -1, 197, 234, -1, -1, + -1, -1, -1, -1, 192, -1, -1, -1, -1, 197, + -1, -1, -1, -1, -1, -1, -1, -1, 219, 220, + -1, -1, 272, -1, 176, 275, -1, -1, -1, -1, + -1, 219, 220, 234, -1, 272, -1, -1, 275, 289, + 192, -1, 292, -1, -1, 197, 234, -1, -1, -1, + -1, -1, 289, -1, -1, 292, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 219, 220, 176, + -1, 272, -1, -1, 275, -1, -1, -1, -1, -1, + -1, -1, 234, -1, 272, 192, -1, 275, 289, -1, + 197, 292, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 289, -1, -1, 292, -1, -1, -1, -1, -1, + -1, -1, 219, 220, -1, 316, -1, -1, -1, -1, + 272, -1, -1, 275, -1, -1, -1, 234, -1, -1, + -1, -1, 382, -1, -1, -1, -1, 289, -1, -1, + 292, -1, -1, -1, -1, 382, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 310, -1, + -1, -1, -1, -1, -1, 272, -1, -1, 275, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - 406, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, 5, + -1, 382, 289, -1, -1, 292, -1, -1, -1, -1, + -1, -1, -1, 443, 382, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, 5, + 382, -1, -1, -1, -1, 485, -1, -1, 488, 489, + 490, -1, 492, 493, 494, 495, 496, 497, 485, -1, + -1, 488, 489, 490, -1, 492, 493, 494, 495, 496, + 497, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 382, -1, -1, -1, -1, + -1, -1, -1, -1, 485, -1, -1, 488, 489, 490, + -1, 492, 493, 494, 495, 496, 497, 485, -1, -1, + 488, 489, 490, -1, 492, 493, 494, 495, 496, 497, + -1, -1, 8, -1, -1, 11, -1, -1, -1, 15, + 16, 17, 18, 19, 20, -1, -1, -1, -1, -1, + -1, -1, -1, 485, -1, -1, 488, 489, 490, 35, + 492, 493, 494, 495, 496, 497, -1, 43, -1, -1, + -1, -1, -1, -1, 50, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, 5, + -1, -1, -1, -1, -1, -1, -1, -1, 485, 75, + -1, 488, 489, 490, -1, 492, 493, 494, 495, 496, + 497, 8, -1, -1, 11, -1, -1, -1, 15, 16, + 17, 18, 19, 20, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 35, -1, + -1, 38, -1, -1, -1, -1, 43, -1, -1, -1, + -1, -1, -1, 50, -1, -1, 8, -1, -1, 11, + -1, -1, -1, 15, 16, 17, 18, 19, 20, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 75, -1, + -1, -1, -1, 35, -1, -1, -1, -1, -1, -1, + -1, 43, -1, -1, -1, 171, -1, -1, 50, -1, + 176, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 192, -1, -1, -1, + -1, 197, -1, 75, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, 5, + -1, -1, -1, 219, 220, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 234, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, 5, + -1, -1, -1, -1, -1, 8, -1, -1, 11, 176, + -1, -1, 15, 16, 17, 18, 19, 20, -1, -1, + -1, -1, -1, -1, -1, 192, 272, -1, -1, 275, + 197, -1, 35, -1, -1, -1, -1, -1, -1, -1, + 43, -1, -1, 289, 166, -1, 292, 50, -1, -1, + -1, -1, 219, 220, 176, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 234, -1, -1, + 192, -1, 75, -1, -1, 197, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, 5, + -1, -1, -1, -1, -1, -1, -1, 219, 220, -1, + -1, -1, -1, -1, -1, 272, -1, -1, 275, -1, + -1, -1, 234, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 289, -1, -1, 292, -1, -1, -1, -1, + 8, -1, -1, 11, -1, -1, 382, 15, 16, 17, + 18, 19, 20, -1, -1, -1, -1, -1, -1, -1, + 272, -1, -1, 275, -1, -1, -1, 35, -1, -1, + 38, -1, -1, -1, -1, 43, -1, 289, -1, -1, + 292, -1, 50, 176, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 192, + -1, -1, 8, -1, 197, 11, -1, 75, -1, 15, + 16, 17, 18, 19, 20, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 382, 219, 220, -1, 35, + -1, -1, -1, -1, -1, -1, -1, 43, -1, -1, + -1, 234, -1, -1, 50, -1, -1, -1, -1, 485, + -1, -1, 488, 489, 490, -1, 492, 493, 494, 495, + 496, 497, -1, -1, -1, -1, -1, -1, -1, 75, + 382, -1, -1, -1, -1, -1, -1, -1, -1, 272, + -1, -1, 275, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 289, -1, -1, 292, + -1, -1, -1, -1, -1, -1, -1, -1, 176, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, 5, + -1, -1, -1, -1, 192, -1, -1, -1, 485, 197, + -1, 488, 489, 490, -1, 492, 493, 494, 495, 496, + 497, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 219, 220, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 234, -1, -1, -1, + 176, -1, -1, 485, -1, -1, 488, 489, 490, -1, + 492, 493, 494, 495, 496, 497, 192, -1, -1, 382, + 8, 197, -1, 11, -1, -1, -1, 15, 16, 17, + 18, 19, 20, -1, 272, -1, -1, 275, -1, -1, + -1, -1, -1, 219, 220, -1, -1, 35, -1, -1, + -1, 289, 415, -1, 292, 43, -1, -1, 234, -1, + -1, -1, 50, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 75, -1, -1, + -1, -1, -1, -1, -1, -1, 272, -1, -1, 275, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, 38, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, + -1, -1, -1, 289, -1, -1, 292, -1, -1, -1, + -1, -1, 485, -1, -1, 488, 489, 490, -1, 492, + 493, 494, 495, 496, 497, -1, -1, -1, 8, -1, + -1, 11, -1, -1, 382, 15, -1, -1, 18, 19, + 20, -1, -1, -1, -1, -1, 8, -1, -1, 11, + -1, -1, -1, 15, -1, 35, 18, 19, 20, -1, + -1, -1, -1, 43, -1, -1, -1, -1, -1, -1, + 50, -1, -1, -1, -1, -1, -1, -1, 176, -1, + -1, 43, -1, -1, -1, -1, -1, -1, 50, -1, + -1, -1, -1, -1, 192, 75, 382, -1, -1, 197, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, 38, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, 5, + -1, -1, -1, 75, -1, -1, -1, -1, -1, -1, + -1, 219, 220, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 234, 485, -1, -1, + 488, 489, 490, -1, 492, 493, 494, 495, 496, 497, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, 5, + -1, -1, -1, -1, 272, -1, -1, 275, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, 5, + -1, 289, -1, -1, 292, -1, 176, -1, -1, 485, + -1, -1, 488, 489, 490, -1, 492, 493, 494, 495, + 496, 497, 192, -1, 176, -1, -1, 197, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, 5, + 192, -1, -1, -1, -1, 197, -1, -1, -1, 219, + 220, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 234, -1, -1, 219, 220, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, + -1, -1, 234, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 382, -1, -1, -1, -1, -1, + -1, -1, 272, -1, -1, 275, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 289, + 272, -1, 292, 275, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 289, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 485, -1, -1, + 488, 489, 490, -1, 492, 493, 494, 495, 496, 497, + -1, -1, 382, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 382, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 485, -1, -1, 488, 489, + 490, -1, 492, 493, 494, 495, 496, 497, 3, -1, + 5, -1, -1, 485, -1, -1, 488, 489, 490, -1, + 492, 493, 494, 495, 496, 497, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, + 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, + 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, + 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, + 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, + 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, + 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, + 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, + 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, + 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, + 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, + 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, + 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, + 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, + 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, + 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, + 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, + 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, + 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, + 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, + 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, + 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, + 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, + 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, + 483, 484, 3, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, + 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, + 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, + 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, + 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, + 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, + 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, + 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, + 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, + 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, + 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, + 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, + 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, + 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, + 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, + 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, + 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, + 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, + 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, + 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, + 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, + 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, + 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, + 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 3, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, + -1, 30, 31, 32, -1, -1, -1, -1, -1, -1, + -1, 40, 41, -1, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, -1, 56, 57, 58, + 59, 60, 61, -1, 63, 64, 65, 66, 67, 68, + -1, 70, 71, 72, 73, 74, -1, 76, -1, 78, + 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, + 89, 90, 91, 92, 93, 94, -1, 96, 97, 98, + 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, -1, 118, + -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, + 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, + -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + -1, 160, -1, 162, 163, 164, 165, -1, 167, -1, + 169, 170, -1, 172, 173, 174, 175, 176, 177, -1, + 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, + 189, 190, 191, 192, 193, 194, 195, 196, -1, 198, + 199, 200, 201, 202, 203, -1, 205, 206, 207, 208, + 209, 210, 211, 212, 213, 214, -1, 216, -1, 218, + 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, + -1, -1, 231, 232, 233, 234, -1, 236, 237, 238, + 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 271, -1, 273, 274, 275, 276, -1, 278, + 279, 280, 281, 282, 283, -1, 285, 286, -1, -1, + 289, 290, 291, -1, -1, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, -1, 311, 312, 313, 314, 315, 316, 317, 318, + 319, 320, -1, 322, 323, 324, 325, 326, 327, -1, + 329, 330, 331, 332, 333, 334, 335, 336, -1, 338, + 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, + 349, 350, -1, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, + 369, -1, 371, 372, 373, 374, 375, 376, 377, 378, + 379, 380, 381, 382, 383, 384, 385, 386, -1, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, -1, 405, 406, -1, 408, + 409, 410, 411, 412, 413, 414, -1, 416, 417, -1, + -1, 420, 421, 422, 423, 424, -1, 426, 427, 428, + 429, 430, 431, 432, 433, -1, -1, 436, 437, 438, + 439, 440, 441, 442, -1, 444, 445, 446, 447, 448, + 449, 450, -1, 452, 453, 454, 455, 456, 457, 458, + -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, + 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, + 479, 480, 481, 482, 483, 484, 3, -1, 5, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, + 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, + -1, -1, -1, 40, 41, -1, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, -1, 56, + 57, 58, 59, 60, 61, -1, -1, 64, 65, 66, + 67, 68, -1, 70, 71, 72, 73, 74, -1, 76, + -1, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, -1, 89, 90, 91, 92, 93, 94, -1, 96, + 97, 98, 99, 100, 101, 102, 103, -1, -1, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + -1, 118, -1, 120, 121, 122, 123, 124, 125, -1, + 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, + 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, + -1, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, -1, 162, 163, 164, 165, -1, + 167, -1, 169, 170, -1, 172, 173, 174, 175, 176, + 177, -1, 179, -1, 181, 182, 183, -1, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + -1, 198, 199, 200, 201, 202, 203, -1, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, -1, 216, + -1, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, -1, -1, 231, 232, 233, 234, -1, 236, + 237, 238, -1, -1, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, -1, 273, 274, 275, 276, + -1, 278, 279, 280, 281, 282, 283, -1, 285, 286, + 287, -1, 289, 290, 291, -1, -1, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, -1, 311, 312, 313, 314, 315, 316, + 317, 318, 319, 320, -1, 322, 323, 324, 325, 326, + 327, -1, 329, 330, 331, 332, 333, 334, 335, 336, + -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, -1, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, + 367, 368, 369, -1, 371, 372, 373, 374, 375, 376, + 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, + -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, -1, 405, 406, + -1, 408, 409, 410, 411, 412, 413, 414, -1, 416, + 417, -1, -1, 420, 421, 422, 423, 424, 425, 426, + 427, 428, 429, 430, 431, 432, 433, -1, -1, 436, + 437, 438, 439, 440, 441, 442, -1, 444, 445, 446, + 447, 448, 449, 450, -1, 452, 453, 454, 455, 456, + 457, 458, -1, -1, 461, -1, -1, 464, 465, 466, + 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, + 477, 478, 479, 480, 481, 482, 483, 484, 3, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, + 25, 26, 27, 28, -1, 30, 31, 32, 33, 34, + -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + -1, 56, 57, 58, 59, 60, 61, -1, -1, 64, + 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, + -1, 76, -1, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, + -1, 96, 97, 98, 99, 100, 101, 102, 103, -1, + -1, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, -1, 118, -1, 120, 121, 122, 123, 124, + 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, + 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, + 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, -1, 160, -1, 162, 163, 164, + 165, -1, 167, -1, 169, 170, -1, 172, 173, 174, + 175, 176, 177, -1, 179, -1, 181, 182, 183, -1, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + -1, 216, -1, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, -1, -1, 231, 232, 233, 234, + -1, 236, 237, 238, -1, -1, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, -1, 273, 274, + 275, 276, -1, 278, 279, 280, 281, 282, 283, -1, + 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, -1, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, -1, 322, 323, 324, + 325, 326, 327, -1, 329, 330, 331, 332, 333, 334, + 335, 336, -1, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, -1, 352, 353, 354, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, + 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, -1, + 405, 406, -1, 408, 409, 410, 411, 412, 413, 414, + -1, 416, 417, -1, -1, 420, 421, 422, 423, 424, + -1, 426, 427, 428, 429, 430, 431, 432, 433, -1, + -1, 436, 437, 438, 439, 440, 441, 442, -1, 444, + 445, 446, 447, 448, 449, 450, -1, 452, 453, 454, + 455, 456, 457, 458, -1, -1, 461, -1, -1, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, + 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, + 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, + -1, -1, -1, -1, -1, -1, -1, 40, 41, -1, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, -1, 56, 57, 58, 59, 60, 61, -1, + -1, 64, 65, 66, 67, 68, -1, 70, 71, 72, + 73, 74, -1, 76, -1, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, + 93, 94, -1, 96, 97, 98, 99, 100, 101, 102, + 103, -1, -1, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, -1, 118, -1, 120, 121, 122, + 123, 124, 125, -1, 127, 128, 129, 130, 131, -1, + -1, 134, 135, 136, 137, 138, -1, 140, 141, 142, + -1, 144, 145, 146, -1, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, -1, 160, -1, 162, + 163, 164, 165, -1, 167, -1, 169, 170, -1, 172, + 173, 174, 175, 176, 177, -1, 179, -1, 181, 182, + 183, -1, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, -1, 198, 199, 200, 201, 202, + 203, -1, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, -1, 216, -1, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, -1, -1, 231, 232, + 233, 234, -1, 236, 237, 238, -1, -1, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, 271, -1, + 273, 274, 275, 276, -1, 278, 279, 280, 281, 282, + 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, + -1, 294, 295, 296, 297, 298, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, + 313, 314, 315, 316, 317, 318, 319, 320, -1, 322, + 323, 324, 325, 326, 327, -1, 329, 330, 331, 332, + 333, 334, 335, 336, -1, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, -1, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 368, 369, -1, 371, 372, + 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, + 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, -1, 405, 406, -1, 408, 409, 410, 411, 412, + 413, 414, -1, 416, 417, -1, -1, 420, 421, 422, + 423, 424, -1, 426, 427, 428, 429, 430, 431, 432, + 433, -1, -1, 436, 437, 438, 439, 440, 441, 442, + -1, 444, 445, 446, 447, 448, 449, 450, -1, 452, + 453, 454, 455, 456, 457, 458, -1, -1, 461, -1, + -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, + 483, 484, 3, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, + 31, 32, -1, -1, -1, -1, -1, -1, -1, 40, + 41, -1, 43, 44, 45, -1, 47, 48, 49, 50, + 51, -1, 53, 54, -1, 56, 57, 58, 59, 60, + 61, -1, -1, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, -1, -1, 77, 78, 79, 80, + 81, 82, 83, -1, 85, 86, 87, 88, 89, 90, + 91, 92, 93, 94, -1, -1, 97, 98, 99, -1, + -1, -1, -1, -1, -1, -1, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, -1, 118, -1, 120, + 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, + 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, + 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, -1, 160, + -1, 162, 163, 164, 165, -1, 167, 168, 169, -1, + -1, -1, 173, 174, 175, -1, 177, -1, 179, -1, + 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, + 191, -1, 193, 194, 195, 196, -1, 198, 199, 200, + 201, 202, 203, -1, 205, -1, 207, 208, 209, 210, + 211, 212, 213, 214, -1, 216, -1, 218, -1, -1, + 221, -1, 223, 224, 225, 226, 227, 228, -1, -1, + 231, -1, 233, -1, -1, 236, 237, 238, -1, -1, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, -1, 267, 268, 269, 270, + 271, -1, 273, 274, -1, 276, -1, 278, 279, 280, + 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, + 291, -1, -1, 294, 295, -1, 297, -1, 299, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, + 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, + 321, 322, 323, 324, 325, 326, 327, -1, 329, 330, + 331, 332, 333, 334, 335, 336, -1, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, + -1, 352, 353, -1, 355, 356, 357, 358, 359, 360, + 361, 362, 363, 364, 365, 366, 367, 368, 369, -1, + 371, 372, 373, 374, 375, -1, 377, 378, 379, 380, + 381, -1, 383, 384, 385, 386, -1, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, -1, 405, 406, -1, 408, -1, 410, + 411, 412, 413, 414, -1, 416, 417, -1, -1, 420, + 421, 422, 423, 424, -1, 426, 427, 428, 429, 430, + 431, 432, 433, -1, 435, 436, 437, 438, 439, 440, + 441, -1, -1, 444, 445, 446, 447, 448, 449, 450, + -1, 452, -1, 454, 455, 456, 457, 458, -1, -1, + 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, + 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 3, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, + -1, 30, 31, 32, -1, -1, -1, -1, -1, -1, + -1, 40, 41, -1, 43, 44, 45, -1, 47, 48, + 49, 50, 51, -1, 53, 54, -1, 56, 57, 58, + 59, 60, 61, -1, -1, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, -1, -1, -1, 78, + 79, 80, 81, 82, 83, -1, 85, 86, 87, 88, + 89, 90, 91, 92, 93, 94, -1, -1, 97, 98, + 99, -1, -1, -1, -1, -1, -1, -1, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, -1, 118, + -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, + 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, + -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + -1, 160, -1, 162, 163, 164, 165, -1, 167, 168, + 169, -1, -1, -1, 173, 174, 175, -1, 177, -1, + 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, + 189, 190, 191, -1, 193, 194, 195, 196, -1, 198, + 199, 200, 201, 202, 203, -1, 205, -1, 207, 208, + 209, 210, 211, 212, 213, 214, -1, 216, -1, 218, + -1, -1, 221, -1, 223, 224, 225, 226, 227, 228, + -1, -1, 231, -1, 233, 234, -1, 236, 237, 238, + -1, -1, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, -1, 267, 268, + 269, 270, 271, -1, 273, 274, -1, 276, -1, 278, + 279, 280, 281, 282, 283, -1, 285, 286, -1, -1, + 289, 290, 291, -1, -1, 294, 295, -1, 297, -1, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, -1, 311, 312, 313, -1, 315, 316, 317, 318, + 319, 320, 321, 322, 323, 324, 325, 326, 327, -1, + 329, 330, 331, 332, 333, 334, 335, 336, -1, 338, + 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, + 349, 350, -1, 352, 353, -1, 355, 356, 357, 358, + 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, + 369, -1, 371, 372, 373, 374, 375, -1, 377, 378, + 379, 380, 381, -1, 383, 384, 385, 386, -1, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, -1, 405, 406, -1, 408, + -1, 410, 411, 412, 413, 414, -1, 416, 417, -1, + -1, 420, 421, 422, 423, 424, -1, 426, 427, 428, + 429, 430, 431, 432, 433, -1, 435, 436, 437, 438, + 439, 440, 441, -1, -1, 444, 445, 446, 447, 448, + 449, 450, -1, 452, -1, 454, 455, 456, 457, 458, + -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, + 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, + 479, 480, 481, 482, 483, 484, 3, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, + 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, + -1, 38, -1, 40, 41, -1, 43, 44, 45, 46, + 47, 48, 49, -1, 51, 52, 53, 54, -1, 56, + 57, 58, 59, 60, 61, -1, -1, 64, 65, 66, + 67, 68, -1, 70, 71, 72, 73, -1, -1, 76, + -1, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, -1, 89, 90, 91, 92, 93, 94, -1, 96, + 97, 98, 99, 100, 101, 102, 103, -1, -1, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + -1, 118, -1, 120, 121, 122, 123, 124, 125, -1, + 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, + 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, + -1, 148, 149, 150, 151, -1, 153, 154, 155, 156, + 157, -1, -1, 160, -1, 162, 163, 164, 165, -1, + 167, -1, 169, 170, -1, 172, 173, 174, 175, 176, + 177, -1, 179, -1, -1, -1, 183, -1, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + -1, 198, 199, 200, 201, 202, 203, -1, 205, 206, + -1, 208, 209, 210, 211, 212, 213, 214, -1, 216, + -1, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, -1, -1, 231, 232, 233, 234, -1, 236, + 237, 238, -1, -1, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, -1, -1, 273, 274, 275, 276, + -1, -1, 279, 280, 281, 282, 283, -1, 285, 286, + -1, -1, 289, 290, 291, -1, -1, 294, -1, 296, + 297, 298, -1, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, -1, 311, 312, -1, 314, 315, 316, + -1, 318, 319, 320, -1, 322, 323, 324, 325, 326, + 327, -1, 329, 330, 331, 332, 333, 334, 335, 336, + -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, -1, 352, 353, 354, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, + 367, 368, 369, -1, 371, 372, 373, 374, 375, 376, + 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, + -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 398, 399, 400, 401, -1, 403, -1, 405, 406, + -1, 408, 409, 410, 411, 412, 413, 414, -1, 416, + 417, -1, -1, 420, 421, -1, 423, -1, -1, 426, + 427, 428, 429, 430, 431, 432, 433, 434, -1, 436, + 437, 438, 439, 440, 441, 442, -1, 444, 445, 446, + 447, 448, -1, 450, -1, 452, 453, 454, 455, 456, + 457, 458, -1, -1, 461, -1, -1, 464, 465, 466, + 467, 468, 469, 3, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 481, 482, 483, 484, -1, -1, + -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, + 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, + 40, 41, -1, 43, 44, 45, 46, 47, 48, 49, + -1, 51, 52, 53, 54, -1, 56, 57, 58, 59, + 60, 61, -1, -1, 64, 65, 66, 67, 68, -1, + 70, 71, 72, 73, -1, -1, 76, -1, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, + 90, 91, 92, 93, 94, -1, 96, 97, 98, 99, + 100, 101, 102, 103, -1, -1, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, -1, 118, -1, + 120, 121, 122, 123, 124, 125, -1, 127, 128, 129, + 130, 131, -1, -1, 134, 135, 136, 137, 138, -1, + 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, + 150, 151, -1, 153, 154, 155, 156, 157, -1, -1, + 160, -1, 162, 163, 164, 165, -1, 167, -1, 169, + 170, -1, 172, 173, 174, -1, 176, 177, -1, 179, + -1, -1, -1, 183, -1, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, -1, 198, 199, + 200, 201, 202, 203, -1, 205, 206, -1, 208, 209, + 210, 211, 212, 213, 214, -1, 216, -1, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228, -1, + -1, 231, 232, 233, 234, -1, 236, 237, 238, -1, + -1, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, -1, -1, 273, 274, 275, 276, -1, -1, 279, + 280, 281, 282, 283, -1, 285, 286, -1, -1, 289, + 290, 291, -1, -1, 294, -1, 296, 297, 298, -1, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + -1, 311, 312, -1, 314, 315, 316, -1, 318, 319, + 320, -1, 322, 323, 324, 325, 326, 327, -1, 329, + 330, 331, 332, 333, 334, 335, 336, -1, 338, 339, + 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, + 350, -1, 352, 353, 354, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, + -1, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 380, 381, 382, 383, 384, 385, 386, -1, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, + 400, 401, -1, 403, -1, 405, 406, -1, 408, 409, + 410, 411, 412, 413, 414, -1, 416, 417, -1, -1, + 420, 421, -1, 423, -1, -1, 426, 427, 428, 429, + 430, 431, 432, 433, 434, -1, 436, 437, 438, 439, + 440, 441, 442, -1, 444, 445, 446, 447, 448, -1, + 450, -1, 452, 453, 454, 455, 456, 457, 458, -1, + -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, + 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 481, 482, 483, 484, -1, -1, -1, 21, 22, + 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, + -1, -1, -1, -1, -1, -1, -1, 40, 41, -1, + 43, 44, 45, 46, 47, 48, 49, -1, 51, 52, + 53, 54, -1, 56, 57, 58, 59, 60, 61, -1, + -1, 64, 65, 66, 67, 68, -1, 70, 71, 72, + 73, -1, -1, 76, -1, 78, 79, 80, 81, 82, + 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, + 93, 94, -1, 96, 97, 98, 99, 100, 101, 102, + 103, -1, -1, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, -1, 118, -1, 120, 121, 122, + 123, 124, 125, -1, 127, 128, 129, 130, 131, -1, + -1, 134, 135, 136, 137, 138, -1, 140, 141, 142, + -1, 144, 145, 146, -1, 148, 149, 150, 151, -1, + 153, 154, 155, 156, 157, -1, -1, 160, -1, 162, + 163, 164, 165, -1, 167, -1, 169, 170, -1, 172, + 173, 174, -1, 176, 177, -1, 179, -1, -1, -1, + 183, -1, 185, 186, 187, 188, 189, 190, 191, 192, + 193, 194, 195, 196, -1, 198, 199, 200, 201, 202, + 203, -1, 205, 206, -1, 208, 209, 210, 211, 212, + 213, 214, -1, 216, -1, 218, 219, 220, 221, 222, + 223, 224, 225, 226, 227, 228, -1, -1, 231, 232, + 233, 234, -1, 236, 237, 238, -1, -1, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, 266, 267, 268, 269, 270, -1, -1, + 273, 274, 275, 276, -1, -1, 279, 280, 281, 282, + 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, + -1, 294, -1, 296, 297, 298, -1, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, + -1, 314, 315, 316, -1, 318, 319, 320, -1, 322, + 323, 324, 325, 326, 327, -1, 329, 330, 331, 332, + 333, 334, 335, 336, -1, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, -1, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 368, 369, -1, 371, 372, + 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, + 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 398, 399, 400, 401, -1, + 403, -1, 405, 406, -1, 408, 409, 410, 411, 412, + 413, 414, -1, 416, 417, -1, -1, 420, 421, -1, + 423, -1, -1, 426, 427, 428, 429, 430, 431, 432, + 433, 434, -1, 436, 437, 438, 439, 440, 441, 442, + -1, 444, 445, 446, 447, 448, -1, 450, -1, 452, + 453, 454, 455, 456, 457, 458, -1, -1, 461, -1, + -1, 464, 465, 466, 467, 468, 469, 3, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 481, 482, + 483, 484, -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, + 46, 47, 48, 49, -1, 51, 52, 53, 54, -1, 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, + 66, 67, 68, -1, 70, 71, 72, 73, -1, -1, + 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 96, 97, 98, 99, 100, 101, 102, 103, -1, -1, + 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, + 146, -1, 148, 149, 150, 151, -1, 153, 154, 155, + 156, 157, -1, -1, 160, -1, 162, 163, 164, 165, + -1, 167, -1, 169, 170, -1, 172, 173, 174, -1, + 176, 177, -1, 179, -1, -1, -1, 183, -1, 185, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, + 206, -1, 208, 209, 210, 211, 212, 213, 214, -1, + 216, -1, 218, 219, 220, 221, 222, 223, 224, 225, + 226, 227, 228, -1, -1, 231, 232, 233, 234, -1, 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, + 266, 267, 268, 269, 270, -1, -1, 273, 274, 275, + 276, -1, -1, 279, 280, 281, 282, 283, -1, 285, + 286, -1, -1, 289, 290, 291, -1, -1, 294, -1, + 296, 297, 298, -1, 300, 301, 302, 303, 304, 305, + 306, 307, 308, 309, -1, 311, 312, -1, 314, 315, + 316, -1, 318, 319, 320, -1, 322, 323, 324, 325, + 326, 327, -1, 329, 330, 331, 332, 333, 334, 335, + 336, -1, 338, 339, 340, 341, 342, 343, 344, 345, + 346, 347, 348, 349, 350, -1, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, + 366, 367, 368, 369, -1, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, + 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 398, 399, 400, 401, -1, 403, -1, 405, + 406, -1, 408, 409, 410, 411, 412, 413, 414, -1, + 416, 417, -1, -1, 420, 421, -1, 423, -1, -1, + 426, 427, 428, 429, 430, 431, 432, 433, 434, -1, + 436, 437, 438, 439, 440, 441, 442, -1, 444, 445, 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, + 456, 457, 458, -1, -1, 461, -1, -1, 464, 465, + 466, 467, 468, 469, 3, -1, 5, -1, -1, -1, + -1, -1, -1, -1, -1, 481, 482, 483, 484, -1, + -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, + -1, 30, 31, 32, 33, 34, -1, -1, -1, -1, + -1, 40, 41, -1, 43, 44, 45, -1, 47, 48, + 49, 50, 51, -1, 53, 54, -1, 56, 57, 58, + 59, 60, 61, -1, -1, 64, 65, 66, 67, 68, + -1, 70, 71, 72, 73, 74, -1, -1, -1, 78, + 79, 80, 81, 82, 83, -1, 85, 86, 87, -1, + 89, 90, 91, 92, 93, 94, -1, -1, 97, 98, + 99, -1, -1, -1, -1, -1, -1, -1, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, -1, 118, + -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, + 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, + -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + -1, 160, -1, 162, 163, 164, 165, -1, 167, -1, + 169, -1, -1, -1, 173, 174, 175, -1, 177, -1, + 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, + 189, 190, 191, -1, 193, 194, 195, 196, -1, 198, + 199, 200, 201, 202, 203, -1, 205, -1, 207, 208, + 209, 210, 211, 212, 213, 214, -1, 216, -1, 218, + -1, -1, 221, -1, 223, 224, 225, 226, 227, 228, + -1, -1, 231, -1, 233, -1, -1, 236, 237, 238, + -1, -1, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, -1, 267, 268, + 269, 270, 271, -1, 273, 274, -1, 276, -1, 278, + 279, 280, 281, 282, 283, -1, 285, 286, -1, -1, + 289, 290, 291, -1, -1, 294, 295, -1, 297, -1, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, -1, 311, 312, 313, -1, 315, 316, 317, 318, + 319, 320, -1, 322, 323, 324, 325, 326, 327, -1, + 329, 330, 331, 332, 333, 334, 335, 336, -1, 338, + 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, + 349, 350, -1, 352, 353, -1, 355, 356, 357, 358, + 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, + 369, -1, 371, 372, 373, 374, 375, -1, 377, 378, + 379, 380, 381, -1, 383, 384, 385, 386, -1, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, -1, 405, 406, -1, 408, + -1, 410, 411, 412, 413, 414, -1, 416, 417, -1, + -1, 420, 421, 422, 423, 424, -1, 426, 427, 428, + 429, 430, 431, 432, 433, -1, -1, 436, 437, 438, + 439, 440, 441, -1, -1, 444, 445, 446, 447, 448, + 449, 450, -1, 452, -1, 454, 455, 456, 457, 458, + -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, + 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, + 479, 480, 481, 482, 483, 484, 3, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, + -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, -1, -1, -1, -1, + -1, -1, -1, 40, 41, -1, 43, 44, 45, -1, + 47, 48, 49, 50, 51, -1, 53, 54, -1, 56, + 57, 58, 59, 60, 61, -1, -1, 64, 65, 66, + 67, 68, -1, 70, 71, 72, 73, 74, -1, -1, + -1, 78, 79, 80, 81, 82, 83, -1, 85, 86, + 87, -1, 89, 90, 91, 92, 93, 94, -1, -1, + 97, 98, 99, -1, -1, -1, -1, -1, -1, -1, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + -1, 118, -1, 120, 121, 122, 123, 124, 125, -1, + 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, + 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, + -1, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, -1, 160, -1, 162, 163, 164, 165, -1, + 167, -1, 169, -1, -1, -1, 173, 174, 175, -1, + 177, -1, 179, -1, 181, 182, 183, -1, 185, 186, + 187, 188, 189, 190, 191, -1, 193, 194, 195, 196, + -1, 198, 199, 200, 201, 202, 203, -1, 205, -1, + 207, 208, 209, 210, 211, 212, 213, 214, -1, 216, + -1, 218, -1, -1, 221, -1, 223, 224, 225, 226, + 227, 228, -1, -1, 231, -1, 233, -1, -1, 236, + 237, 238, -1, -1, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, -1, + 267, 268, 269, 270, 271, -1, 273, 274, -1, 276, + -1, 278, 279, 280, 281, 282, 283, -1, 285, 286, + -1, -1, 289, 290, 291, -1, -1, 294, 295, -1, + 297, -1, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, -1, 311, 312, 313, -1, 315, 316, + 317, 318, 319, 320, -1, 322, 323, 324, 325, 326, + 327, -1, 329, 330, 331, 332, 333, 334, 335, 336, + -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, -1, 352, 353, -1, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, + 367, 368, 369, -1, 371, 372, 373, 374, 375, -1, + 377, 378, 379, 380, 381, -1, 383, 384, 385, 386, + -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, -1, 405, 406, + -1, 408, -1, 410, 411, 412, 413, 414, -1, 416, + 417, -1, -1, 420, 421, 422, 423, 424, -1, 426, + 427, 428, 429, 430, 431, 432, 433, -1, -1, 436, + 437, 438, 439, 440, 441, -1, -1, 444, 445, 446, + 447, 448, 449, 450, -1, 452, -1, 454, 455, 456, + 457, 458, -1, -1, 461, -1, -1, 464, 465, 466, + 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, + 477, 478, 479, 480, 481, 482, 483, 484, 3, -1, + 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, + 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, + -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, + 45, -1, 47, 48, 49, 50, 51, -1, 53, 54, + -1, 56, 57, 58, 59, 60, 61, -1, -1, 64, + 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, + -1, -1, -1, 78, 79, 80, 81, 82, 83, -1, + 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, + -1, -1, 97, 98, 99, -1, -1, -1, -1, -1, + -1, -1, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, -1, 118, -1, 120, 121, 122, 123, 124, + 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, + 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, + 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, -1, 160, -1, 162, 163, 164, + 165, -1, 167, -1, 169, -1, -1, -1, 173, 174, + 175, -1, 177, -1, 179, -1, 181, 182, 183, -1, + 185, 186, 187, 188, 189, 190, 191, -1, 193, 194, + 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, + 205, -1, 207, 208, 209, 210, 211, 212, 213, 214, + -1, 216, -1, 218, -1, -1, 221, -1, 223, 224, + 225, 226, 227, 228, -1, -1, 231, -1, 233, -1, + -1, 236, 237, 238, -1, -1, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, -1, 267, 268, 269, 270, 271, -1, 273, 274, + -1, 276, -1, 278, 279, 280, 281, 282, 283, -1, + 285, 286, -1, 288, 289, 290, 291, -1, -1, 294, + 295, -1, 297, -1, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, -1, 311, 312, 313, -1, + 315, 316, 317, 318, 319, 320, -1, 322, 323, 324, + 325, 326, 327, -1, 329, 330, 331, 332, 333, 334, + 335, 336, -1, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, -1, 352, 353, -1, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, + 375, -1, 377, 378, 379, 380, 381, -1, 383, 384, + 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, -1, + 405, 406, -1, 408, -1, 410, 411, 412, 413, 414, + -1, 416, 417, -1, -1, 420, 421, 422, 423, 424, + -1, 426, 427, 428, 429, 430, 431, 432, 433, -1, + -1, 436, 437, 438, 439, 440, 441, -1, -1, 444, + 445, 446, 447, 448, 449, 450, -1, 452, -1, 454, + 455, 456, 457, 458, -1, -1, 461, -1, -1, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, + 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 3, -1, 5, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, + 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, + -1, -1, -1, -1, -1, -1, -1, 40, 41, -1, + 43, 44, 45, -1, 47, 48, 49, 50, 51, -1, + 53, 54, -1, 56, 57, 58, 59, 60, 61, -1, + -1, 64, 65, 66, 67, 68, -1, 70, 71, 72, + 73, 74, -1, -1, -1, 78, 79, 80, 81, 82, + 83, -1, 85, 86, 87, -1, 89, 90, 91, 92, + 93, 94, -1, -1, 97, 98, 99, -1, -1, -1, + -1, -1, -1, -1, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, -1, 118, -1, 120, 121, 122, + 123, 124, 125, -1, 127, 128, 129, 130, 131, -1, + -1, 134, 135, 136, 137, 138, -1, 140, 141, 142, + -1, 144, 145, 146, -1, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, -1, 160, -1, 162, + 163, 164, 165, -1, 167, -1, 169, -1, -1, -1, + 173, 174, 175, -1, 177, -1, 179, -1, 181, 182, + 183, -1, 185, 186, 187, 188, 189, 190, 191, -1, + 193, 194, 195, 196, -1, 198, 199, 200, 201, 202, + 203, -1, 205, -1, 207, 208, 209, 210, 211, 212, + 213, 214, -1, 216, -1, 218, -1, -1, 221, -1, + 223, 224, 225, 226, 227, 228, -1, -1, 231, -1, + 233, -1, -1, 236, 237, 238, -1, -1, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, -1, 267, 268, 269, 270, 271, -1, + 273, 274, -1, 276, -1, 278, 279, 280, 281, 282, + 283, -1, 285, 286, -1, 288, 289, 290, 291, -1, + -1, 294, 295, -1, 297, -1, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, + 313, -1, 315, 316, 317, 318, 319, 320, -1, 322, + 323, 324, 325, 326, 327, -1, 329, 330, 331, 332, + 333, 334, 335, 336, -1, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, -1, 352, + 353, -1, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 368, 369, -1, 371, 372, + 373, 374, 375, -1, 377, 378, 379, 380, 381, -1, + 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, -1, 405, 406, -1, 408, -1, 410, 411, 412, + 413, 414, -1, 416, 417, -1, -1, 420, 421, 422, + 423, 424, -1, 426, 427, 428, 429, 430, 431, 432, + 433, -1, -1, 436, 437, 438, 439, 440, 441, -1, + -1, 444, 445, 446, 447, 448, 449, 450, -1, 452, + -1, 454, 455, 456, 457, 458, -1, -1, 461, -1, + -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, + 483, 484, 3, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, 38, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - -1, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, -1, -1, -1, -1, -1, -1, -1, 40, + 41, -1, 43, 44, 45, -1, 47, 48, 49, 50, + 51, -1, 53, 54, -1, 56, 57, 58, 59, 60, + 61, -1, -1, 64, 65, 66, 67, 68, -1, 70, + 71, 72, 73, 74, -1, -1, -1, 78, 79, 80, + 81, 82, 83, -1, 85, 86, 87, -1, 89, 90, + 91, 92, 93, 94, -1, -1, 97, 98, 99, -1, + -1, -1, -1, -1, -1, -1, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, -1, 118, -1, 120, + 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, + 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, + 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, -1, 160, + -1, 162, 163, 164, 165, -1, 167, -1, 169, -1, + -1, -1, 173, 174, 175, -1, 177, -1, 179, -1, + 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, + 191, -1, 193, 194, 195, 196, -1, 198, 199, 200, + 201, 202, 203, -1, 205, -1, 207, 208, 209, 210, + 211, 212, 213, 214, -1, 216, -1, 218, -1, -1, + 221, -1, 223, 224, 225, 226, 227, 228, -1, -1, + 231, -1, 233, -1, -1, 236, 237, 238, -1, -1, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, -1, 267, 268, 269, 270, + 271, -1, 273, 274, -1, 276, -1, 278, 279, 280, + 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, + 291, -1, -1, 294, 295, -1, 297, -1, 299, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, + 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, + -1, 322, 323, 324, 325, 326, 327, -1, 329, 330, + 331, 332, 333, 334, 335, 336, -1, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, + -1, 352, 353, -1, 355, 356, 357, 358, 359, 360, + 361, 362, 363, 364, 365, 366, 367, 368, 369, -1, + 371, 372, 373, 374, 375, -1, 377, 378, 379, 380, + 381, -1, 383, 384, 385, 386, -1, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, -1, 405, 406, -1, 408, -1, 410, + 411, 412, 413, 414, -1, 416, 417, -1, -1, 420, + 421, 422, 423, 424, -1, 426, 427, 428, 429, 430, + 431, 432, 433, -1, -1, 436, 437, 438, 439, 440, + 441, -1, -1, 444, 445, 446, 447, 448, 449, 450, + -1, 452, -1, 454, 455, 456, 457, 458, -1, -1, + 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, + 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 3, 4, -1, -1, -1, -1, + 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, + -1, 30, 31, 32, -1, -1, -1, -1, -1, -1, + -1, 40, 41, -1, 43, 44, 45, -1, 47, 48, + 49, 50, 51, -1, 53, 54, -1, 56, 57, 58, + 59, 60, 61, -1, -1, 64, 65, 66, 67, 68, + -1, 70, 71, 72, 73, 74, -1, -1, -1, 78, + 79, 80, 81, 82, 83, -1, 85, 86, 87, -1, + 89, 90, 91, 92, 93, 94, -1, -1, 97, 98, + 99, -1, -1, -1, -1, -1, -1, -1, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, -1, 118, + -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, + 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, + -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + -1, 160, -1, 162, 163, 164, 165, -1, 167, -1, + 169, -1, -1, -1, 173, 174, 175, -1, 177, -1, + 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, + 189, 190, 191, -1, 193, 194, 195, 196, -1, 198, + 199, 200, 201, 202, 203, -1, 205, -1, 207, 208, + 209, 210, 211, 212, 213, 214, -1, 216, -1, 218, + -1, -1, 221, -1, 223, 224, 225, 226, 227, 228, + -1, -1, 231, -1, 233, -1, -1, 236, 237, 238, + -1, -1, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, -1, 267, 268, + 269, 270, 271, -1, 273, 274, -1, 276, -1, 278, + 279, 280, 281, 282, 283, -1, 285, 286, -1, -1, + 289, 290, 291, -1, -1, 294, 295, -1, 297, -1, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, -1, 311, 312, 313, -1, 315, 316, 317, 318, + 319, 320, -1, 322, 323, 324, 325, 326, 327, -1, + 329, 330, 331, 332, 333, 334, 335, 336, -1, 338, + 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, + 349, 350, -1, 352, 353, -1, 355, 356, 357, 358, + 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, + 369, -1, 371, 372, 373, 374, 375, -1, 377, 378, + 379, 380, 381, -1, 383, 384, 385, 386, -1, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, -1, 405, 406, -1, 408, + -1, 410, 411, 412, 413, 414, -1, 416, 417, -1, + -1, 420, 421, 422, 423, 424, -1, 426, 427, 428, + 429, 430, 431, 432, 433, -1, -1, 436, 437, 438, + 439, 440, 441, -1, -1, 444, 445, 446, 447, 448, + 449, 450, -1, 452, -1, 454, 455, 456, 457, 458, + -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, + 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, + 479, 480, 481, 482, 483, 484, 3, -1, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, + -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, + 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, + -1, -1, -1, 40, 41, -1, 43, 44, 45, -1, + 47, 48, 49, 50, 51, -1, 53, 54, -1, 56, + 57, 58, 59, 60, 61, -1, -1, 64, 65, 66, + 67, 68, -1, 70, 71, 72, 73, 74, -1, -1, + -1, 78, 79, 80, 81, 82, 83, -1, 85, 86, + 87, -1, 89, 90, 91, 92, 93, 94, -1, -1, + 97, 98, 99, -1, -1, -1, -1, -1, -1, -1, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + -1, 118, -1, 120, 121, 122, 123, 124, 125, -1, + 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, + 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, + -1, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, -1, 160, -1, 162, 163, 164, 165, -1, + 167, -1, 169, -1, -1, -1, 173, 174, 175, -1, + 177, -1, 179, -1, 181, 182, 183, -1, 185, 186, + 187, 188, 189, 190, 191, -1, 193, 194, 195, 196, + -1, 198, 199, 200, 201, 202, 203, -1, 205, -1, + 207, 208, 209, 210, 211, 212, 213, 214, -1, 216, + -1, 218, -1, -1, 221, -1, 223, 224, 225, 226, + 227, 228, -1, -1, 231, -1, 233, -1, -1, 236, + 237, 238, -1, -1, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, -1, + 267, 268, 269, 270, 271, -1, 273, 274, -1, 276, + -1, 278, 279, 280, 281, 282, 283, -1, 285, 286, + -1, -1, 289, 290, 291, -1, -1, 294, 295, -1, + 297, -1, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, -1, 311, 312, 313, -1, 315, 316, + 317, 318, 319, 320, -1, 322, 323, 324, 325, 326, + 327, -1, 329, 330, 331, 332, 333, 334, 335, 336, + -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, -1, 352, 353, -1, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, + 367, 368, 369, -1, 371, 372, 373, 374, 375, -1, + 377, 378, 379, 380, 381, -1, 383, 384, 385, 386, + -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, -1, 405, 406, + 407, 408, -1, 410, 411, 412, 413, 414, -1, 416, + 417, -1, -1, 420, 421, 422, 423, 424, -1, 426, + 427, 428, 429, 430, 431, 432, 433, -1, -1, 436, + 437, 438, 439, 440, 441, -1, -1, 444, 445, 446, + 447, 448, 449, 450, -1, 452, -1, 454, 455, 456, + 457, 458, -1, -1, 461, -1, -1, 464, 465, 466, + 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, + 477, 478, 479, 480, 481, 482, 483, 484, 3, -1, + 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, + 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, + -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, + 45, -1, 47, 48, 49, 50, 51, -1, 53, 54, + -1, 56, 57, 58, 59, 60, 61, -1, -1, 64, + 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, + -1, -1, -1, 78, 79, 80, 81, 82, 83, -1, + 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, + -1, -1, 97, 98, 99, -1, -1, -1, -1, -1, + -1, -1, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, -1, 118, -1, 120, 121, 122, 123, 124, + 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, + 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, + 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, -1, 160, -1, 162, 163, 164, + 165, -1, 167, -1, 169, -1, -1, -1, 173, 174, + 175, -1, 177, -1, 179, -1, 181, 182, 183, -1, + 185, 186, 187, 188, 189, 190, 191, -1, 193, 194, + 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, + 205, -1, 207, 208, 209, 210, 211, 212, 213, 214, + -1, 216, -1, 218, -1, -1, 221, -1, 223, 224, + 225, 226, 227, 228, -1, -1, 231, -1, 233, -1, + -1, 236, 237, 238, -1, -1, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, -1, 267, 268, 269, 270, 271, -1, 273, 274, + -1, 276, -1, 278, 279, 280, 281, 282, 283, -1, + 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, + 295, -1, 297, -1, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, -1, 311, 312, 313, -1, + 315, 316, 317, 318, 319, 320, -1, 322, 323, 324, + 325, 326, 327, -1, 329, 330, 331, 332, 333, 334, + 335, 336, -1, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, -1, 352, 353, -1, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, + 375, -1, 377, 378, 379, 380, 381, -1, 383, 384, + 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, -1, + 405, 406, -1, 408, -1, 410, 411, 412, 413, 414, + -1, 416, 417, -1, -1, 420, 421, 422, 423, 424, + -1, 426, 427, 428, 429, 430, 431, 432, 433, -1, + -1, 436, 437, 438, 439, 440, 441, -1, -1, 444, + 445, 446, 447, 448, 449, 450, -1, 452, -1, 454, + 455, 456, 457, 458, -1, -1, 461, -1, -1, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, + 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 3, -1, 5, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, + 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, + -1, -1, -1, -1, -1, -1, -1, 40, 41, -1, + 43, 44, 45, -1, 47, 48, 49, 50, 51, -1, + 53, 54, -1, 56, 57, 58, 59, 60, 61, -1, + -1, 64, 65, 66, 67, 68, -1, 70, 71, 72, + 73, 74, -1, -1, -1, 78, 79, 80, 81, 82, + 83, -1, 85, 86, 87, -1, 89, 90, 91, 92, + 93, 94, -1, -1, 97, 98, 99, -1, -1, -1, + -1, -1, -1, -1, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, -1, 118, -1, 120, 121, 122, + 123, 124, 125, -1, 127, 128, 129, 130, 131, -1, + -1, 134, 135, 136, 137, 138, -1, 140, 141, 142, + -1, 144, 145, 146, -1, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, -1, 160, -1, 162, + 163, 164, 165, -1, 167, -1, 169, -1, -1, -1, + 173, 174, 175, -1, 177, -1, 179, -1, 181, 182, + 183, -1, 185, 186, 187, 188, 189, 190, 191, -1, + 193, 194, 195, 196, -1, 198, 199, 200, 201, 202, + 203, -1, 205, -1, 207, 208, 209, 210, 211, 212, + 213, 214, -1, 216, -1, 218, -1, -1, 221, -1, + 223, 224, 225, 226, 227, 228, -1, -1, 231, -1, + 233, -1, -1, 236, 237, 238, -1, -1, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, -1, 267, 268, 269, 270, 271, -1, + 273, 274, -1, 276, -1, 278, 279, 280, 281, 282, + 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, + -1, 294, 295, -1, 297, -1, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, + 313, -1, 315, 316, 317, 318, 319, 320, -1, 322, + 323, 324, 325, 326, 327, -1, 329, 330, 331, 332, + 333, 334, 335, 336, -1, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, -1, 352, + 353, -1, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 368, 369, -1, 371, 372, + 373, 374, 375, -1, 377, 378, 379, 380, 381, -1, + 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, -1, 405, 406, -1, 408, -1, 410, 411, 412, + 413, 414, -1, 416, 417, -1, -1, 420, 421, 422, + 423, 424, -1, 426, 427, 428, 429, 430, 431, 432, + 433, -1, -1, 436, 437, 438, 439, 440, 441, -1, + -1, 444, 445, 446, 447, 448, 449, 450, -1, 452, + -1, 454, 455, 456, 457, 458, -1, -1, 461, -1, + -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, + 483, 484, 3, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, -1, -1, -1, -1, -1, -1, -1, 40, + 41, -1, 43, 44, 45, -1, 47, 48, 49, 50, + 51, -1, 53, 54, -1, 56, 57, 58, 59, 60, + 61, -1, -1, 64, 65, 66, 67, 68, -1, 70, + 71, 72, 73, 74, -1, -1, -1, 78, 79, 80, + 81, 82, 83, -1, 85, 86, 87, -1, 89, 90, + 91, 92, 93, 94, -1, -1, 97, 98, 99, -1, + -1, -1, -1, -1, -1, -1, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, -1, 118, -1, 120, + 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, + 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, + 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, -1, 160, + -1, 162, 163, 164, 165, -1, 167, -1, 169, -1, + -1, -1, 173, 174, 175, -1, 177, -1, 179, -1, + 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, + 191, -1, 193, 194, 195, 196, -1, 198, 199, 200, + 201, 202, 203, -1, 205, -1, 207, 208, 209, 210, + 211, 212, 213, 214, -1, 216, -1, 218, -1, -1, + 221, -1, 223, 224, 225, 226, 227, 228, -1, -1, + 231, -1, 233, -1, -1, 236, 237, 238, -1, -1, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, -1, 267, 268, 269, 270, + 271, -1, 273, 274, -1, 276, -1, 278, 279, 280, + 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, + 291, -1, -1, 294, 295, -1, 297, -1, 299, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, + 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, + -1, 322, 323, 324, 325, 326, 327, -1, 329, 330, + 331, 332, 333, 334, 335, 336, -1, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, + -1, 352, 353, -1, 355, 356, 357, 358, 359, 360, + 361, 362, 363, 364, 365, 366, 367, 368, 369, -1, + 371, 372, 373, 374, 375, -1, 377, 378, 379, 380, + 381, -1, 383, 384, 385, 386, -1, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, -1, 405, 406, -1, 408, -1, 410, + 411, 412, 413, 414, -1, 416, 417, -1, -1, 420, + 421, 422, 423, 424, -1, 426, 427, 428, 429, 430, + 431, 432, 433, -1, -1, 436, 437, 438, 439, 440, + 441, -1, -1, 444, 445, 446, 447, 448, 449, 450, + -1, 452, -1, 454, 455, 456, 457, 458, -1, -1, + 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, + 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 3, -1, 5, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, + -1, 30, 31, 32, -1, -1, -1, -1, -1, -1, + -1, 40, 41, -1, 43, 44, 45, -1, 47, 48, + 49, 50, 51, -1, 53, 54, -1, 56, 57, 58, + 59, 60, 61, -1, -1, 64, 65, 66, 67, 68, + -1, 70, 71, 72, 73, 74, -1, -1, -1, 78, + 79, 80, 81, 82, 83, -1, 85, 86, 87, -1, + 89, 90, 91, 92, 93, 94, -1, -1, 97, 98, + 99, -1, -1, -1, -1, -1, -1, -1, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, -1, 118, + -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, + 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, + -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + -1, 160, -1, 162, 163, 164, 165, -1, 167, -1, + 169, -1, -1, -1, 173, 174, 175, -1, 177, -1, + 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, + 189, 190, 191, -1, 193, 194, 195, 196, -1, 198, + 199, 200, 201, 202, 203, -1, 205, -1, 207, 208, + 209, 210, 211, 212, 213, 214, -1, 216, -1, 218, + -1, -1, 221, -1, 223, 224, 225, 226, 227, 228, + -1, -1, 231, -1, 233, -1, -1, 236, 237, 238, + -1, -1, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, -1, 267, 268, + 269, 270, 271, -1, 273, 274, -1, 276, -1, 278, + 279, 280, 281, 282, 283, -1, 285, 286, -1, -1, + 289, 290, 291, -1, -1, 294, 295, -1, 297, -1, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, -1, 311, 312, 313, -1, 315, 316, 317, 318, + 319, 320, -1, 322, 323, 324, 325, 326, 327, -1, + 329, 330, 331, 332, 333, 334, 335, 336, -1, 338, + 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, + 349, 350, -1, 352, 353, -1, 355, 356, 357, 358, + 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, + 369, -1, 371, 372, 373, 374, 375, -1, 377, 378, + 379, 380, 381, -1, 383, 384, 385, 386, -1, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, -1, 405, 406, -1, 408, + -1, 410, 411, 412, 413, 414, -1, 416, 417, -1, + -1, 420, 421, 422, 423, 424, -1, 426, 427, 428, + 429, 430, 431, 432, 433, -1, -1, 436, 437, 438, + 439, 440, 441, -1, -1, 444, 445, 446, 447, 448, + 449, 450, -1, 452, -1, 454, 455, 456, 457, 458, + -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, + 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, + 479, 480, 481, 482, 483, 484, 3, -1, 5, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, + 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, + -1, -1, -1, 40, 41, -1, 43, 44, 45, -1, + 47, 48, 49, 50, 51, -1, 53, 54, -1, 56, + 57, 58, 59, 60, 61, -1, -1, 64, 65, 66, + 67, 68, -1, 70, 71, 72, 73, 74, -1, -1, + -1, 78, 79, 80, 81, 82, 83, -1, 85, 86, + 87, -1, 89, 90, 91, 92, 93, 94, -1, -1, + 97, 98, 99, -1, -1, -1, -1, -1, -1, -1, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + -1, 118, -1, 120, 121, 122, 123, 124, 125, -1, + 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, + 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, + -1, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, -1, 160, -1, 162, 163, 164, 165, -1, + 167, -1, 169, -1, -1, -1, 173, 174, 175, -1, + 177, -1, 179, -1, 181, 182, 183, -1, 185, 186, + 187, 188, 189, 190, 191, -1, 193, 194, 195, 196, + -1, 198, 199, 200, 201, 202, 203, -1, 205, -1, + 207, 208, 209, 210, 211, 212, 213, 214, -1, 216, + -1, 218, -1, -1, 221, -1, 223, 224, 225, 226, + 227, 228, -1, -1, 231, -1, 233, -1, -1, 236, + 237, 238, -1, -1, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, -1, + 267, 268, 269, 270, 271, -1, 273, 274, -1, 276, + -1, 278, 279, 280, 281, 282, 283, -1, 285, 286, + -1, -1, 289, 290, 291, -1, -1, 294, 295, -1, + 297, -1, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, -1, 311, 312, 313, -1, 315, 316, + 317, 318, 319, 320, -1, 322, 323, 324, 325, 326, + 327, -1, 329, 330, 331, 332, 333, 334, 335, 336, + -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, -1, 352, 353, -1, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, + 367, 368, 369, -1, 371, 372, 373, 374, 375, -1, + 377, 378, 379, 380, 381, -1, 383, 384, 385, 386, + -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, -1, 405, 406, + -1, 408, -1, 410, 411, 412, 413, 414, -1, 416, + 417, -1, -1, 420, 421, 422, 423, 424, -1, 426, + 427, 428, 429, 430, 431, 432, 433, -1, -1, 436, + 437, 438, 439, 440, 441, -1, -1, 444, 445, 446, + 447, 448, 449, 450, -1, 452, -1, 454, 455, 456, + 457, 458, -1, -1, 461, -1, -1, 464, 465, 466, + 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, + 477, 478, 479, 480, 481, 482, 483, 484, 3, -1, + 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, + 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, + -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, + 45, -1, 47, 48, 49, 50, 51, -1, 53, 54, + -1, 56, 57, 58, 59, 60, 61, -1, -1, 64, + 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, + -1, -1, -1, 78, 79, 80, 81, 82, 83, -1, + 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, + -1, -1, 97, 98, 99, -1, -1, -1, -1, -1, + -1, -1, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, -1, 118, -1, 120, 121, 122, 123, 124, + 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, + 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, + 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, -1, 160, -1, 162, 163, 164, + 165, -1, 167, -1, 169, -1, -1, -1, 173, 174, + 175, -1, 177, -1, 179, -1, 181, 182, 183, -1, + 185, 186, 187, 188, 189, 190, 191, -1, 193, 194, + 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, + 205, -1, 207, 208, 209, 210, 211, 212, 213, 214, + -1, 216, -1, 218, -1, -1, 221, -1, 223, 224, + 225, 226, 227, 228, -1, -1, 231, -1, 233, -1, + -1, 236, 237, 238, -1, -1, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, -1, 267, 268, 269, 270, 271, -1, 273, 274, + -1, 276, -1, 278, 279, 280, 281, 282, 283, -1, + 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, + 295, -1, 297, -1, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, -1, 311, 312, 313, -1, + 315, 316, 317, 318, 319, 320, -1, 322, 323, 324, + 325, 326, 327, -1, 329, 330, 331, 332, 333, 334, + 335, 336, -1, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, -1, 352, 353, -1, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, + 375, -1, 377, 378, 379, 380, 381, -1, 383, 384, + 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, -1, + 405, 406, -1, 408, -1, 410, 411, 412, 413, 414, + -1, 416, 417, -1, -1, 420, 421, 422, 423, 424, + -1, 426, 427, 428, 429, 430, 431, 432, 433, -1, + -1, 436, 437, 438, 439, 440, 441, -1, -1, 444, + 445, 446, 447, 448, 449, 450, -1, 452, -1, 454, + 455, 456, 457, 458, -1, -1, 461, -1, -1, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, + 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 3, -1, 5, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, + 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, + -1, -1, -1, -1, -1, -1, -1, 40, 41, -1, + 43, 44, 45, -1, 47, 48, 49, 50, 51, -1, + 53, 54, -1, 56, 57, 58, 59, 60, 61, -1, + -1, 64, 65, 66, 67, 68, -1, 70, 71, 72, + 73, 74, -1, -1, -1, 78, 79, 80, 81, 82, + 83, -1, 85, 86, 87, -1, 89, 90, 91, 92, + 93, 94, -1, -1, 97, 98, 99, -1, -1, -1, + -1, -1, -1, -1, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, -1, 118, -1, 120, 121, 122, + 123, 124, 125, -1, 127, 128, 129, 130, 131, -1, + -1, 134, 135, 136, 137, 138, -1, 140, 141, 142, + -1, 144, 145, 146, -1, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, -1, 160, -1, 162, + 163, 164, 165, -1, 167, -1, 169, -1, -1, -1, + 173, 174, 175, -1, 177, -1, 179, -1, 181, 182, + 183, -1, 185, 186, 187, 188, 189, 190, 191, -1, + 193, 194, 195, 196, -1, 198, 199, 200, 201, 202, + 203, -1, 205, -1, 207, 208, 209, 210, 211, 212, + 213, 214, -1, 216, -1, 218, -1, -1, 221, -1, + 223, 224, 225, 226, 227, 228, -1, -1, 231, -1, + 233, -1, -1, 236, 237, 238, -1, -1, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, -1, 267, 268, 269, 270, 271, -1, + 273, 274, -1, 276, -1, 278, 279, 280, 281, 282, + 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, + -1, 294, 295, -1, 297, -1, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, + 313, -1, 315, 316, 317, 318, 319, 320, -1, 322, + 323, 324, 325, 326, 327, -1, 329, 330, 331, 332, + 333, 334, 335, 336, -1, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, -1, 352, + 353, -1, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 368, 369, -1, 371, 372, + 373, 374, 375, -1, 377, 378, 379, 380, 381, -1, + 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, -1, 405, 406, -1, 408, -1, 410, 411, 412, + 413, 414, -1, 416, 417, -1, -1, 420, 421, 422, + 423, 424, -1, 426, 427, 428, 429, 430, 431, 432, + 433, -1, -1, 436, 437, 438, 439, 440, 441, -1, + -1, 444, 445, 446, 447, 448, 449, 450, -1, 452, + -1, 454, 455, 456, 457, 458, -1, -1, 461, -1, + -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, + 483, 484, 3, -1, 5, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, + 31, 32, -1, -1, -1, -1, -1, -1, -1, 40, + 41, -1, 43, 44, 45, -1, 47, 48, 49, 50, + 51, -1, 53, 54, -1, 56, 57, 58, 59, 60, + 61, -1, -1, 64, 65, 66, 67, 68, -1, 70, + 71, 72, 73, 74, -1, -1, -1, 78, 79, 80, + 81, 82, 83, -1, 85, 86, 87, -1, 89, 90, + 91, 92, 93, 94, -1, -1, 97, 98, 99, -1, + -1, -1, -1, -1, -1, -1, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, -1, 118, -1, 120, + 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, + 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, + 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, -1, 160, + -1, 162, 163, 164, 165, -1, 167, -1, 169, -1, + -1, -1, 173, 174, 175, -1, 177, -1, 179, -1, + 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, + 191, -1, 193, 194, 195, 196, -1, 198, 199, 200, + 201, 202, 203, -1, 205, -1, 207, 208, 209, 210, + 211, 212, 213, 214, -1, 216, -1, 218, -1, -1, + 221, -1, 223, 224, 225, 226, 227, 228, -1, -1, + 231, -1, 233, -1, -1, 236, 237, 238, -1, -1, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, -1, 267, 268, 269, 270, + 271, -1, 273, 274, -1, 276, -1, 278, 279, 280, + 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, + 291, -1, -1, 294, 295, -1, 297, -1, 299, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, + 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, + -1, 322, 323, 324, 325, 326, 327, -1, 329, 330, + 331, 332, 333, 334, 335, 336, -1, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, + -1, 352, 353, -1, 355, 356, 357, 358, 359, 360, + 361, 362, 363, 364, 365, 366, 367, 368, 369, -1, + 371, 372, 373, 374, 375, -1, 377, 378, 379, 380, + 381, -1, 383, 384, 385, 386, -1, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, -1, 405, 406, -1, 408, -1, 410, + 411, 412, 413, 414, -1, 416, 417, -1, -1, 420, + 421, 422, 423, 424, -1, 426, 427, 428, 429, 430, + 431, 432, 433, -1, -1, 436, 437, 438, 439, 440, + 441, -1, -1, 444, 445, 446, 447, 448, 449, 450, + -1, 452, -1, 454, 455, 456, 457, 458, -1, -1, + 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, + 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 3, -1, 5, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, + -1, 30, 31, 32, -1, -1, -1, -1, -1, -1, + -1, 40, 41, -1, 43, 44, 45, -1, 47, 48, + 49, 50, 51, -1, 53, 54, -1, 56, 57, 58, + 59, 60, 61, -1, -1, 64, 65, 66, 67, 68, + -1, 70, 71, 72, 73, 74, -1, -1, -1, 78, + 79, 80, 81, 82, 83, -1, 85, 86, 87, -1, + 89, 90, 91, 92, 93, 94, -1, -1, 97, 98, + 99, -1, -1, -1, -1, -1, -1, -1, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, -1, 118, + -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, + 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, + -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + -1, 160, -1, 162, 163, 164, 165, -1, 167, -1, + 169, -1, -1, -1, 173, 174, 175, -1, 177, -1, + 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, + 189, 190, 191, -1, 193, 194, 195, 196, -1, 198, + 199, 200, 201, 202, 203, -1, 205, -1, 207, 208, + 209, 210, 211, 212, 213, 214, -1, 216, -1, 218, + -1, -1, 221, -1, 223, 224, 225, 226, 227, 228, + -1, -1, 231, -1, 233, -1, -1, 236, 237, 238, + -1, -1, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, -1, 267, 268, + 269, 270, 271, -1, 273, 274, -1, 276, -1, 278, + 279, 280, 281, 282, 283, -1, 285, 286, -1, -1, + 289, 290, 291, -1, -1, 294, 295, -1, 297, -1, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, -1, 311, 312, 313, -1, 315, 316, 317, 318, + 319, 320, -1, 322, 323, 324, 325, 326, 327, -1, + 329, 330, 331, 332, 333, 334, 335, 336, -1, 338, + 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, + 349, 350, -1, 352, 353, -1, 355, 356, 357, 358, + 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, + 369, -1, 371, 372, 373, 374, 375, -1, 377, 378, + 379, 380, 381, -1, 383, 384, 385, 386, -1, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, -1, 405, 406, -1, 408, + -1, 410, 411, 412, 413, 414, -1, 416, 417, -1, + -1, 420, 421, 422, 423, 424, -1, 426, 427, 428, + 429, 430, 431, 432, 433, -1, -1, 436, 437, 438, + 439, 440, 441, -1, -1, 444, 445, 446, 447, 448, + 449, 450, -1, 452, -1, 454, 455, 456, 457, 458, + -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, + 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, + 479, 480, 481, 482, 483, 484, 3, -1, 5, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, + 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, + -1, -1, -1, 40, 41, -1, 43, 44, 45, -1, + 47, 48, 49, 50, 51, -1, 53, 54, -1, 56, + 57, 58, 59, 60, 61, -1, -1, 64, 65, 66, + 67, 68, -1, 70, 71, 72, 73, 74, -1, -1, + -1, 78, 79, 80, 81, 82, 83, -1, 85, 86, + 87, -1, 89, 90, 91, 92, 93, 94, -1, -1, + 97, 98, 99, -1, -1, -1, -1, -1, -1, -1, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + -1, 118, -1, 120, 121, 122, 123, 124, 125, -1, + 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, + 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, + -1, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, -1, 160, -1, 162, 163, 164, 165, -1, + 167, -1, 169, -1, -1, -1, 173, 174, 175, -1, + 177, -1, 179, -1, 181, 182, 183, -1, 185, 186, + 187, 188, 189, 190, 191, -1, 193, 194, 195, 196, + -1, 198, 199, 200, 201, 202, 203, -1, 205, -1, + 207, 208, 209, 210, 211, 212, 213, 214, -1, 216, + -1, 218, -1, -1, 221, -1, 223, 224, 225, 226, + 227, 228, -1, -1, 231, -1, 233, -1, -1, 236, + 237, 238, -1, -1, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, -1, + 267, 268, 269, 270, 271, -1, 273, 274, -1, 276, + -1, 278, 279, 280, 281, 282, 283, -1, 285, 286, + -1, -1, 289, 290, 291, -1, -1, 294, 295, -1, + 297, -1, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, -1, 311, 312, 313, -1, 315, 316, + 317, 318, 319, 320, -1, 322, 323, 324, 325, 326, + 327, -1, 329, 330, 331, 332, 333, 334, 335, 336, + -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, -1, 352, 353, -1, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, + 367, 368, 369, -1, 371, 372, 373, 374, 375, -1, + 377, 378, 379, 380, 381, -1, 383, 384, 385, 386, + -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, -1, 405, 406, + -1, 408, -1, 410, 411, 412, 413, 414, -1, 416, + 417, -1, -1, 420, 421, 422, 423, 424, -1, 426, + 427, 428, 429, 430, 431, 432, 433, -1, -1, 436, + 437, 438, 439, 440, 441, -1, -1, 444, 445, 446, + 447, 448, 449, 450, -1, 452, -1, 454, 455, 456, + 457, 458, -1, -1, 461, -1, -1, 464, 465, 466, + 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, + 477, 478, 479, 480, 481, 482, 483, 484, 3, -1, + 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, + 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, + -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, + 45, -1, 47, 48, 49, 50, 51, -1, 53, 54, + -1, 56, 57, 58, 59, 60, 61, -1, -1, 64, + 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, + -1, -1, -1, 78, 79, 80, 81, 82, 83, -1, + 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, + -1, -1, 97, 98, 99, -1, -1, -1, -1, -1, + -1, -1, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, -1, 118, -1, 120, 121, 122, 123, 124, + 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, + 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, + 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, -1, 160, -1, 162, 163, 164, + 165, -1, 167, -1, 169, -1, -1, -1, 173, 174, + 175, -1, 177, -1, 179, -1, 181, 182, 183, -1, + 185, 186, 187, 188, 189, 190, 191, -1, 193, 194, + 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, + 205, -1, 207, 208, 209, 210, 211, 212, 213, 214, + -1, 216, -1, 218, -1, -1, 221, -1, 223, 224, + 225, 226, 227, 228, -1, -1, 231, -1, 233, -1, + -1, 236, 237, 238, -1, -1, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, -1, 267, 268, 269, 270, 271, -1, 273, 274, + -1, 276, -1, 278, 279, 280, 281, 282, 283, -1, + 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, + 295, -1, 297, -1, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, -1, 311, 312, 313, -1, + 315, 316, 317, 318, 319, 320, -1, 322, 323, 324, + 325, 326, 327, -1, 329, 330, 331, 332, 333, 334, + 335, 336, -1, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, -1, 352, 353, -1, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, + 375, -1, 377, 378, 379, 380, 381, -1, 383, 384, + 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, -1, + 405, 406, -1, 408, -1, 410, 411, 412, 413, 414, + -1, 416, 417, -1, -1, 420, 421, 422, 423, 424, + -1, 426, 427, 428, 429, 430, 431, 432, 433, -1, + -1, 436, 437, 438, 439, 440, 441, -1, -1, 444, + 445, 446, 447, 448, 449, 450, -1, 452, -1, 454, + 455, 456, 457, 458, -1, -1, 461, -1, -1, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, + 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, + 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, + -1, -1, -1, -1, -1, 38, -1, 40, 41, -1, + 43, 44, 45, -1, 47, 48, 49, 50, 51, -1, + 53, 54, -1, 56, 57, 58, 59, 60, 61, -1, + -1, 64, 65, 66, 67, 68, -1, 70, 71, 72, + 73, 74, -1, -1, -1, 78, 79, 80, 81, 82, + 83, -1, 85, 86, 87, -1, 89, 90, 91, 92, + 93, 94, -1, -1, 97, 98, 99, -1, -1, -1, + -1, -1, -1, -1, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, -1, 118, -1, 120, 121, 122, + 123, 124, 125, -1, 127, 128, 129, 130, 131, -1, + -1, 134, 135, 136, 137, 138, -1, 140, 141, 142, + -1, 144, 145, 146, -1, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, -1, 160, -1, 162, + 163, 164, 165, -1, 167, -1, 169, -1, -1, -1, + 173, 174, 175, -1, 177, -1, 179, -1, 181, 182, + 183, -1, 185, 186, 187, 188, 189, 190, 191, -1, + 193, 194, 195, 196, -1, 198, 199, 200, 201, 202, + 203, -1, 205, -1, 207, 208, 209, 210, 211, 212, + 213, 214, -1, 216, -1, 218, -1, -1, 221, -1, + 223, 224, 225, 226, 227, 228, -1, -1, 231, -1, + 233, -1, -1, 236, 237, 238, -1, -1, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, -1, 267, 268, 269, 270, 271, -1, + 273, 274, -1, 276, -1, 278, 279, 280, 281, 282, + 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, + -1, 294, 295, -1, 297, -1, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, + 313, -1, 315, 316, 317, 318, 319, 320, -1, 322, + 323, 324, 325, 326, 327, -1, 329, 330, 331, 332, + 333, 334, 335, 336, -1, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, -1, 352, + 353, -1, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 368, 369, -1, 371, 372, + 373, 374, 375, -1, 377, 378, 379, 380, 381, -1, + 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, -1, 405, 406, -1, 408, -1, 410, 411, 412, + 413, 414, -1, 416, 417, -1, -1, 420, 421, 422, + 423, 424, -1, 426, 427, 428, 429, 430, 431, 432, + 433, -1, -1, 436, 437, 438, 439, 440, 441, -1, + -1, 444, 445, 446, 447, 448, 449, 450, -1, 452, + -1, 454, 455, 456, 457, 458, -1, -1, 461, -1, + -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, + 483, 484, 3, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, + 31, 32, -1, -1, -1, -1, -1, 38, -1, 40, + 41, -1, 43, 44, 45, -1, 47, 48, 49, 50, + 51, -1, 53, 54, -1, 56, 57, 58, 59, 60, + 61, -1, -1, 64, 65, 66, 67, 68, -1, 70, + 71, 72, 73, 74, -1, -1, -1, 78, 79, 80, + 81, 82, 83, -1, 85, 86, 87, -1, 89, 90, + 91, 92, 93, 94, -1, -1, 97, 98, 99, -1, + -1, -1, -1, -1, -1, -1, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, -1, 118, -1, 120, + 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, + 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, + 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, -1, 160, + -1, 162, 163, 164, 165, -1, 167, -1, 169, -1, + -1, -1, 173, 174, 175, -1, 177, -1, 179, -1, + 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, + 191, -1, 193, 194, 195, 196, -1, 198, 199, 200, + 201, 202, 203, -1, 205, -1, 207, 208, 209, 210, + 211, 212, 213, 214, -1, 216, -1, 218, -1, -1, + 221, -1, 223, 224, 225, 226, 227, 228, -1, -1, + 231, -1, 233, -1, -1, 236, 237, 238, -1, -1, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, -1, 267, 268, 269, 270, + 271, -1, 273, 274, -1, 276, -1, 278, 279, 280, + 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, + 291, -1, -1, 294, 295, -1, 297, -1, 299, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, + 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, + -1, 322, 323, 324, 325, 326, 327, -1, 329, 330, + 331, 332, 333, 334, 335, 336, -1, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, + -1, 352, 353, -1, 355, 356, 357, 358, 359, 360, + 361, 362, 363, 364, 365, 366, 367, 368, 369, -1, + 371, 372, 373, 374, 375, -1, 377, 378, 379, 380, + 381, -1, 383, 384, 385, 386, -1, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, -1, 405, 406, -1, 408, -1, 410, + 411, 412, 413, 414, -1, 416, 417, -1, -1, 420, + 421, 422, 423, 424, -1, 426, 427, 428, 429, 430, + 431, 432, 433, -1, -1, 436, 437, 438, 439, 440, + 441, -1, -1, 444, 445, 446, 447, 448, 449, 450, + -1, 452, -1, 454, 455, 456, 457, 458, -1, -1, + 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, + 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 3, -1, 5, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, + -1, 30, 31, 32, -1, -1, -1, -1, -1, -1, + -1, 40, 41, -1, 43, 44, 45, -1, 47, 48, + 49, 50, 51, -1, 53, 54, -1, 56, 57, 58, + 59, 60, 61, -1, -1, 64, 65, 66, 67, 68, + -1, 70, 71, 72, 73, 74, -1, -1, -1, 78, + 79, 80, 81, 82, 83, -1, 85, 86, 87, -1, + 89, 90, 91, 92, 93, 94, -1, -1, 97, 98, + 99, -1, -1, -1, -1, -1, -1, -1, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, -1, 118, + -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, + 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, + -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + -1, 160, -1, 162, 163, 164, 165, -1, 167, -1, + 169, -1, -1, -1, 173, 174, 175, -1, 177, -1, + 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, + 189, 190, 191, -1, 193, 194, 195, 196, -1, 198, + 199, 200, 201, 202, 203, -1, 205, -1, 207, 208, + 209, 210, 211, 212, 213, 214, -1, 216, -1, 218, + -1, -1, 221, -1, 223, 224, 225, 226, 227, 228, + -1, -1, 231, -1, 233, -1, -1, 236, 237, 238, + -1, -1, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, -1, 267, 268, + 269, 270, 271, -1, 273, 274, -1, 276, -1, 278, + 279, 280, 281, 282, 283, -1, 285, 286, -1, -1, + 289, 290, 291, -1, -1, 294, 295, -1, 297, -1, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, -1, 311, 312, 313, -1, 315, 316, 317, 318, + 319, 320, -1, 322, 323, 324, 325, 326, 327, -1, + 329, 330, 331, 332, 333, 334, 335, 336, -1, 338, + 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, + 349, 350, -1, 352, 353, -1, 355, 356, 357, 358, + 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, + 369, -1, 371, 372, 373, 374, 375, -1, 377, 378, + 379, 380, 381, -1, 383, 384, 385, 386, -1, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, -1, 405, 406, -1, 408, + -1, 410, 411, 412, 413, 414, -1, 416, 417, -1, + -1, 420, 421, 422, 423, 424, -1, 426, 427, 428, + 429, 430, 431, 432, 433, -1, -1, 436, 437, 438, + 439, 440, 441, -1, -1, 444, 445, 446, 447, 448, + 449, 450, -1, 452, -1, 454, 455, 456, 457, 458, + -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, + 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, + 479, 480, 481, 482, 483, 484, 3, -1, 5, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, + 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, + -1, -1, -1, 40, 41, -1, 43, 44, 45, -1, + 47, 48, 49, 50, 51, -1, 53, 54, -1, 56, + 57, 58, 59, 60, 61, -1, -1, 64, 65, 66, + 67, 68, -1, 70, 71, 72, 73, 74, -1, -1, + -1, 78, 79, 80, 81, 82, 83, -1, 85, 86, + 87, -1, 89, 90, 91, 92, 93, 94, -1, -1, + 97, 98, 99, -1, -1, -1, -1, -1, -1, -1, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + -1, 118, -1, 120, 121, 122, 123, 124, 125, -1, + 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, + 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, + -1, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, -1, 160, -1, 162, 163, 164, 165, -1, + 167, -1, 169, -1, -1, -1, 173, 174, 175, -1, + 177, -1, 179, -1, 181, 182, 183, -1, 185, 186, + 187, 188, 189, 190, 191, -1, 193, 194, 195, 196, + -1, 198, 199, 200, 201, 202, 203, -1, 205, -1, + 207, 208, 209, 210, 211, 212, 213, 214, -1, 216, + -1, 218, -1, -1, 221, -1, 223, 224, 225, 226, + 227, 228, -1, -1, 231, -1, 233, -1, -1, 236, + 237, 238, -1, -1, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, -1, + 267, 268, 269, 270, 271, -1, 273, 274, -1, 276, + -1, 278, 279, 280, 281, 282, 283, -1, 285, 286, + -1, -1, 289, 290, 291, -1, -1, 294, 295, -1, + 297, -1, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, -1, 311, 312, 313, -1, 315, 316, + 317, 318, 319, 320, -1, 322, 323, 324, 325, 326, + 327, -1, 329, 330, 331, 332, 333, 334, 335, 336, + -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, -1, 352, 353, -1, 355, 356, + 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, + 367, 368, 369, -1, 371, 372, 373, 374, 375, -1, + 377, 378, 379, 380, 381, -1, 383, 384, 385, 386, + -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 398, 399, 400, 401, 402, 403, -1, 405, 406, + -1, 408, -1, 410, 411, 412, 413, 414, -1, 416, + 417, -1, -1, 420, 421, 422, 423, 424, -1, 426, + 427, 428, 429, 430, 431, 432, 433, -1, -1, 436, + 437, 438, 439, 440, 441, -1, -1, 444, 445, 446, + 447, 448, 449, 450, -1, 452, -1, 454, 455, 456, + 457, 458, -1, -1, 461, -1, -1, 464, 465, 466, + 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, + 477, 478, 479, 480, 481, 482, 483, 484, 3, -1, + 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, + 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, + -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, + 45, -1, 47, 48, 49, 50, 51, -1, 53, 54, + -1, 56, 57, 58, 59, 60, 61, -1, -1, 64, + 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, + -1, -1, -1, 78, 79, 80, 81, 82, 83, -1, + 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, + -1, -1, 97, 98, 99, -1, -1, -1, -1, -1, + -1, -1, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, -1, 118, -1, 120, 121, 122, 123, 124, + 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, + 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, + 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, -1, 160, -1, 162, 163, 164, + 165, -1, 167, -1, 169, -1, -1, -1, 173, 174, + 175, -1, 177, -1, 179, -1, 181, 182, 183, -1, + 185, 186, 187, 188, 189, 190, 191, -1, 193, 194, + 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, + 205, -1, 207, 208, 209, 210, 211, 212, 213, 214, + -1, 216, -1, 218, -1, -1, 221, -1, 223, 224, + 225, 226, 227, 228, -1, -1, 231, -1, 233, -1, + -1, 236, 237, 238, -1, -1, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, -1, 267, 268, 269, 270, 271, -1, 273, 274, + -1, 276, -1, 278, 279, 280, 281, 282, 283, -1, + 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, + 295, -1, 297, -1, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, -1, 311, 312, 313, -1, + 315, 316, 317, 318, 319, 320, -1, 322, 323, 324, + 325, 326, 327, -1, 329, 330, 331, 332, 333, 334, + 335, 336, -1, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, -1, 352, 353, -1, + 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, + 375, -1, 377, 378, 379, 380, 381, -1, 383, 384, + 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, -1, + 405, 406, -1, 408, -1, 410, 411, 412, 413, 414, + -1, 416, 417, -1, -1, 420, 421, 422, 423, 424, + -1, 426, 427, 428, 429, 430, 431, 432, 433, -1, + -1, 436, 437, 438, 439, 440, 441, -1, -1, 444, + 445, 446, 447, 448, 449, 450, -1, 452, -1, 454, + 455, 456, 457, 458, -1, -1, 461, -1, -1, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, + 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 3, -1, 5, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, + 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, + -1, -1, -1, -1, -1, -1, -1, 40, 41, -1, + 43, 44, 45, -1, 47, 48, 49, 50, 51, -1, + 53, 54, -1, 56, 57, 58, 59, 60, 61, -1, + -1, 64, 65, 66, 67, 68, -1, 70, 71, 72, + 73, 74, -1, -1, -1, 78, 79, 80, 81, 82, + 83, -1, 85, 86, 87, -1, 89, 90, 91, 92, + 93, 94, -1, -1, 97, 98, 99, -1, -1, -1, + -1, -1, -1, -1, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, -1, 118, -1, 120, 121, 122, + 123, 124, 125, -1, 127, 128, 129, 130, 131, -1, + -1, 134, 135, 136, 137, 138, -1, 140, 141, 142, + -1, 144, 145, 146, -1, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, -1, 160, -1, 162, + 163, 164, 165, -1, 167, -1, 169, -1, -1, -1, + 173, 174, 175, -1, 177, -1, 179, -1, 181, 182, + 183, -1, 185, 186, 187, 188, 189, 190, 191, -1, + 193, 194, 195, 196, -1, 198, 199, 200, 201, 202, + 203, -1, 205, -1, 207, 208, 209, 210, 211, 212, + 213, 214, -1, 216, -1, 218, -1, -1, 221, -1, + 223, 224, 225, 226, 227, 228, -1, -1, 231, -1, + 233, -1, -1, 236, 237, 238, -1, -1, 241, 242, + 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, + 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, + 263, 264, 265, -1, 267, 268, 269, 270, 271, -1, + 273, 274, -1, 276, -1, 278, 279, 280, 281, 282, + 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, + -1, 294, 295, -1, 297, -1, 299, 300, 301, 302, + 303, 304, 305, 306, 307, 308, 309, -1, 311, 312, + 313, -1, 315, 316, 317, 318, 319, 320, -1, 322, + 323, 324, 325, 326, 327, -1, 329, 330, 331, 332, + 333, 334, 335, 336, -1, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, -1, 352, + 353, -1, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 368, 369, -1, 371, 372, + 373, 374, 375, -1, 377, 378, 379, 380, 381, -1, + 383, 384, 385, 386, -1, 388, 389, 390, 391, 392, + 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, + 403, -1, 405, 406, -1, 408, -1, 410, 411, 412, + 413, 414, -1, 416, 417, -1, -1, 420, 421, 422, + 423, 424, -1, 426, 427, 428, 429, 430, 431, 432, + 433, -1, -1, 436, 437, 438, 439, 440, 441, -1, + -1, 444, 445, 446, 447, 448, 449, 450, -1, 452, + -1, 454, 455, 456, 457, 458, -1, -1, 461, -1, + -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, + 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, + 483, 484, 3, -1, 5, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, + 31, 32, -1, -1, -1, -1, -1, -1, -1, 40, + 41, -1, 43, 44, 45, -1, 47, 48, 49, 50, + 51, -1, 53, 54, -1, 56, 57, 58, 59, 60, + 61, -1, -1, 64, 65, 66, 67, 68, -1, 70, + 71, 72, 73, 74, -1, -1, -1, 78, 79, 80, + 81, 82, 83, -1, 85, 86, 87, -1, 89, 90, + 91, 92, 93, 94, -1, -1, 97, 98, 99, -1, + -1, -1, -1, -1, -1, -1, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, -1, 118, -1, 120, + 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, + 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, + 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, + 151, 152, 153, 154, 155, 156, 157, 158, -1, 160, + -1, 162, 163, 164, 165, -1, 167, -1, 169, -1, + -1, -1, 173, 174, 175, -1, 177, -1, 179, -1, + 181, 182, 183, -1, 185, 186, 187, 188, 189, 190, + 191, -1, 193, 194, 195, 196, -1, 198, 199, 200, + 201, 202, 203, -1, 205, -1, 207, 208, 209, 210, + 211, 212, 213, 214, -1, 216, -1, 218, -1, -1, + 221, -1, 223, 224, 225, 226, 227, 228, -1, -1, + 231, -1, 233, -1, -1, 236, 237, 238, -1, -1, + 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, -1, 267, 268, 269, 270, + 271, -1, 273, 274, -1, 276, -1, 278, 279, 280, + 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, + 291, -1, -1, 294, 295, -1, 297, -1, 299, 300, + 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, + 311, 312, 313, -1, 315, 316, 317, 318, 319, 320, + -1, 322, 323, 324, 325, 326, 327, -1, 329, 330, + 331, 332, 333, 334, 335, 336, -1, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, + -1, 352, 353, -1, 355, 356, 357, 358, 359, 360, + 361, 362, 363, 364, 365, 366, 367, 368, 369, -1, + 371, 372, 373, 374, 375, -1, 377, 378, 379, 380, + 381, -1, 383, 384, 385, 386, -1, 388, 389, 390, + 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, + 401, 402, 403, -1, 405, 406, -1, 408, -1, 410, + 411, 412, 413, 414, -1, 416, 417, -1, -1, 420, + 421, 422, 423, 424, -1, 426, 427, 428, 429, 430, + 431, 432, 433, -1, -1, 436, 437, 438, 439, 440, + 441, -1, -1, 444, 445, 446, 447, 448, 449, 450, + -1, 452, -1, 454, 455, 456, 457, 458, -1, -1, + 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, + 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 3, -1, 5, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, + -1, 30, 31, 32, -1, -1, -1, -1, -1, -1, + -1, 40, 41, -1, 43, 44, 45, -1, 47, 48, + 49, 50, 51, -1, 53, 54, -1, 56, 57, 58, + 59, 60, 61, -1, -1, 64, 65, 66, 67, 68, + -1, 70, 71, 72, 73, 74, -1, -1, -1, 78, + 79, 80, 81, 82, 83, -1, 85, 86, 87, -1, + 89, 90, 91, 92, 93, 94, -1, -1, 97, 98, + 99, -1, -1, -1, -1, -1, -1, -1, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, -1, 118, + -1, 120, 121, 122, 123, 124, 125, -1, 127, 128, + 129, 130, 131, -1, -1, 134, 135, 136, 137, 138, + -1, 140, 141, 142, -1, 144, 145, 146, -1, 148, + 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, + -1, 160, -1, 162, 163, 164, 165, -1, 167, -1, + 169, -1, -1, -1, 173, 174, 175, -1, 177, -1, + 179, -1, 181, 182, 183, -1, 185, 186, 187, 188, + 189, 190, 191, -1, 193, 194, 195, 196, -1, 198, + 199, 200, 201, 202, 203, -1, 205, -1, 207, 208, + 209, 210, 211, 212, 213, 214, -1, 216, -1, 218, + -1, -1, 221, -1, 223, 224, 225, 226, 227, 228, + -1, -1, 231, -1, 233, -1, -1, 236, 237, 238, + -1, -1, 241, 242, 243, 244, 245, 246, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, + 259, 260, 261, 262, 263, 264, 265, -1, 267, 268, + 269, 270, 271, -1, 273, 274, -1, 276, -1, 278, + 279, 280, 281, 282, 283, -1, 285, 286, -1, -1, + 289, 290, 291, -1, -1, 294, 295, -1, 297, -1, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, -1, 311, 312, 313, -1, 315, 316, 317, 318, + 319, 320, -1, 322, 323, 324, 325, 326, 327, -1, + 329, 330, 331, 332, 333, 334, 335, 336, -1, 338, + 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, + 349, 350, -1, 352, 353, -1, 355, 356, 357, 358, + 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, + 369, -1, 371, 372, 373, 374, 375, -1, 377, 378, + 379, 380, 381, -1, 383, 384, 385, 386, -1, 388, + 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, + 399, 400, 401, 402, 403, -1, 405, 406, -1, 408, + -1, 410, 411, 412, 413, 414, -1, 416, 417, -1, + -1, 420, 421, 422, 423, 424, -1, 426, 427, 428, + 429, 430, 431, 432, 433, -1, -1, 436, 437, 438, + 439, 440, 441, -1, -1, 444, 445, 446, 447, 448, + 449, 450, -1, 452, -1, 454, 455, 456, 457, 458, + -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, + 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, + 479, 480, 481, 482, 483, 484, 3, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, + 27, 28, -1, 30, 31, 32, -1, -1, -1, -1, + -1, -1, -1, 40, 41, -1, 43, 44, 45, 46, + 47, 48, 49, -1, 51, 52, 53, 54, -1, 56, + 57, 58, 59, 60, 61, -1, -1, 64, 65, 66, + 67, 68, -1, 70, 71, 72, 73, -1, -1, 76, + -1, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, -1, 89, 90, 91, 92, 93, 94, -1, 96, + 97, 98, 99, 100, 101, 102, 103, -1, -1, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + -1, 118, -1, 120, 121, 122, 123, 124, 125, -1, + 127, 128, 129, 130, 131, -1, -1, 134, 135, 136, + 137, 138, -1, 140, 141, 142, -1, 144, 145, 146, + -1, 148, 149, 150, 151, -1, 153, 154, 155, 156, + 157, -1, -1, 160, -1, 162, 163, 164, 165, -1, + 167, -1, 169, 170, -1, 172, 173, 174, 175, 176, + 177, -1, 179, -1, -1, -1, 183, -1, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + -1, 198, 199, 200, 201, 202, 203, -1, 205, 206, + -1, 208, 209, 210, 211, 212, 213, 214, -1, 216, + -1, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, -1, -1, 231, 232, 233, 234, -1, 236, + 237, 238, -1, -1, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, -1, -1, 273, 274, 275, 276, + -1, -1, 279, 280, 281, 282, 283, -1, 285, 286, + -1, -1, 289, 290, 291, -1, -1, 294, -1, 296, + 297, 298, -1, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, -1, 311, 312, -1, 314, 315, 316, + -1, 318, 319, 320, -1, 322, 323, 324, 325, 326, + 327, -1, 329, 330, 331, 332, 333, 334, 335, 336, + -1, 338, 339, 340, 341, 342, 343, 344, 345, 346, + 347, 348, 349, 350, -1, 352, 353, 354, 355, 356, + 357, -1, 359, 360, 361, 362, 363, 364, 365, 366, + 367, 368, 369, -1, 371, 372, 373, 374, 375, 376, + 377, -1, 379, 380, 381, 382, 383, 384, 385, 386, + -1, 388, 389, 390, 391, 392, 393, 394, 395, 396, + 397, 398, 399, 400, 401, -1, 403, -1, 405, 406, + -1, 408, 409, 410, 411, 412, 413, 414, -1, 416, + 417, -1, -1, 420, 421, -1, 423, -1, -1, 426, + 427, 428, 429, 430, 431, 432, 433, -1, -1, 436, + 437, 438, 439, 440, 441, 442, -1, 444, 445, 446, + 447, 448, -1, 450, -1, 452, 453, 454, 455, 456, + 457, 458, -1, -1, 461, -1, -1, 464, 465, 466, + 467, 468, 469, 3, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 481, 482, 483, 484, -1, -1, + -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, + 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, + 40, 41, -1, 43, 44, 45, -1, 47, 48, 49, + 50, 51, -1, 53, 54, -1, 56, 57, 58, 59, + 60, 61, -1, -1, 64, 65, 66, 67, 68, -1, + 70, 71, 72, 73, 74, -1, -1, -1, 78, 79, + 80, 81, 82, 83, -1, 85, 86, 87, -1, 89, + 90, 91, 92, 93, 94, -1, -1, 97, 98, 99, + -1, -1, -1, -1, -1, -1, -1, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, -1, 118, -1, + 120, 121, 122, 123, 124, 125, -1, 127, 128, 129, + 130, 131, -1, -1, 134, 135, 136, 137, 138, -1, + 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, -1, + 160, -1, 162, 163, 164, 165, -1, 167, -1, 169, + -1, -1, -1, 173, 174, 175, -1, 177, -1, 179, + -1, 181, 182, 183, -1, 185, 186, 187, 188, 189, + 190, 191, -1, 193, 194, 195, 196, -1, 198, 199, + 200, 201, 202, 203, -1, 205, -1, 207, 208, 209, + 210, 211, 212, 213, 214, -1, 216, -1, 218, -1, + -1, 221, -1, 223, 224, 225, 226, 227, 228, -1, + -1, 231, -1, 233, -1, -1, 236, 237, 238, -1, + -1, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, -1, 267, 268, 269, + 270, 271, -1, 273, 274, -1, 276, -1, 278, 279, + 280, 281, 282, 283, -1, 285, 286, -1, -1, 289, + 290, 291, -1, -1, 294, 295, -1, 297, -1, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + -1, 311, 312, 313, -1, 315, 316, 317, 318, 319, + 320, -1, 322, 323, 324, 325, 326, 327, -1, 329, + 330, 331, 332, 333, 334, 335, 336, -1, 338, 339, + 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, + 350, -1, 352, 353, -1, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, + -1, 371, 372, 373, 374, 375, -1, 377, 378, 379, + 380, 381, -1, 383, 384, 385, 386, -1, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, + 400, 401, 402, 403, -1, 405, 406, -1, 408, -1, + 410, 411, 412, 413, 414, -1, 416, 417, -1, -1, + 420, 421, 422, 423, 424, -1, 426, 427, 428, 429, + 430, 431, 432, 433, -1, -1, 436, 437, 438, 439, + 440, 441, -1, -1, 444, 445, 446, 447, 448, 449, + 450, -1, 452, -1, 454, 455, 456, 457, 458, -1, + -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, + 480, 481, 482, 483, 484, 3, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, + 28, -1, 30, 31, 32, -1, -1, -1, -1, -1, + -1, -1, 40, 41, -1, 43, 44, 45, -1, 47, + 48, 49, 50, 51, -1, 53, 54, -1, 56, 57, + 58, 59, 60, 61, -1, -1, 64, 65, 66, 67, + 68, -1, 70, 71, 72, 73, 74, -1, -1, -1, + 78, 79, 80, 81, 82, 83, -1, 85, 86, 87, + -1, 89, 90, 91, 92, 93, 94, -1, -1, 97, + 98, 99, -1, -1, -1, -1, -1, -1, -1, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, -1, + 118, -1, 120, 121, 122, 123, 124, 125, -1, 127, + 128, 129, 130, 131, -1, -1, 134, 135, 136, 137, + 138, -1, 140, 141, 142, -1, 144, 145, 146, -1, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, -1, 160, -1, 162, 163, 164, 165, -1, 167, + -1, 169, -1, -1, -1, 173, 174, 175, -1, 177, + -1, 179, -1, 181, 182, 183, -1, 185, 186, 187, + 188, 189, 190, 191, -1, 193, 194, 195, 196, -1, + 198, 199, 200, 201, 202, 203, -1, 205, -1, 207, + 208, 209, 210, 211, 212, 213, 214, -1, 216, -1, + 218, -1, -1, 221, -1, 223, 224, 225, 226, 227, + 228, -1, -1, 231, -1, 233, -1, -1, 236, 237, + 238, -1, -1, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, -1, 267, + 268, 269, 270, 271, -1, 273, 274, -1, 276, -1, + 278, 279, 280, 281, 282, 283, -1, 285, 286, -1, + -1, 289, 290, 291, -1, -1, 294, 295, -1, 297, + -1, 299, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, -1, 311, 312, 313, -1, 315, 316, 317, + 318, 319, 320, -1, 322, 323, 324, 325, 326, 327, + -1, 329, 330, 331, 332, 333, 334, 335, 336, -1, + 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, + 348, 349, 350, -1, 352, 353, -1, 355, 356, 357, + 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, + 368, 369, -1, 371, 372, 373, 374, 375, -1, 377, + 378, 379, 380, 381, -1, 383, 384, 385, 386, -1, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, -1, 405, 406, -1, + 408, -1, 410, 411, 412, 413, 414, -1, 416, 417, + -1, -1, 420, 421, 422, 423, 424, -1, 426, 427, + 428, 429, 430, 431, 432, 433, -1, -1, 436, 437, + 438, 439, 440, 441, -1, -1, 444, 445, 446, 447, + 448, 449, 450, -1, 452, -1, 454, 455, 456, 457, + 458, -1, -1, 461, -1, -1, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, + 478, 479, 480, 481, 482, 483, 484, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, @@ -309323,24 +323437,217 @@ static const yytype_int16 yycheck[] = 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, + 306, 307, 308, 309, -1, 311, 312, 313, -1, 315, + 316, 317, 318, 319, 320, -1, 322, 323, 324, 325, + 326, 327, -1, 329, 330, 331, 332, 333, 334, 335, + 336, -1, 338, 339, 340, 341, 342, 343, 344, 345, + 346, 347, 348, 349, 350, -1, 352, 353, -1, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, + 366, 367, 368, 369, -1, 371, 372, 373, 374, 375, + -1, 377, 378, 379, 380, 381, -1, 383, 384, 385, + 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 403, -1, 405, + 406, -1, 408, -1, 410, 411, 412, 413, 414, -1, + 416, 417, -1, -1, 420, 421, 422, 423, 424, -1, + 426, 427, 428, 429, 430, 431, 432, 433, -1, -1, + 436, 437, 438, 439, 440, 441, -1, -1, 444, 445, + 446, 447, 448, 449, 450, -1, 452, -1, 454, 455, + 456, 457, 458, -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, + 476, 477, 478, 479, 480, 481, 482, 483, 484, 3, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, + 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, + -1, -1, -1, -1, -1, -1, 40, 41, -1, 43, + 44, 45, -1, 47, 48, 49, 50, 51, -1, 53, + 54, -1, 56, 57, 58, 59, 60, 61, -1, -1, + 64, 65, 66, 67, 68, -1, 70, 71, 72, 73, + 74, -1, -1, -1, 78, 79, 80, 81, 82, 83, + -1, 85, 86, 87, -1, 89, 90, 91, 92, 93, + 94, -1, -1, 97, 98, 99, -1, -1, -1, -1, + -1, -1, -1, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, -1, 118, -1, 120, 121, 122, 123, + 124, 125, -1, 127, 128, 129, 130, 131, -1, -1, + 134, 135, 136, 137, 138, -1, 140, 141, 142, -1, + 144, 145, 146, -1, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, -1, 160, -1, 162, 163, + 164, 165, -1, 167, -1, 169, -1, -1, -1, 173, + 174, 175, -1, 177, -1, 179, -1, 181, 182, 183, + -1, 185, 186, 187, 188, 189, 190, 191, -1, 193, + 194, 195, 196, -1, 198, 199, 200, 201, 202, 203, + -1, 205, -1, 207, 208, 209, 210, 211, 212, 213, + 214, -1, 216, -1, 218, -1, -1, 221, -1, 223, + 224, 225, 226, 227, 228, -1, -1, 231, -1, 233, + -1, -1, 236, 237, 238, -1, -1, 241, 242, 243, + 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, + 264, 265, -1, 267, 268, 269, 270, 271, -1, 273, + 274, -1, 276, -1, 278, 279, 280, 281, 282, 283, + -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, + 294, 295, -1, 297, -1, 299, 300, 301, 302, 303, + 304, 305, 306, 307, 308, 309, -1, 311, 312, 313, + -1, 315, 316, 317, 318, 319, 320, -1, 322, 323, + 324, 325, 326, 327, -1, 329, 330, 331, 332, 333, + 334, 335, 336, -1, 338, 339, 340, 341, 342, 343, + 344, 345, 346, 347, 348, 349, 350, -1, 352, 353, + -1, 355, 356, 357, 358, 359, 360, 361, 362, 363, + 364, 365, 366, 367, 368, 369, -1, 371, 372, 373, + 374, 375, -1, 377, 378, 379, 380, 381, -1, 383, + 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, + -1, 405, 406, -1, 408, -1, 410, 411, 412, 413, + 414, -1, 416, 417, -1, -1, 420, 421, 422, 423, + 424, -1, 426, 427, 428, 429, 430, 431, 432, 433, + -1, -1, 436, 437, 438, 439, 440, 441, -1, -1, + 444, 445, 446, 447, 448, 449, 450, -1, 452, -1, + 454, 455, 456, 457, 458, -1, -1, 461, -1, -1, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, + 484, 3, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, + 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, + 32, -1, -1, -1, -1, -1, -1, -1, 40, 41, + -1, 43, 44, 45, -1, 47, 48, 49, 50, 51, + -1, 53, 54, -1, 56, 57, 58, 59, 60, 61, + -1, -1, 64, 65, 66, 67, 68, -1, 70, 71, + 72, 73, 74, -1, -1, -1, 78, 79, 80, 81, + 82, 83, -1, 85, 86, 87, -1, 89, 90, 91, + 92, 93, 94, -1, -1, 97, 98, 99, -1, -1, + -1, -1, -1, -1, -1, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, -1, 118, -1, 120, 121, + 122, 123, 124, 125, -1, 127, 128, 129, 130, 131, + -1, -1, 134, 135, 136, 137, 138, -1, 140, 141, + 142, -1, 144, 145, 146, -1, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, -1, 160, -1, + 162, 163, 164, 165, -1, 167, -1, 169, -1, -1, + -1, 173, 174, 175, -1, 177, -1, 179, -1, 181, + 182, 183, -1, 185, 186, 187, 188, 189, 190, 191, + -1, 193, 194, 195, 196, -1, 198, 199, 200, 201, + 202, 203, -1, 205, -1, 207, 208, 209, 210, 211, + 212, 213, 214, -1, 216, -1, 218, -1, -1, 221, + -1, 223, 224, 225, 226, 227, 228, -1, -1, 231, + -1, 233, -1, -1, 236, 237, 238, -1, -1, 241, + 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, -1, 267, 268, 269, 270, 271, + -1, 273, 274, -1, 276, -1, 278, 279, 280, 281, + 282, 283, -1, 285, 286, -1, -1, 289, 290, 291, + -1, -1, 294, 295, -1, 297, -1, 299, 300, 301, + 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, + 312, 313, -1, 315, 316, 317, 318, 319, 320, -1, + 322, 323, 324, 325, 326, 327, -1, 329, 330, 331, + 332, 333, 334, 335, 336, -1, 338, 339, 340, 341, + 342, 343, 344, 345, 346, 347, 348, 349, 350, -1, + 352, 353, -1, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, 365, 366, 367, 368, 369, -1, 371, + 372, 373, 374, 375, -1, 377, 378, 379, 380, 381, + -1, 383, 384, 385, 386, -1, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, + 402, 403, -1, 405, 406, -1, 408, -1, 410, 411, + 412, 413, 414, -1, 416, 417, -1, -1, 420, 421, + 422, 423, 424, -1, 426, 427, 428, 429, 430, 431, + 432, 433, -1, -1, 436, 437, 438, 439, 440, 441, + -1, -1, 444, 445, 446, 447, 448, 449, 450, -1, + 452, -1, 454, 455, 456, 457, 458, -1, -1, 461, + -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, + 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, + 482, 483, 484, 3, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, + 30, 31, 32, -1, -1, -1, -1, -1, 38, -1, + 40, 41, -1, 43, 44, 45, -1, 47, 48, 49, + 50, 51, -1, 53, 54, -1, 56, 57, 58, 59, + 60, 61, -1, -1, 64, 65, 66, 67, 68, -1, + 70, 71, 72, 73, 74, -1, -1, -1, 78, 79, + 80, 81, 82, 83, -1, 85, 86, 87, -1, 89, + 90, 91, 92, 93, 94, -1, -1, 97, 98, 99, + -1, -1, -1, -1, -1, -1, -1, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, -1, 118, -1, + 120, 121, 122, 123, 124, 125, -1, 127, 128, 129, + 130, 131, -1, -1, 134, 135, 136, 137, 138, -1, + 140, 141, 142, -1, 144, 145, 146, -1, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, -1, + 160, -1, 162, 163, 164, 165, -1, 167, -1, 169, + -1, -1, -1, 173, 174, 175, -1, 177, -1, 179, + -1, 181, 182, 183, -1, 185, 186, 187, 188, 189, + 190, 191, -1, 193, 194, 195, 196, -1, 198, 199, + 200, 201, 202, 203, -1, 205, -1, 207, 208, 209, + 210, 211, 212, 213, 214, -1, 216, -1, 218, -1, + -1, 221, -1, 223, 224, 225, 226, 227, 228, -1, + -1, 231, -1, 233, -1, -1, 236, 237, 238, -1, + -1, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, -1, 267, 268, 269, + 270, 271, -1, 273, 274, -1, 276, -1, 278, 279, + 280, 281, 282, 283, -1, 285, 286, -1, -1, 289, + 290, 291, -1, -1, 294, 295, -1, 297, -1, 299, + 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, + -1, 311, 312, 313, -1, 315, 316, 317, 318, 319, + 320, -1, 322, 323, 324, 325, 326, 327, -1, 329, + 330, 331, 332, 333, 334, 335, 336, -1, 338, 339, + 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, + 350, -1, 352, 353, -1, 355, 356, 357, 358, 359, + 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, + -1, 371, 372, 373, 374, 375, -1, -1, 378, 379, + 380, 381, -1, 383, 384, 385, 386, -1, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, + 400, 401, 402, 403, -1, 405, 406, -1, 408, -1, + 410, 411, 412, 413, 414, -1, 416, 417, -1, -1, + 420, 421, 422, 423, 424, -1, 426, 427, 428, 429, + 430, 431, 432, 433, -1, -1, 436, 437, 438, 439, + 440, 441, -1, -1, 444, 445, 446, 447, 448, 449, + 450, -1, 452, -1, 454, 455, 456, 457, 458, -1, + -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, + 480, 481, 482, 483, 484, 3, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, + 28, -1, 30, 31, 32, -1, -1, -1, -1, -1, + -1, -1, 40, 41, -1, 43, 44, 45, -1, 47, + 48, 49, 50, 51, -1, 53, 54, -1, 56, 57, + 58, 59, 60, 61, -1, -1, 64, 65, 66, 67, + 68, -1, 70, 71, 72, 73, 74, -1, -1, -1, + 78, 79, 80, 81, 82, 83, -1, 85, 86, 87, + -1, 89, 90, 91, 92, 93, 94, -1, -1, 97, + 98, 99, -1, -1, -1, -1, -1, -1, -1, 107, + 108, 109, 110, 111, 112, 113, 114, 115, 116, -1, + 118, -1, 120, 121, 122, 123, 124, 125, -1, 127, + 128, 129, 130, 131, -1, -1, 134, 135, 136, 137, + 138, -1, 140, 141, 142, -1, 144, 145, 146, -1, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, + 158, -1, 160, -1, 162, 163, 164, 165, -1, 167, + -1, 169, -1, -1, -1, 173, 174, 175, -1, 177, + -1, 179, -1, 181, 182, 183, -1, 185, 186, 187, + 188, 189, 190, 191, -1, 193, 194, 195, 196, -1, + 198, 199, 200, 201, 202, 203, -1, 205, -1, 207, + 208, 209, 210, 211, 212, 213, 214, -1, 216, -1, + 218, -1, -1, 221, -1, 223, 224, 225, 226, 227, + 228, -1, -1, 231, -1, 233, -1, -1, 236, 237, + 238, -1, -1, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, + 258, 259, 260, 261, 262, 263, 264, 265, -1, 267, + 268, 269, 270, 271, -1, 273, 274, -1, 276, -1, + 278, 279, 280, 281, 282, 283, -1, 285, 286, -1, + -1, 289, 290, 291, -1, -1, 294, 295, -1, 297, + -1, 299, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, -1, 311, 312, 313, -1, 315, 316, 317, + 318, 319, 320, -1, 322, 323, 324, 325, 326, 327, + -1, 329, 330, 331, 332, 333, 334, 335, 336, -1, + 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, + 348, 349, 350, -1, 352, 353, -1, 355, 356, 357, + 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, + 368, 369, -1, 371, 372, 373, 374, 375, -1, 377, + 378, 379, 380, 381, -1, 383, 384, 385, 386, -1, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, -1, 405, 406, -1, + 408, -1, 410, 411, 412, 413, 414, -1, 416, 417, + -1, -1, 420, 421, 422, 423, 424, -1, 426, 427, + 428, 429, 430, 431, 432, 433, -1, -1, 436, 437, + 438, 439, 440, 441, -1, -1, 444, 445, 446, 447, + 448, 449, 450, -1, 452, -1, 454, 455, 456, 457, + 458, -1, -1, 461, -1, -1, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, + 478, 479, 480, 481, 482, 483, 484, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, @@ -309371,538 +323678,549 @@ static const yytype_int16 yycheck[] = 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, + 306, 307, 308, 309, -1, 311, 312, 313, -1, 315, + 316, 317, 318, 319, 320, -1, 322, 323, 324, 325, + 326, 327, -1, 329, 330, 331, 332, 333, 334, 335, + 336, -1, 338, 339, 340, 341, 342, 343, 344, 345, + 346, 347, 348, 349, 350, -1, 352, 353, -1, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, + 366, 367, 368, 369, -1, 371, 372, 373, 374, 375, + -1, 377, 378, 379, 380, 381, -1, 383, 384, 385, + 386, -1, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 403, -1, 405, + 406, -1, 408, -1, 410, 411, 412, 413, 414, -1, + 416, 417, -1, -1, 420, 421, 422, 423, 424, -1, + 426, 427, 428, 429, 430, 431, 432, 433, -1, -1, + 436, 437, 438, 439, 440, 441, -1, -1, 444, 445, + 446, 447, 448, 449, 450, -1, 452, -1, 454, 455, + 456, 457, 458, -1, -1, 461, -1, -1, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 3, -1, -1, + 476, 477, 478, 479, 480, 481, 482, 483, 484, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - 46, 47, 48, 49, -1, 51, 52, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, -1, -1, - 76, -1, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - 96, 97, 98, 99, 100, 101, 102, 103, -1, -1, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, -1, 153, 154, 155, - 156, 157, -1, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, 170, -1, 172, 173, 174, 175, - 176, 177, -1, 179, -1, -1, -1, 183, -1, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - 206, -1, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, -1, -1, 231, 232, 233, 234, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, -1, -1, 273, 274, 275, - 276, -1, -1, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, -1, - 296, 297, 298, -1, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, -1, 311, 312, -1, 314, 315, - -1, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, 329, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, 353, 354, 355, - 356, -1, 358, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, 375, - 376, -1, 378, 379, 380, 381, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, -1, 402, -1, 404, 405, - -1, 407, 408, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, -1, 422, -1, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, 440, -1, 442, 443, 444, 445, - 446, -1, 448, -1, 450, 451, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 3, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 479, 480, 481, 482, -1, -1, -1, - 21, 22, 23, 24, 25, 26, 27, 28, -1, 30, - 31, 32, -1, -1, -1, -1, -1, -1, -1, 40, - 41, -1, 43, 44, 45, 46, 47, 48, 49, -1, - 51, 52, 53, 54, -1, 56, 57, 58, 59, 60, - 61, -1, -1, 64, 65, 66, 67, 68, -1, 70, - 71, 72, 73, -1, -1, 76, -1, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, -1, 89, 90, - 91, 92, 93, 94, -1, 96, 97, 98, 99, 100, - 101, 102, 103, -1, -1, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, -1, 118, -1, 120, - 121, 122, 123, 124, 125, -1, 127, 128, 129, 130, - 131, -1, -1, 134, 135, 136, 137, 138, -1, 140, - 141, 142, -1, 144, 145, 146, -1, 148, 149, 150, - 151, -1, 153, 154, 155, 156, 157, -1, -1, 160, - -1, 162, 163, 164, 165, -1, 167, -1, 169, 170, - -1, 172, 173, 174, -1, 176, 177, -1, 179, -1, - -1, -1, 183, -1, 185, 186, 187, 188, 189, 190, - 191, 192, 193, 194, 195, 196, -1, 198, 199, 200, - 201, 202, 203, -1, 205, 206, -1, 208, 209, 210, - 211, 212, 213, 214, -1, 216, -1, 218, 219, 220, - 221, 222, 223, 224, 225, 226, 227, 228, -1, -1, - 231, 232, 233, 234, -1, 236, 237, 238, -1, -1, - 241, 242, 243, 244, 245, -1, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - -1, -1, 273, 274, 275, 276, -1, -1, 279, 280, - 281, 282, 283, -1, 285, 286, -1, -1, 289, 290, - 291, -1, -1, 294, -1, 296, 297, 298, -1, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, -1, - 311, 312, -1, 314, 315, -1, 317, 318, 319, -1, - 321, 322, 323, 324, 325, 326, -1, 328, 329, 330, - 331, 332, 333, 334, 335, -1, 337, 338, 339, 340, - 341, 342, 343, 344, 345, 346, 347, 348, 349, -1, - 351, 352, 353, 354, 355, 356, -1, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, -1, 370, - 371, 372, 373, 374, 375, 376, -1, 378, 379, 380, - 381, 382, 383, 384, 385, -1, 387, 388, 389, 390, - 391, 392, 393, 394, 395, 396, 397, 398, -1, 400, - -1, 402, -1, 404, 405, -1, 407, 408, 409, 410, - 411, 412, 413, -1, 415, 416, -1, -1, 419, 420, - -1, 422, -1, -1, 425, 426, 427, 428, 429, 430, - 431, 432, -1, -1, 435, 436, 437, 438, 439, 440, - -1, 442, 443, 444, 445, 446, -1, 448, -1, 450, - 451, 452, 453, 454, 455, 456, -1, -1, 459, -1, - -1, 462, 463, 464, 465, 466, 467, 3, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 479, 480, - 481, 482, -1, -1, -1, 21, 22, 23, 24, 25, - 26, 27, 28, -1, 30, 31, 32, -1, -1, -1, - -1, -1, -1, -1, 40, 41, -1, 43, 44, 45, - -1, 47, 48, 49, 50, 51, -1, 53, 54, -1, - 56, 57, 58, 59, 60, 61, -1, -1, 64, 65, - 66, 67, 68, -1, 70, 71, 72, 73, 74, -1, - -1, -1, 78, 79, 80, 81, 82, 83, -1, 85, - 86, 87, -1, 89, 90, 91, 92, 93, 94, -1, - -1, 97, 98, 99, -1, -1, -1, -1, -1, -1, - -1, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, -1, 118, -1, 120, 121, 122, 123, 124, 125, - -1, 127, 128, 129, 130, 131, -1, -1, 134, 135, - 136, 137, 138, -1, 140, 141, 142, -1, 144, 145, - 146, -1, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, -1, 160, -1, 162, 163, 164, 165, - -1, 167, -1, 169, -1, -1, -1, 173, 174, 175, - -1, 177, -1, 179, -1, 181, 182, 183, -1, 185, - 186, 187, 188, 189, 190, 191, -1, 193, 194, 195, - 196, -1, 198, 199, 200, 201, 202, 203, -1, 205, - -1, 207, 208, 209, 210, 211, 212, 213, 214, -1, - 216, -1, 218, -1, -1, 221, -1, 223, 224, 225, - 226, 227, 228, -1, -1, 231, -1, 233, -1, -1, - 236, 237, 238, -1, -1, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - -1, 267, 268, 269, 270, 271, -1, 273, 274, -1, - 276, -1, 278, 279, 280, 281, 282, 283, -1, 285, - 286, -1, -1, 289, 290, 291, -1, -1, 294, 295, - -1, 297, -1, 299, 300, 301, 302, 303, 304, 305, - -1, 307, 308, 309, -1, 311, 312, 313, 314, 315, - 316, 317, 318, 319, -1, 321, 322, 323, 324, 325, - 326, -1, 328, -1, 330, 331, 332, 333, 334, 335, - -1, 337, 338, 339, 340, 341, 342, 343, 344, 345, - 346, 347, 348, 349, -1, 351, 352, -1, 354, 355, - 356, 357, -1, 359, 360, 361, 362, 363, 364, 365, - 366, 367, 368, -1, 370, 371, 372, 373, 374, -1, - 376, 377, 378, 379, 380, -1, 382, 383, 384, 385, - -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, - -1, 407, -1, 409, 410, 411, 412, 413, -1, 415, - 416, -1, -1, 419, 420, 421, 422, 423, -1, 425, - 426, 427, 428, 429, 430, 431, 432, -1, -1, 435, - 436, 437, 438, 439, -1, -1, 442, 443, 444, 445, - 446, 447, 448, -1, 450, -1, 452, 453, 454, 455, - 456, -1, -1, 459, -1, -1, 462, 463, 464, 465, - 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, - 476, 477, 478, 479, 480, 481, 482, 21, 21, -1, - -1, -1, -1, -1, -1, -1, -1, 31, 31, 33, - 34, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 49, 49, -1, -1, -1, - -1, -1, -1, -1, 58, 58, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 70, 70, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 81, 81, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 93, - 93, 95, 95, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 113, - 113, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 127, 127, -1, -1, -1, -1, -1, - -1, -1, -1, 137, 137, -1, -1, -1, -1, 143, - 143, -1, -1, -1, -1, -1, -1, 151, 151, -1, + -1, -1, -1, -1, -1, -1, -1, 21, 22, 23, + 24, 25, 26, 27, 28, -1, 30, 31, 32, -1, + -1, -1, -1, -1, -1, -1, 40, 41, -1, 43, + 44, 45, -1, 47, 48, 49, 50, 51, -1, 53, + 54, -1, 56, 57, 58, 59, 60, 61, -1, -1, + 64, 65, 66, 67, 68, -1, 70, 71, 72, 73, + 74, -1, -1, -1, 78, 79, 80, 81, 82, 83, + -1, 85, 86, 87, -1, 89, 90, 91, 92, 93, + 94, -1, -1, 97, 98, 99, -1, -1, -1, -1, + -1, -1, -1, 107, 108, 109, 110, 111, 112, 113, + 114, 115, 116, -1, 118, -1, 120, 121, 122, 123, + 124, 125, -1, 127, 128, 129, 130, 131, -1, -1, + 134, 135, 136, 137, 138, -1, 140, 141, 142, -1, + 144, 145, 146, -1, 148, 149, 150, 151, 152, 153, + 154, 155, 156, 157, 158, -1, 160, -1, 162, 163, + 164, 165, -1, 167, -1, 169, -1, -1, -1, 173, + 174, 175, -1, 177, -1, 179, -1, 181, 182, 183, + -1, 185, 186, 187, 188, 189, 190, 191, -1, 193, + 194, 195, 196, -1, 198, 199, 200, 201, 202, 203, + -1, 205, -1, 207, 208, 209, 210, 211, 212, 213, + 214, -1, 216, -1, 218, -1, -1, 221, -1, 223, + 224, 225, 226, 227, 228, -1, -1, 231, -1, 233, + -1, -1, 236, 237, 238, -1, -1, 241, 242, 243, + 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, + 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, + 264, 265, -1, 267, 268, 269, 270, 271, -1, 273, + 274, -1, 276, -1, 278, 279, 280, 281, 282, 283, + -1, 285, 286, -1, -1, 289, 290, 291, -1, -1, + 294, 295, -1, 297, -1, 299, 300, 301, 302, 303, + 304, 305, 306, 307, 308, 309, -1, 311, 312, 313, + -1, 315, 316, 317, 318, 319, 320, -1, 322, 323, + 324, 325, 326, 327, -1, 329, 330, 331, 332, 333, + 334, 335, 336, -1, 338, 339, 340, 341, 342, 343, + 344, 345, 346, 347, 348, 349, 350, -1, 352, 353, + -1, 355, 356, 357, 358, 359, 360, 361, 362, 363, + 364, 365, 366, 367, 368, 369, -1, 371, 372, 373, + 374, 375, -1, 377, 378, 379, 380, 381, -1, 383, + 384, 385, 386, -1, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, + -1, 405, 406, -1, 408, -1, 410, 411, 412, 413, + 414, -1, 416, 417, -1, -1, 420, 421, 422, 423, + 424, -1, 426, 427, 428, 429, 430, 431, 432, 433, + -1, -1, 436, 437, 438, 439, 440, 441, -1, -1, + 444, 445, 446, 447, 448, 449, 450, -1, 452, -1, + 454, 455, 456, 457, 458, -1, -1, 461, -1, -1, + 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, + 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, + 484, 3, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 21, + 22, 23, 24, 25, 26, 27, 28, -1, 30, 31, + 32, -1, -1, -1, -1, -1, -1, -1, 40, 41, + -1, 43, 44, 45, 46, 47, 48, 49, -1, 51, + 52, 53, 54, -1, 56, 57, 58, 59, 60, 61, + -1, -1, 64, 65, 66, 67, 68, -1, 70, 71, + 72, 73, -1, -1, 76, -1, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, -1, 89, 90, 91, + 92, 93, 94, -1, 96, 97, 98, 99, 100, 101, + 102, 103, -1, -1, 106, 107, 108, 109, 110, 111, + 112, 113, 114, 115, 116, -1, 118, -1, 120, 121, + 122, 123, 124, 125, -1, 127, 128, 129, 130, 131, + -1, -1, 134, 135, 136, 137, 138, -1, 140, 141, + 142, -1, 144, 145, 146, -1, 148, 149, 150, 151, + -1, 153, 154, 155, 156, 157, -1, -1, 160, -1, + 162, 163, 164, 165, -1, 167, -1, 169, 170, -1, + 172, 173, 174, -1, 176, 177, -1, 179, -1, -1, + -1, 183, -1, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, -1, 198, 199, 200, 201, + 202, 203, -1, 205, 206, -1, 208, 209, 210, 211, + 212, 213, 214, -1, 216, -1, 218, 219, 220, 221, + 222, 223, 224, 225, 226, 227, 228, -1, -1, 231, + 232, 233, 234, -1, 236, 237, 238, -1, -1, 241, + 242, 243, 244, 245, -1, 247, 248, 249, 250, 251, + 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, + 262, 263, 264, 265, 266, 267, 268, 269, 270, -1, + -1, 273, 274, 275, 276, -1, -1, 279, 280, 281, + 282, 283, -1, 285, 286, -1, -1, 289, 290, 291, + -1, -1, 294, -1, 296, 297, 298, -1, 300, 301, + 302, 303, 304, 305, 306, 307, 308, 309, -1, 311, + 312, -1, 314, 315, 316, -1, 318, 319, 320, -1, + 322, 323, 324, 325, 326, 327, -1, 329, 330, 331, + 332, 333, 334, 335, 336, -1, 338, 339, 340, 341, + 342, 343, 344, 345, 346, 347, 348, 349, 350, -1, + 352, 353, 354, 355, 356, 357, -1, 359, 360, 361, + 362, 363, 364, 365, 366, 367, 368, 369, -1, 371, + 372, 373, 374, 375, 376, 377, -1, 379, 380, 381, + 382, 383, 384, 385, 386, -1, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, 398, 399, -1, 401, + -1, 403, -1, 405, 406, -1, 408, 409, 410, 411, + 412, 413, 414, -1, 416, 417, -1, -1, 420, 421, + -1, 423, -1, -1, 426, 427, 428, 429, 430, 431, + 432, 433, -1, -1, 436, 437, 438, 439, 440, 441, + 442, -1, 444, 445, 446, 447, 448, -1, 450, -1, + 452, 453, 454, 455, 456, 457, 458, -1, -1, 461, + -1, -1, 464, 465, 466, 467, 468, 469, 3, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 481, + 482, 483, 484, -1, -1, -1, 21, 22, 23, 24, + 25, 26, 27, 28, -1, 30, 31, 32, -1, -1, + -1, -1, -1, -1, -1, 40, 41, -1, 43, 44, + 45, -1, 47, 48, 49, 50, 51, -1, 53, 54, + -1, 56, 57, 58, 59, 60, 61, -1, -1, 64, + 65, 66, 67, 68, -1, 70, 71, 72, 73, 74, + -1, -1, -1, 78, 79, 80, 81, 82, 83, -1, + 85, 86, 87, -1, 89, 90, 91, 92, 93, 94, + -1, -1, 97, 98, 99, -1, -1, -1, -1, -1, + -1, -1, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, -1, 118, -1, 120, 121, 122, 123, 124, + 125, -1, 127, 128, 129, 130, 131, -1, -1, 134, + 135, 136, 137, 138, -1, 140, 141, 142, -1, 144, + 145, 146, -1, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, -1, 160, -1, 162, 163, 164, + 165, -1, 167, -1, 169, -1, -1, -1, 173, 174, + 175, -1, 177, -1, 179, -1, 181, 182, 183, -1, + 185, 186, 187, 188, 189, 190, 191, -1, 193, 194, + 195, 196, -1, 198, 199, 200, 201, 202, 203, -1, + 205, -1, 207, 208, 209, 210, 211, 212, 213, 214, + -1, 216, -1, 218, -1, -1, 221, -1, 223, 224, + 225, 226, 227, 228, -1, -1, 231, -1, 233, -1, + -1, 236, 237, 238, -1, -1, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, -1, 267, 268, 269, 270, 271, -1, 273, 274, + -1, 276, -1, 278, 279, 280, 281, 282, 283, -1, + 285, 286, -1, -1, 289, 290, 291, -1, -1, 294, + 295, -1, 297, -1, 299, 300, 301, 302, 303, 304, + 305, -1, 307, 308, 309, -1, 311, 312, 313, -1, + 315, 316, 317, 318, 319, 320, -1, 322, 323, 324, + 325, 326, 327, -1, 329, -1, 331, 332, 333, 334, + 335, 336, -1, 338, 339, 340, 341, 342, 343, 344, + 345, 346, 347, 348, 349, 350, -1, 352, 353, -1, + 355, 356, 357, 358, -1, 360, 361, 362, 363, 364, + 365, 366, 367, 368, 369, -1, 371, 372, 373, 374, + 375, -1, 377, 378, 379, 380, 381, -1, 383, 384, + 385, 386, -1, 388, 389, 390, 391, 392, 393, 394, + 395, 396, 397, 398, 399, 400, 401, 402, 403, -1, + 405, 406, -1, 408, -1, 410, 411, 412, 413, 414, + -1, 416, 417, -1, -1, 420, 421, 422, 423, 424, + -1, 426, 427, 428, 429, 430, 431, 432, 433, -1, + -1, 436, 437, 438, 439, 440, 441, -1, -1, 444, + 445, 446, 447, 448, 449, 450, -1, 452, -1, 454, + 455, 456, 457, 458, -1, -1, 461, -1, -1, 464, + 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, + 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, + 21, 21, -1, -1, -1, -1, -1, -1, -1, -1, + 31, 31, 33, 34, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 49, 49, + -1, -1, -1, -1, -1, -1, -1, 58, 58, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 70, + 70, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 81, 81, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 93, 93, 95, 95, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 167, 167, -1, -1, 171, 171, -1, + -1, -1, 113, 113, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 127, 127, -1, -1, + -1, -1, -1, -1, -1, -1, 137, 137, -1, -1, + -1, -1, 143, 143, -1, -1, -1, -1, -1, -1, + 151, 151, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 167, 167, -1, -1, + 171, 171, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 211, 211, -1, + 211, 211, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 237, 237, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 237, 237, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 315, 315, -1, 318, 318, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 314, 314, -1, 317, 317, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 347, 347, -1, -1, + -1, -1, -1, -1, -1, 356, 356, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 370, + 370, -1, -1, -1, -1, -1, 377, 377, -1, -1, + 381, 381, -1, -1, -1, -1, -1, -1, -1, -1, + 391, 391, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 403, 403, -1, -1, 407, 407, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 346, 346, -1, -1, -1, -1, -1, -1, - -1, 355, 355, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 369, 369, -1, -1, -1, - -1, -1, 376, 376, -1, -1, 380, 380, -1, -1, - -1, -1, -1, -1, -1, -1, 390, 390, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 402, 402, - -1, -1, 406, 406, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 426, 426, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 425, 425, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 442, 442, - -1, -1, -1, 447, 447, -1, -1, 451, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 461, 461, -1, + -1, -1, -1, 444, 444, -1, -1, -1, 449, 449, + -1, -1, 453, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 463, 463, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 487, 487, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 485, 485, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 499, 499 + 501, 501 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint16 yystos[] = { - 0, 21, 31, 33, 34, 49, 58, 70, 81, 93, - 95, 113, 127, 137, 143, 151, 153, 154, 167, 171, - 196, 211, 237, 314, 317, 346, 355, 369, 376, 380, - 390, 402, 406, 425, 442, 447, 461, 485, 499, 510, - 511, 512, 513, 524, 525, 527, 531, 546, 549, 550, - 552, 554, 561, 563, 611, 618, 621, 622, 639, 640, - 641, 642, 644, 645, 697, 698, 844, 847, 850, 857, - 858, 859, 860, 861, 868, 872, 878, 880, 885, 889, - 890, 893, 894, 897, 898, 900, 419, 464, 562, 200, - 362, 370, 406, 453, 562, 3, 21, 22, 23, 24, - 25, 26, 27, 28, 30, 31, 32, 40, 41, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 56, 57, 58, 59, 60, 61, 64, 65, 66, - 67, 68, 70, 71, 72, 73, 74, 76, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 89, 90, - 91, 92, 93, 94, 96, 97, 98, 99, 100, 101, - 102, 103, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, 118, 120, 121, 122, 123, 124, 125, - 127, 128, 129, 130, 131, 134, 135, 136, 137, 138, - 140, 141, 142, 144, 145, 146, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 160, 162, 163, - 164, 165, 167, 169, 170, 172, 173, 174, 175, 176, - 177, 179, 181, 182, 183, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 198, 199, 200, - 201, 202, 203, 205, 206, 207, 208, 209, 210, 211, - 212, 213, 214, 216, 218, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 228, 231, 232, 233, 234, 236, - 237, 238, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, 273, 274, 275, 276, 278, 279, 280, - 281, 282, 283, 285, 286, 289, 290, 291, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 311, 312, 313, 314, 315, 316, - 317, 318, 319, 321, 322, 323, 324, 325, 326, 328, - 329, 330, 331, 332, 333, 334, 335, 337, 338, 339, - 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, - 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, - 361, 362, 363, 364, 365, 366, 367, 368, 370, 371, - 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, - 382, 383, 384, 385, 387, 388, 389, 390, 391, 392, - 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, - 404, 405, 407, 408, 409, 410, 411, 412, 413, 415, - 416, 419, 420, 421, 422, 423, 425, 426, 427, 428, - 429, 430, 431, 432, 435, 436, 437, 438, 439, 440, - 442, 443, 444, 445, 446, 447, 448, 450, 451, 452, - 453, 454, 455, 456, 459, 462, 463, 464, 465, 466, - 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, - 477, 478, 479, 480, 481, 482, 756, 829, 833, 836, - 903, 904, 905, 562, 52, 499, 634, 177, 238, 292, - 362, 410, 412, 428, 434, 437, 609, 856, 3, 5, - 29, 175, 246, 317, 399, 827, 833, 834, 903, 23, - 76, 92, 146, 156, 168, 173, 200, 245, 249, 312, - 326, 359, 362, 370, 373, 392, 406, 413, 422, 428, - 453, 612, 613, 616, 562, 827, 451, 499, 513, 524, - 525, 527, 546, 549, 550, 552, 554, 561, 563, 611, - 618, 621, 622, 639, 844, 847, 850, 857, 858, 864, - 868, 872, 878, 880, 885, 890, 893, 897, 898, 900, - 110, 70, 211, 63, 74, 76, 100, 101, 102, 103, - 104, 105, 106, 158, 229, 239, 240, 278, 288, 299, - 313, 358, 375, 401, 421, 423, 427, 440, 447, 499, - 640, 698, 700, 702, 703, 710, 711, 756, 758, 759, - 824, 833, 834, 110, 5, 832, 833, 879, 879, 833, - 827, 29, 415, 419, 833, 891, 892, 895, 562, 29, - 132, 653, 654, 177, 238, 362, 374, 415, 873, 874, - 895, 562, 639, 645, 833, 896, 710, 833, 406, 650, - 172, 499, 882, 499, 334, 646, 647, 827, 646, 640, - 641, 0, 502, 122, 210, 439, 147, 215, 293, 433, - 656, 657, 640, 642, 644, 503, 451, 862, 29, 415, - 419, 639, 896, 190, 824, 827, 190, 824, 190, 710, - 190, 824, 499, 497, 501, 808, 810, 639, 824, 410, - 412, 410, 412, 344, 190, 833, 833, 838, 173, 245, - 334, 370, 406, 453, 619, 200, 29, 827, 251, 422, - 109, 406, 406, 453, 365, 3, 46, 51, 52, 53, - 54, 66, 67, 76, 78, 84, 96, 100, 101, 102, - 103, 106, 114, 115, 136, 164, 170, 172, 176, 190, - 192, 206, 213, 214, 216, 219, 220, 222, 232, 234, - 246, 265, 266, 267, 275, 280, 296, 298, 331, 353, - 357, 375, 377, 381, 384, 399, 408, 415, 416, 427, - 433, 440, 448, 451, 617, 721, 723, 725, 727, 729, - 731, 733, 734, 735, 737, 738, 739, 741, 742, 837, - 903, 906, 190, 614, 838, 190, 825, 827, 190, 827, - 499, 553, 864, 3, 46, 50, 51, 52, 53, 54, - 66, 67, 74, 76, 78, 84, 96, 100, 101, 102, - 103, 106, 114, 115, 152, 158, 164, 170, 172, 175, - 176, 181, 182, 192, 206, 207, 213, 214, 216, 219, - 220, 222, 232, 234, 246, 265, 266, 267, 271, 275, - 278, 280, 295, 296, 298, 299, 313, 316, 331, 353, - 357, 375, 377, 381, 384, 399, 401, 408, 415, 416, - 421, 423, 427, 440, 447, 448, 451, 468, 469, 470, - 471, 472, 473, 474, 475, 476, 477, 478, 865, 867, - 868, 870, 871, 903, 907, 862, 832, 879, 499, 499, - 166, 499, 499, 499, 640, 711, 499, 499, 499, 499, - 824, 499, 499, 171, 499, 499, 499, 499, 640, 698, - 702, 703, 38, 704, 705, 833, 704, 369, 503, 643, - 96, 172, 206, 222, 232, 266, 353, 707, 705, 38, - 704, 706, 833, 485, 715, 492, 810, 832, 488, 499, - 499, 845, 482, 221, 501, 287, 4, 6, 7, 8, - 9, 10, 37, 51, 53, 54, 62, 66, 67, 78, - 114, 115, 117, 152, 159, 164, 181, 182, 213, 214, - 216, 265, 267, 272, 277, 280, 289, 331, 357, 384, - 415, 416, 424, 448, 483, 490, 491, 492, 497, 499, - 504, 505, 506, 640, 687, 726, 729, 732, 733, 734, - 736, 737, 738, 741, 742, 753, 755, 756, 757, 759, - 760, 774, 775, 782, 802, 807, 814, 815, 816, 829, - 830, 831, 832, 833, 813, 815, 873, 873, 832, 873, - 482, 171, 417, 488, 501, 810, 710, 886, 3, 170, - 172, 451, 868, 881, 883, 170, 884, 753, 786, 787, - 833, 646, 503, 499, 840, 500, 500, 512, 171, 217, - 886, 29, 132, 651, 651, 56, 651, 161, 166, 235, - 284, 662, 664, 665, 690, 692, 693, 694, 656, 657, - 499, 824, 482, 221, 152, 25, 31, 137, 291, 342, - 346, 376, 444, 518, 521, 522, 342, 152, 38, 57, - 108, 199, 250, 258, 270, 301, 342, 348, 370, 376, - 390, 521, 555, 558, 152, 342, 376, 521, 152, 342, - 376, 521, 3, 29, 46, 52, 76, 78, 84, 96, - 100, 101, 102, 103, 106, 132, 170, 172, 175, 176, - 192, 206, 219, 220, 222, 232, 234, 246, 266, 275, - 296, 298, 353, 375, 381, 399, 408, 427, 440, 449, - 451, 492, 500, 753, 789, 790, 835, 841, 903, 908, - 753, 809, 3, 29, 33, 34, 35, 36, 37, 38, - 39, 42, 55, 62, 63, 69, 75, 77, 88, 95, - 104, 105, 117, 119, 126, 132, 133, 139, 143, 147, - 159, 161, 166, 168, 171, 178, 180, 184, 197, 204, - 215, 217, 229, 230, 235, 239, 240, 272, 277, 284, - 287, 288, 292, 293, 310, 320, 327, 336, 350, 369, - 386, 403, 406, 414, 417, 418, 424, 433, 434, 441, - 447, 449, 457, 458, 460, 461, 828, 842, 903, 907, - 909, 808, 500, 499, 598, 609, 272, 848, 501, 839, - 38, 453, 190, 824, 190, 824, 902, 824, 190, 824, - 84, 853, 465, 85, 129, 304, 411, 450, 740, 740, - 740, 499, 728, 728, 316, 499, 730, 152, 499, 66, - 67, 740, 728, 725, 463, 485, 499, 743, 499, 743, - 499, 60, 349, 503, 615, 499, 37, 724, 499, 111, + 0, 21, 31, 33, 34, 44, 49, 58, 70, 81, + 93, 95, 113, 127, 128, 137, 143, 151, 153, 154, + 167, 171, 196, 211, 237, 315, 318, 347, 356, 370, + 377, 381, 391, 403, 407, 426, 441, 444, 449, 463, + 487, 501, 513, 514, 515, 516, 527, 528, 530, 534, + 550, 553, 554, 556, 558, 560, 567, 569, 570, 618, + 625, 628, 629, 646, 647, 648, 649, 651, 652, 704, + 705, 853, 856, 859, 866, 867, 869, 870, 871, 878, + 882, 888, 890, 895, 899, 900, 901, 906, 909, 910, + 913, 914, 916, 420, 466, 568, 200, 363, 371, 407, + 455, 110, 902, 568, 3, 21, 22, 23, 24, 25, + 26, 27, 28, 30, 31, 32, 40, 41, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 56, 57, 58, 59, 60, 61, 64, 65, 66, 67, + 68, 70, 71, 72, 73, 74, 76, 78, 79, 80, + 81, 82, 83, 84, 85, 86, 87, 89, 90, 91, + 92, 93, 94, 96, 97, 98, 99, 100, 101, 102, + 103, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 118, 120, 121, 122, 123, 124, 125, 127, + 128, 129, 130, 131, 134, 135, 136, 137, 138, 140, + 141, 142, 144, 145, 146, 148, 149, 150, 151, 152, + 153, 154, 155, 156, 157, 158, 160, 162, 163, 164, + 165, 167, 169, 170, 172, 173, 174, 175, 176, 177, + 179, 181, 182, 183, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 198, 199, 200, 201, + 202, 203, 205, 206, 207, 208, 209, 210, 211, 212, + 213, 214, 216, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 231, 232, 233, 234, 236, 237, + 238, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, + 270, 271, 273, 274, 275, 276, 278, 279, 280, 281, + 282, 283, 285, 286, 289, 290, 291, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 311, 312, 313, 314, 315, 316, 317, + 318, 319, 320, 322, 323, 324, 325, 326, 327, 329, + 330, 331, 332, 333, 334, 335, 336, 338, 339, 340, + 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, + 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, 365, 366, 367, 368, 369, 371, 372, + 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, + 383, 384, 385, 386, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, + 405, 406, 408, 409, 410, 411, 412, 413, 414, 416, + 417, 420, 421, 422, 423, 424, 426, 427, 428, 429, + 430, 431, 432, 433, 436, 437, 438, 439, 440, 441, + 442, 444, 445, 446, 447, 448, 449, 450, 452, 453, + 454, 455, 456, 457, 458, 461, 464, 465, 466, 467, + 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, + 478, 479, 480, 481, 482, 483, 484, 764, 837, 841, + 844, 919, 920, 921, 3, 175, 246, 400, 841, 868, + 919, 568, 52, 501, 641, 5, 110, 177, 238, 292, + 363, 411, 413, 429, 435, 438, 555, 616, 840, 865, + 5, 29, 318, 835, 841, 842, 3, 110, 904, 905, + 23, 76, 92, 110, 146, 156, 168, 173, 200, 245, + 249, 312, 327, 360, 363, 371, 374, 393, 407, 414, + 423, 429, 455, 619, 620, 623, 568, 835, 95, 453, + 501, 516, 527, 528, 530, 550, 553, 556, 558, 560, + 567, 570, 618, 625, 628, 629, 646, 853, 856, 859, + 866, 867, 874, 878, 882, 888, 890, 895, 906, 909, + 913, 914, 916, 110, 70, 211, 63, 74, 76, 100, + 101, 102, 103, 104, 105, 106, 158, 229, 239, 240, + 278, 288, 299, 313, 359, 376, 402, 422, 424, 428, + 442, 449, 501, 647, 705, 707, 709, 710, 717, 718, + 764, 766, 767, 832, 841, 842, 110, 840, 841, 889, + 889, 841, 835, 29, 416, 420, 841, 907, 908, 911, + 568, 29, 132, 660, 661, 177, 238, 363, 375, 416, + 883, 884, 911, 568, 646, 652, 841, 912, 717, 841, + 407, 657, 832, 172, 501, 892, 501, 335, 653, 654, + 835, 653, 647, 648, 0, 504, 122, 210, 440, 147, + 215, 293, 434, 663, 664, 647, 649, 651, 505, 453, + 872, 29, 416, 420, 646, 912, 190, 832, 835, 190, + 832, 190, 717, 190, 832, 840, 501, 499, 503, 816, + 818, 646, 832, 190, 832, 411, 413, 411, 413, 345, + 190, 832, 832, 110, 173, 245, 335, 371, 407, 455, + 626, 200, 29, 835, 190, 621, 841, 846, 505, 251, + 423, 109, 407, 407, 455, 366, 3, 46, 51, 52, + 53, 54, 66, 67, 76, 78, 84, 96, 100, 101, + 102, 103, 106, 114, 115, 136, 164, 170, 172, 176, + 190, 192, 206, 213, 214, 216, 219, 220, 222, 232, + 234, 246, 265, 266, 267, 275, 280, 296, 298, 314, + 332, 354, 358, 376, 378, 382, 385, 400, 409, 416, + 417, 428, 434, 442, 450, 453, 624, 728, 730, 732, + 734, 736, 738, 740, 741, 742, 744, 745, 746, 748, + 749, 845, 919, 922, 190, 621, 190, 833, 835, 190, + 835, 501, 559, 292, 874, 3, 46, 50, 51, 52, + 53, 54, 66, 67, 74, 76, 78, 84, 96, 100, + 101, 102, 103, 106, 114, 115, 152, 158, 164, 170, + 172, 175, 176, 181, 182, 192, 206, 207, 213, 214, + 216, 219, 220, 222, 232, 234, 246, 265, 266, 267, + 271, 275, 278, 280, 295, 296, 298, 299, 313, 314, + 317, 332, 354, 358, 376, 378, 382, 385, 400, 402, + 409, 416, 417, 422, 424, 428, 442, 449, 450, 453, + 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, + 480, 875, 877, 878, 880, 881, 919, 923, 872, 840, + 841, 868, 889, 501, 501, 166, 501, 501, 501, 647, + 718, 501, 501, 501, 501, 832, 501, 501, 171, 501, + 501, 501, 501, 647, 705, 709, 710, 38, 711, 712, + 841, 711, 370, 505, 650, 96, 172, 206, 222, 232, + 266, 314, 354, 714, 712, 38, 711, 713, 841, 487, + 722, 494, 818, 840, 490, 501, 501, 854, 484, 221, + 503, 287, 4, 6, 7, 8, 9, 10, 37, 51, + 53, 54, 62, 66, 67, 78, 114, 115, 117, 152, + 159, 164, 181, 182, 213, 214, 216, 265, 267, 272, + 277, 280, 289, 332, 358, 385, 416, 417, 425, 450, + 485, 492, 493, 494, 499, 501, 506, 507, 508, 509, + 647, 694, 733, 736, 739, 740, 741, 743, 744, 745, + 748, 749, 760, 762, 763, 764, 765, 767, 768, 782, + 783, 790, 810, 815, 822, 823, 824, 837, 838, 839, + 840, 841, 821, 823, 883, 883, 840, 883, 484, 171, + 418, 490, 503, 818, 717, 896, 3, 170, 172, 453, + 878, 891, 893, 170, 894, 760, 794, 795, 841, 653, + 505, 501, 848, 502, 502, 515, 171, 292, 537, 896, + 29, 132, 658, 658, 56, 658, 161, 166, 235, 284, + 669, 671, 672, 697, 699, 700, 701, 663, 664, 501, + 832, 484, 221, 152, 25, 31, 137, 291, 343, 347, + 377, 446, 521, 524, 525, 343, 152, 38, 57, 108, + 199, 250, 258, 270, 301, 343, 349, 371, 377, 391, + 524, 561, 564, 152, 343, 377, 524, 152, 343, 377, + 524, 38, 903, 3, 29, 46, 52, 76, 78, 84, + 96, 100, 101, 102, 103, 106, 132, 170, 172, 175, + 176, 192, 206, 219, 220, 222, 232, 234, 246, 266, + 275, 296, 298, 314, 354, 376, 382, 400, 409, 428, + 442, 451, 453, 494, 502, 760, 797, 798, 843, 849, + 919, 924, 760, 817, 3, 29, 33, 34, 35, 36, + 37, 38, 39, 42, 55, 62, 63, 69, 75, 77, + 88, 95, 104, 105, 117, 119, 126, 132, 133, 139, + 143, 147, 159, 161, 166, 168, 171, 178, 180, 184, + 197, 204, 215, 217, 229, 230, 235, 239, 240, 272, + 277, 284, 287, 288, 292, 293, 310, 321, 328, 337, + 351, 370, 387, 404, 407, 415, 418, 419, 425, 434, + 435, 443, 449, 451, 459, 460, 462, 463, 836, 850, + 919, 923, 925, 816, 502, 501, 605, 272, 171, 110, + 616, 272, 857, 38, 832, 455, 190, 832, 190, 832, + 918, 190, 832, 190, 832, 84, 862, 152, 505, 503, + 847, 904, 467, 85, 129, 304, 412, 452, 747, 747, + 747, 501, 735, 735, 317, 501, 737, 152, 501, 66, + 67, 747, 735, 732, 465, 487, 501, 750, 501, 750, + 501, 60, 350, 505, 622, 501, 37, 731, 501, 111, 112, 187, 188, 252, 253, 254, 255, 256, 257, 260, - 261, 366, 367, 479, 480, 499, 744, 745, 746, 747, - 748, 749, 750, 751, 752, 728, 152, 503, 615, 152, - 503, 615, 152, 287, 787, 500, 503, 4, 159, 287, - 424, 490, 491, 557, 560, 831, 832, 863, 865, 866, - 869, 864, 499, 629, 633, 753, 787, 499, 831, 831, - 3, 744, 745, 746, 747, 748, 749, 750, 751, 792, - 793, 832, 705, 706, 831, 831, 753, 824, 753, 794, - 490, 491, 754, 755, 775, 782, 796, 499, 753, 786, - 797, 753, 55, 171, 230, 418, 753, 787, 800, 753, - 500, 834, 408, 670, 671, 499, 671, 653, 654, 702, - 217, 648, 222, 296, 708, 702, 708, 222, 707, 708, - 222, 671, 499, 834, 671, 499, 294, 557, 869, 875, - 877, 789, 723, 791, 38, 233, 833, 499, 811, 497, - 640, 753, 806, 499, 640, 753, 499, 499, 753, 753, - 753, 148, 817, 818, 753, 787, 788, 640, 753, 786, - 9, 811, 776, 777, 778, 834, 810, 499, 832, 499, - 831, 832, 3, 8, 11, 15, 16, 17, 18, 19, - 20, 35, 38, 43, 50, 75, 176, 192, 197, 219, - 220, 234, 272, 275, 289, 292, 381, 483, 486, 487, - 488, 490, 491, 492, 493, 494, 495, 780, 781, 782, - 784, 462, 761, 811, 298, 753, 503, 648, 499, 832, - 811, 501, 810, 648, 3, 117, 238, 557, 742, 832, - 876, 99, 117, 877, 117, 877, 833, 38, 833, 500, - 503, 862, 503, 500, 647, 825, 826, 38, 886, 529, - 824, 376, 642, 642, 29, 492, 658, 659, 753, 56, - 642, 652, 163, 269, 678, 224, 270, 330, 379, 439, - 4, 9, 29, 673, 753, 490, 491, 674, 675, 753, - 755, 690, 691, 665, 664, 662, 663, 166, 693, 282, - 695, 662, 690, 787, 840, 233, 824, 69, 77, 88, - 168, 190, 320, 434, 580, 590, 605, 833, 77, 88, - 526, 88, 526, 499, 417, 499, 578, 244, 437, 578, - 88, 503, 417, 824, 725, 557, 56, 559, 557, 557, - 108, 250, 258, 56, 417, 461, 485, 556, 263, 362, - 556, 558, 710, 88, 417, 526, 362, 824, 417, 362, - 789, 789, 790, 500, 503, 656, 657, 13, 14, 498, - 508, 417, 597, 602, 833, 461, 632, 334, 406, 453, - 619, 152, 95, 550, 563, 849, 850, 898, 828, 501, - 144, 723, 824, 272, 551, 555, 272, 499, 598, 38, - 598, 272, 499, 620, 190, 592, 833, 854, 499, 788, - 831, 617, 791, 740, 740, 37, 724, 415, 415, 831, - 831, 720, 833, 723, 720, 497, 497, 831, 831, 417, - 417, 417, 417, 614, 838, 825, 827, 827, 838, 500, - 864, 870, 4, 831, 4, 831, 631, 638, 842, 52, - 97, 123, 141, 145, 167, 170, 185, 277, 285, 328, - 635, 38, 500, 753, 500, 500, 500, 171, 500, 500, - 503, 500, 310, 795, 500, 754, 754, 11, 15, 18, - 19, 20, 197, 219, 289, 486, 487, 488, 490, 491, - 492, 493, 494, 495, 782, 754, 500, 712, 713, 758, - 166, 171, 798, 799, 503, 500, 38, 800, 787, 800, - 800, 171, 500, 38, 704, 499, 4, 9, 666, 668, - 669, 833, 826, 815, 813, 177, 238, 406, 410, 412, - 437, 649, 824, 458, 716, 702, 287, 441, 709, 702, - 222, 702, 717, 718, 834, 499, 717, 834, 503, 500, - 503, 500, 503, 527, 621, 639, 846, 885, 787, 808, - 788, 457, 803, 804, 492, 832, 8, 15, 18, 19, - 20, 486, 487, 488, 490, 491, 492, 493, 494, 495, - 780, 785, 833, 500, 787, 499, 833, 344, 822, 166, - 498, 500, 503, 503, 507, 508, 787, 753, 752, 752, - 723, 753, 753, 753, 753, 753, 753, 753, 5, 842, - 843, 415, 42, 403, 812, 838, 753, 753, 499, 640, - 801, 132, 159, 272, 277, 282, 424, 435, 753, 277, - 499, 753, 417, 50, 176, 192, 197, 234, 381, 753, - 753, 753, 753, 753, 753, 753, 753, 753, 753, 29, - 36, 386, 779, 180, 162, 762, 357, 499, 775, 816, - 171, 699, 789, 492, 699, 499, 832, 833, 824, 881, - 824, 889, 753, 503, 500, 499, 441, 888, 117, 300, - 499, 528, 639, 38, 499, 533, 542, 543, 545, 833, - 39, 126, 660, 660, 503, 441, 660, 263, 642, 357, - 358, 490, 491, 675, 677, 755, 379, 224, 288, 309, - 309, 503, 494, 4, 676, 831, 676, 357, 358, 677, - 823, 824, 276, 383, 696, 691, 663, 500, 342, 521, - 499, 190, 590, 827, 224, 272, 224, 441, 499, 583, - 722, 723, 827, 833, 190, 827, 190, 833, 25, 137, - 376, 517, 520, 574, 588, 842, 827, 582, 601, 842, - 827, 518, 827, 342, 376, 521, 555, 557, 838, 827, - 557, 838, 827, 557, 342, 376, 521, 827, 827, 827, - 827, 342, 376, 521, 827, 827, 656, 656, 656, 449, - 790, 191, 347, 655, 753, 753, 753, 809, 325, 628, - 500, 503, 285, 171, 417, 623, 453, 824, 902, 824, - 824, 833, 292, 609, 828, 499, 640, 499, 152, 152, - 234, 580, 590, 593, 596, 606, 608, 833, 461, 463, - 585, 151, 639, 461, 855, 152, 500, 789, 38, 272, - 287, 787, 500, 500, 615, 500, 497, 482, 482, 500, - 500, 500, 503, 723, 500, 831, 498, 831, 500, 500, - 745, 747, 748, 749, 748, 749, 749, 615, 615, 287, - 615, 500, 503, 492, 499, 557, 630, 869, 38, 627, - 832, 627, 272, 277, 328, 627, 627, 723, 500, 753, - 753, 753, 798, 723, 754, 754, 754, 754, 754, 132, - 272, 282, 754, 754, 754, 754, 754, 754, 754, 754, - 754, 754, 500, 503, 38, 714, 753, 753, 799, 798, - 723, 500, 500, 500, 787, 723, 826, 309, 494, 309, - 358, 494, 499, 499, 500, 648, 410, 412, 410, 412, - 824, 650, 650, 650, 753, 180, 679, 753, 499, 702, - 709, 500, 503, 723, 717, 500, 875, 723, 500, 498, - 753, 139, 804, 805, 818, 500, 500, 501, 500, 826, - 499, 753, 819, 833, 811, 753, 776, 753, 500, 500, - 482, 754, 754, 145, 787, 171, 132, 159, 277, 282, - 424, 435, 499, 145, 785, 753, 403, 812, 753, 801, - 753, 417, 499, 640, 499, 499, 155, 763, 700, 701, - 716, 656, 818, 716, 831, 752, 840, 846, 701, 458, - 887, 447, 405, 440, 537, 532, 541, 833, 287, 534, - 833, 538, 545, 503, 699, 488, 811, 484, 661, 661, - 659, 289, 780, 783, 661, 4, 831, 677, 288, 439, - 674, 503, 243, 417, 753, 272, 605, 499, 152, 499, - 583, 200, 602, 603, 564, 38, 175, 573, 599, 564, - 25, 137, 346, 348, 376, 514, 515, 516, 522, 523, - 152, 615, 152, 615, 574, 588, 574, 500, 503, 567, - 832, 500, 503, 488, 501, 417, 362, 88, 417, 526, - 362, 417, 417, 417, 362, 655, 655, 655, 790, 279, - 279, 500, 498, 393, 394, 637, 832, 597, 628, 824, - 499, 38, 598, 620, 848, 344, 406, 547, 548, 832, - 602, 824, 824, 902, 824, 500, 503, 285, 578, 285, - 287, 577, 827, 461, 901, 578, 38, 824, 500, 406, - 753, 152, 824, 500, 724, 831, 743, 743, 724, 833, - 724, 498, 498, 838, 631, 625, 636, 869, 832, 832, - 277, 602, 492, 602, 832, 832, 500, 500, 799, 171, - 132, 282, 499, 715, 712, 499, 500, 500, 500, 833, - 666, 716, 650, 650, 650, 650, 824, 824, 824, 56, - 184, 688, 826, 718, 75, 719, 500, 414, 753, 143, - 822, 785, 500, 753, 819, 820, 821, 38, 197, 500, - 752, 753, 35, 35, 753, 500, 753, 171, 499, 791, - 753, 500, 145, 754, 754, 145, 145, 753, 753, 657, - 458, 753, 297, 767, 503, 679, 655, 822, 679, 500, - 500, 753, 350, 536, 446, 500, 503, 811, 86, 536, - 500, 503, 533, 887, 753, 163, 228, 499, 661, 288, - 824, 827, 500, 152, 603, 590, 603, 564, 592, 503, - 500, 119, 204, 270, 272, 589, 499, 32, 56, 610, - 599, 69, 75, 88, 117, 119, 204, 272, 277, 320, - 336, 434, 441, 569, 570, 584, 175, 117, 189, 272, - 578, 556, 109, 117, 175, 272, 392, 395, 558, 578, - 376, 516, 428, 827, 833, 520, 601, 3, 46, 52, - 76, 78, 84, 96, 100, 101, 102, 103, 106, 170, - 172, 175, 176, 192, 206, 219, 220, 222, 232, 234, - 246, 266, 271, 275, 289, 296, 298, 353, 375, 377, - 381, 399, 408, 427, 433, 440, 451, 490, 491, 557, - 565, 604, 723, 783, 832, 835, 903, 909, 842, 827, - 827, 827, 827, 827, 827, 827, 827, 827, 827, 500, - 500, 500, 656, 556, 637, 499, 596, 639, 855, 38, - 609, 190, 824, 500, 503, 500, 551, 499, 38, 587, - 585, 593, 81, 553, 109, 270, 639, 620, 639, 592, - 441, 852, 498, 723, 615, 500, 503, 602, 754, 171, - 499, 791, 717, 500, 503, 500, 679, 824, 824, 824, - 824, 29, 98, 181, 356, 492, 499, 680, 681, 682, - 683, 684, 685, 686, 753, 753, 460, 764, 500, 838, - 753, 500, 503, 500, 833, 753, 755, 753, 753, 753, - 791, 500, 753, 35, 35, 753, 753, 145, 500, 500, - 753, 500, 499, 768, 833, 688, 500, 688, 832, 814, - 639, 300, 639, 532, 287, 499, 530, 488, 545, 536, - 785, 564, 590, 500, 500, 461, 595, 120, 193, 202, - 119, 443, 753, 117, 38, 499, 838, 827, 754, 120, - 193, 119, 277, 224, 824, 595, 83, 610, 190, 277, - 557, 753, 610, 277, 490, 491, 560, 833, 723, 615, - 615, 246, 399, 835, 839, 488, 417, 417, 655, 629, - 441, 624, 626, 602, 500, 901, 38, 406, 753, 406, - 272, 499, 832, 855, 596, 151, 639, 149, 198, 577, - 122, 137, 319, 901, 109, 461, 899, 38, 287, 833, - 851, 499, 636, 754, 791, 500, 500, 9, 343, 672, - 688, 499, 378, 499, 500, 503, 765, 766, 833, 327, - 689, 819, 498, 190, 500, 753, 753, 753, 500, 769, - 833, 764, 832, 764, 503, 537, 88, 499, 535, 544, - 758, 833, 133, 753, 500, 336, 595, 499, 586, 564, - 500, 189, 499, 753, 272, 570, 595, 598, 827, 38, - 152, 719, 839, 494, 565, 827, 827, 500, 556, 124, - 500, 585, 639, 639, 824, 152, 38, 500, 827, 901, - 29, 80, 89, 118, 189, 201, 392, 395, 581, 581, - 358, 358, 61, 69, 238, 406, 753, 824, 544, 500, - 500, 499, 764, 787, 499, 787, 682, 503, 38, 753, - 441, 667, 753, 306, 770, 689, 689, 446, 827, 753, - 500, 503, 75, 539, 539, 273, 439, 824, 564, 591, - 594, 842, 396, 455, 571, 572, 499, 566, 753, 500, - 248, 607, 189, 441, 519, 494, 428, 629, 832, 855, - 577, 899, 499, 824, 639, 585, 553, 69, 290, 69, - 639, 852, 500, 9, 689, 500, 681, 500, 766, 768, - 360, 498, 56, 656, 667, 667, 639, 500, 716, 535, - 838, 540, 838, 540, 376, 598, 500, 503, 488, 555, - 500, 270, 579, 172, 305, 382, 287, 575, 576, 600, - 566, 753, 428, 38, 499, 899, 577, 901, 290, 290, - 499, 855, 500, 667, 500, 669, 786, 329, 358, 771, - 539, 660, 660, 543, 607, 594, 565, 500, 572, 202, - 122, 439, 287, 600, 287, 575, 639, 544, 716, 50, - 99, 430, 753, 772, 773, 772, 500, 540, 661, 661, - 716, 576, 60, 270, 349, 376, 568, 568, 899, 500, - 773, 357, 165, 315, 165, 315, 660, 564, 24, 117, - 277, 855, 35, 661, 716, 773 + 261, 367, 368, 481, 482, 501, 751, 752, 753, 754, + 755, 756, 757, 758, 759, 735, 152, 622, 152, 505, + 622, 152, 287, 795, 345, 502, 505, 4, 159, 287, + 425, 492, 493, 563, 566, 839, 840, 873, 875, 876, + 879, 874, 501, 636, 640, 418, 760, 795, 501, 839, + 839, 3, 751, 752, 753, 754, 755, 756, 757, 758, + 800, 801, 840, 712, 713, 839, 839, 760, 832, 760, + 802, 492, 493, 761, 762, 783, 790, 804, 501, 760, + 794, 805, 760, 55, 171, 230, 419, 760, 795, 808, + 760, 502, 842, 409, 677, 678, 501, 678, 660, 661, + 709, 217, 655, 222, 296, 715, 709, 715, 222, 714, + 222, 715, 222, 678, 501, 842, 678, 501, 294, 563, + 879, 885, 887, 797, 730, 799, 38, 233, 841, 501, + 499, 647, 760, 814, 501, 647, 760, 501, 501, 760, + 760, 760, 148, 825, 826, 760, 795, 796, 647, 760, + 794, 9, 3, 852, 784, 785, 786, 842, 818, 501, + 840, 501, 839, 840, 3, 8, 11, 15, 16, 17, + 18, 19, 20, 35, 38, 43, 50, 75, 176, 192, + 197, 219, 220, 234, 272, 275, 289, 292, 382, 485, + 488, 489, 490, 492, 493, 494, 495, 496, 497, 788, + 789, 790, 792, 819, 464, 769, 298, 760, 505, 655, + 501, 840, 819, 503, 818, 655, 3, 117, 238, 563, + 749, 840, 886, 99, 117, 887, 117, 887, 841, 38, + 841, 502, 505, 872, 505, 502, 654, 833, 834, 38, + 896, 191, 345, 217, 377, 649, 649, 29, 494, 665, + 666, 760, 56, 649, 659, 163, 269, 685, 224, 270, + 331, 380, 440, 4, 9, 29, 680, 760, 492, 493, + 681, 682, 760, 762, 697, 698, 672, 671, 669, 670, + 166, 700, 282, 702, 669, 697, 795, 848, 233, 832, + 69, 77, 88, 168, 190, 321, 435, 587, 597, 612, + 841, 77, 88, 529, 88, 529, 501, 418, 501, 585, + 244, 438, 585, 88, 505, 418, 832, 732, 563, 56, + 565, 563, 563, 108, 250, 258, 56, 418, 463, 487, + 562, 263, 363, 562, 564, 717, 88, 418, 529, 363, + 832, 418, 363, 841, 636, 797, 797, 798, 502, 505, + 663, 664, 13, 14, 500, 511, 418, 604, 609, 841, + 463, 639, 152, 840, 832, 335, 407, 455, 626, 152, + 95, 556, 570, 858, 859, 914, 144, 730, 832, 272, + 557, 561, 272, 501, 605, 38, 272, 605, 272, 501, + 627, 190, 599, 841, 863, 621, 846, 836, 503, 501, + 796, 839, 624, 799, 747, 747, 37, 731, 416, 416, + 839, 839, 727, 841, 730, 727, 499, 499, 839, 839, + 418, 418, 418, 418, 621, 833, 835, 835, 846, 502, + 874, 880, 4, 839, 4, 839, 638, 645, 850, 52, + 97, 123, 141, 145, 167, 170, 185, 277, 285, 306, + 329, 642, 840, 38, 502, 760, 502, 502, 502, 171, + 502, 502, 505, 502, 310, 803, 502, 761, 761, 11, + 15, 18, 19, 20, 197, 219, 289, 488, 489, 490, + 492, 493, 494, 495, 496, 497, 790, 761, 502, 719, + 720, 766, 166, 171, 806, 807, 505, 502, 38, 808, + 795, 808, 808, 171, 502, 38, 711, 501, 4, 9, + 673, 675, 676, 841, 834, 823, 821, 177, 238, 407, + 411, 413, 438, 656, 832, 460, 723, 709, 287, 443, + 716, 709, 222, 709, 709, 724, 725, 842, 501, 724, + 842, 505, 502, 505, 502, 505, 530, 628, 646, 855, + 895, 795, 796, 459, 811, 812, 494, 840, 8, 15, + 18, 19, 20, 488, 489, 490, 492, 493, 494, 495, + 496, 497, 788, 793, 841, 502, 795, 501, 841, 345, + 830, 166, 500, 502, 505, 505, 510, 511, 795, 760, + 759, 759, 730, 760, 760, 760, 760, 760, 760, 760, + 5, 850, 851, 416, 42, 404, 820, 846, 760, 760, + 501, 647, 809, 132, 159, 272, 277, 282, 425, 436, + 760, 277, 501, 760, 418, 50, 176, 192, 197, 234, + 382, 760, 760, 760, 760, 760, 760, 760, 760, 760, + 760, 29, 36, 387, 787, 816, 180, 162, 770, 358, + 501, 783, 824, 171, 706, 797, 494, 706, 501, 840, + 841, 832, 891, 832, 899, 760, 505, 502, 501, 443, + 898, 532, 832, 501, 536, 546, 547, 549, 841, 39, + 126, 667, 667, 505, 443, 667, 263, 649, 358, 359, + 492, 493, 682, 684, 762, 380, 224, 288, 309, 309, + 505, 496, 4, 683, 839, 683, 358, 359, 684, 831, + 832, 276, 384, 703, 698, 670, 502, 343, 524, 501, + 190, 597, 835, 224, 272, 224, 443, 501, 590, 729, + 730, 835, 841, 190, 835, 190, 841, 25, 137, 377, + 520, 523, 581, 595, 850, 835, 589, 608, 850, 835, + 521, 835, 343, 377, 524, 561, 563, 846, 835, 563, + 846, 835, 563, 343, 377, 524, 835, 835, 835, 835, + 343, 377, 524, 835, 835, 663, 663, 663, 451, 798, + 191, 348, 662, 760, 760, 760, 817, 326, 635, 502, + 505, 285, 171, 418, 630, 832, 171, 455, 832, 918, + 832, 832, 832, 292, 616, 501, 647, 501, 152, 152, + 234, 587, 597, 600, 603, 613, 615, 841, 463, 465, + 592, 151, 646, 152, 463, 864, 152, 502, 797, 38, + 272, 287, 836, 795, 502, 502, 622, 502, 499, 484, + 484, 502, 502, 502, 505, 730, 502, 839, 500, 839, + 502, 502, 752, 754, 755, 756, 755, 756, 756, 622, + 622, 287, 622, 502, 505, 494, 501, 563, 637, 879, + 38, 634, 840, 634, 272, 277, 329, 634, 56, 634, + 636, 730, 502, 760, 760, 760, 806, 730, 761, 761, + 761, 761, 761, 132, 272, 282, 761, 761, 761, 761, + 761, 761, 761, 761, 761, 761, 502, 505, 38, 721, + 760, 760, 807, 806, 730, 502, 502, 502, 795, 730, + 834, 309, 496, 309, 359, 496, 501, 501, 502, 655, + 411, 413, 411, 413, 832, 657, 657, 657, 760, 180, + 686, 760, 501, 709, 716, 502, 505, 730, 724, 502, + 885, 730, 502, 500, 760, 139, 812, 813, 826, 502, + 502, 503, 502, 834, 501, 760, 827, 841, 760, 784, + 760, 502, 502, 484, 761, 761, 145, 795, 171, 132, + 159, 277, 282, 425, 436, 501, 145, 793, 760, 404, + 820, 760, 809, 760, 418, 501, 647, 501, 501, 155, + 771, 707, 708, 723, 663, 826, 723, 839, 759, 848, + 855, 708, 460, 897, 117, 300, 501, 531, 646, 38, + 542, 549, 505, 706, 490, 819, 486, 668, 668, 666, + 289, 788, 791, 668, 4, 839, 684, 288, 440, 681, + 505, 243, 418, 760, 272, 612, 501, 152, 501, 590, + 200, 609, 610, 571, 38, 175, 580, 606, 571, 25, + 137, 347, 349, 377, 517, 518, 519, 525, 526, 152, + 622, 152, 622, 581, 595, 581, 502, 505, 574, 840, + 502, 505, 490, 503, 418, 363, 88, 418, 529, 363, + 418, 418, 418, 363, 662, 662, 662, 798, 279, 279, + 502, 500, 394, 395, 644, 840, 604, 635, 171, 840, + 832, 501, 38, 605, 627, 857, 345, 407, 551, 552, + 840, 609, 832, 832, 918, 832, 502, 505, 285, 585, + 285, 287, 584, 835, 463, 917, 832, 585, 38, 832, + 502, 407, 760, 152, 832, 502, 731, 839, 750, 750, + 731, 841, 731, 500, 500, 846, 638, 632, 643, 879, + 840, 840, 277, 609, 494, 609, 840, 494, 609, 840, + 502, 502, 807, 171, 132, 282, 501, 722, 719, 501, + 502, 502, 502, 841, 673, 723, 657, 657, 657, 657, + 832, 832, 832, 56, 184, 695, 834, 725, 75, 726, + 502, 415, 760, 143, 830, 793, 502, 760, 827, 828, + 829, 38, 197, 502, 759, 760, 35, 35, 760, 502, + 760, 171, 501, 799, 760, 502, 145, 761, 761, 145, + 145, 760, 760, 664, 460, 760, 297, 775, 505, 686, + 662, 830, 686, 502, 502, 760, 351, 540, 449, 406, + 442, 541, 535, 545, 841, 287, 538, 841, 502, 505, + 536, 897, 760, 163, 228, 501, 668, 288, 832, 835, + 502, 152, 610, 597, 610, 571, 599, 505, 502, 119, + 204, 270, 272, 596, 501, 32, 56, 617, 606, 69, + 75, 88, 117, 119, 204, 272, 277, 321, 337, 435, + 443, 576, 577, 591, 175, 117, 189, 272, 585, 562, + 109, 117, 175, 272, 393, 396, 564, 585, 377, 519, + 429, 835, 841, 523, 608, 3, 46, 52, 76, 78, + 84, 96, 100, 101, 102, 103, 106, 170, 172, 175, + 176, 192, 206, 219, 220, 222, 232, 234, 246, 266, + 271, 275, 289, 296, 298, 314, 354, 376, 378, 382, + 400, 409, 428, 434, 442, 453, 492, 493, 563, 572, + 611, 730, 791, 840, 843, 919, 925, 850, 835, 835, + 835, 835, 835, 835, 835, 835, 835, 835, 502, 502, + 502, 663, 562, 644, 840, 501, 603, 646, 864, 38, + 616, 190, 832, 502, 505, 502, 557, 501, 38, 594, + 592, 600, 81, 559, 109, 270, 605, 646, 627, 646, + 599, 443, 861, 500, 730, 622, 502, 505, 609, 761, + 171, 501, 799, 724, 502, 505, 502, 686, 832, 832, + 832, 832, 29, 98, 181, 357, 494, 501, 687, 688, + 689, 690, 691, 692, 693, 760, 760, 462, 772, 502, + 846, 760, 502, 505, 502, 841, 760, 762, 760, 760, + 760, 799, 502, 760, 35, 35, 760, 760, 145, 502, + 502, 760, 502, 501, 776, 841, 695, 502, 695, 840, + 822, 448, 502, 505, 819, 86, 540, 490, 549, 540, + 793, 571, 597, 502, 502, 463, 602, 120, 193, 202, + 119, 445, 760, 117, 38, 501, 846, 835, 761, 120, + 193, 119, 277, 224, 832, 602, 83, 617, 190, 277, + 563, 760, 617, 277, 492, 493, 566, 841, 730, 622, + 622, 246, 400, 843, 847, 490, 418, 418, 662, 636, + 443, 631, 633, 609, 502, 917, 38, 407, 760, 407, + 272, 501, 840, 864, 603, 151, 646, 149, 198, 584, + 122, 137, 320, 917, 109, 864, 463, 915, 38, 287, + 841, 860, 501, 643, 761, 799, 502, 502, 9, 344, + 679, 695, 501, 379, 501, 502, 505, 773, 774, 841, + 328, 696, 827, 500, 190, 502, 760, 760, 760, 502, + 777, 841, 772, 840, 772, 505, 646, 300, 646, 535, + 287, 501, 533, 760, 502, 337, 602, 501, 593, 571, + 502, 189, 501, 760, 272, 577, 602, 605, 835, 38, + 152, 726, 847, 496, 572, 835, 835, 502, 562, 124, + 502, 592, 646, 646, 832, 152, 38, 502, 835, 917, + 29, 80, 89, 118, 189, 201, 393, 396, 588, 588, + 359, 359, 38, 61, 69, 238, 407, 760, 832, 501, + 539, 548, 766, 841, 502, 502, 501, 772, 795, 501, + 795, 689, 505, 38, 760, 443, 674, 760, 306, 778, + 696, 696, 541, 88, 548, 133, 832, 571, 598, 601, + 850, 397, 457, 578, 579, 501, 573, 760, 502, 248, + 614, 189, 443, 522, 496, 429, 636, 840, 864, 584, + 915, 501, 832, 646, 592, 559, 646, 69, 290, 69, + 646, 861, 760, 502, 505, 75, 543, 543, 9, 696, + 502, 688, 502, 774, 776, 361, 500, 56, 663, 674, + 674, 448, 835, 502, 273, 440, 605, 502, 505, 490, + 561, 502, 270, 586, 172, 305, 383, 287, 582, 583, + 607, 573, 760, 429, 38, 501, 915, 584, 917, 915, + 290, 290, 501, 502, 864, 539, 846, 544, 846, 544, + 502, 674, 502, 676, 794, 330, 359, 779, 646, 723, + 377, 614, 601, 572, 502, 579, 202, 122, 440, 287, + 607, 287, 582, 646, 548, 543, 723, 667, 667, 50, + 99, 431, 760, 780, 781, 780, 502, 547, 583, 60, + 270, 350, 377, 575, 575, 915, 502, 544, 668, 668, + 781, 358, 165, 316, 165, 316, 723, 571, 24, 117, + 277, 864, 667, 35, 723, 668, 781 }; #define yyerrok (yyerrstatus = 0) @@ -310545,7 +324863,7 @@ YYLTYPE yylloc; yystate = 0; yyerrstatus = 0; - yynerrs = 0; + yynerrs = 0; (void)yynerrs; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. @@ -310745,14 +325063,14 @@ YYLTYPE yylloc; switch (yyn) { case 2: -#line 471 "third_party/libpg_query/grammar/grammar.y" +#line 484 "third_party/libpg_query/grammar/grammar.y" { pg_yyget_extra(yyscanner)->parsetree = (yyvsp[(1) - (1)].list); ;} break; case 3: -#line 487 "third_party/libpg_query/grammar/grammar.y" +#line 500 "third_party/libpg_query/grammar/grammar.y" { if ((yyvsp[(1) - (3)].list) != NIL) { @@ -310767,7 +325085,7 @@ YYLTYPE yylloc; break; case 4: -#line 499 "third_party/libpg_query/grammar/grammar.y" +#line 512 "third_party/libpg_query/grammar/grammar.y" { if ((yyvsp[(1) - (1)].node) != NULL) (yyval.list) = list_make1(makeRawStmt((yyvsp[(1) - (1)].node), 0)); @@ -310776,12 +325094,12 @@ YYLTYPE yylloc; ;} break; - case 39: -#line 542 "third_party/libpg_query/grammar/grammar.y" + case 43: +#line 559 "third_party/libpg_query/grammar/grammar.y" { (yyval.node) = NULL; ;} break; - case 40: + case 44: #line 10 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableStmt *n = makeNode(PGAlterTableStmt); @@ -310793,7 +325111,7 @@ YYLTYPE yylloc; ;} break; - case 41: + case 45: #line 19 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableStmt *n = makeNode(PGAlterTableStmt); @@ -310805,7 +325123,7 @@ YYLTYPE yylloc; ;} break; - case 42: + case 46: #line 28 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableStmt *n = makeNode(PGAlterTableStmt); @@ -310817,7 +325135,7 @@ YYLTYPE yylloc; ;} break; - case 43: + case 47: #line 37 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableStmt *n = makeNode(PGAlterTableStmt); @@ -310829,7 +325147,7 @@ YYLTYPE yylloc; ;} break; - case 44: + case 48: #line 46 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableStmt *n = makeNode(PGAlterTableStmt); @@ -310841,7 +325159,7 @@ YYLTYPE yylloc; ;} break; - case 45: + case 49: #line 55 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableStmt *n = makeNode(PGAlterTableStmt); @@ -310853,7 +325171,7 @@ YYLTYPE yylloc; ;} break; - case 46: + case 50: #line 64 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableStmt *n = makeNode(PGAlterTableStmt); @@ -310865,7 +325183,7 @@ YYLTYPE yylloc; ;} break; - case 47: + case 51: #line 73 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableStmt *n = makeNode(PGAlterTableStmt); @@ -310877,41 +325195,41 @@ YYLTYPE yylloc; ;} break; - case 48: + case 52: #line 86 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); ;} break; - case 49: + case 53: #line 88 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].defelt)); ;} break; - case 50: + case 54: #line 93 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.node) = (yyvsp[(3) - (3)].node); ;} break; - case 51: + case 55: #line 94 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.node) = NULL; ;} break; - case 52: + case 56: #line 100 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.defelt) = makeDefElem("restart", NULL, (yylsp[(1) - (1)])); ;} break; - case 53: + case 57: #line 104 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.defelt) = makeDefElem("restart", (PGNode *)(yyvsp[(3) - (3)].value), (yylsp[(1) - (3)])); ;} break; - case 54: + case 58: #line 108 "third_party/libpg_query/grammar/statements/alter_table.y" { if (strcmp((yyvsp[(2) - (2)].defelt)->defname, "as") == 0 || @@ -310925,28 +325243,28 @@ YYLTYPE yylloc; ;} break; - case 55: + case 59: #line 119 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.defelt) = makeDefElem("generated", (PGNode *) makeInteger((yyvsp[(3) - (3)].ival)), (yylsp[(1) - (3)])); ;} break; - case 56: + case 60: #line 127 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); ;} break; - case 57: + case 61: #line 131 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt)); ;} break; - case 58: + case 62: #line 140 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -310957,7 +325275,7 @@ YYLTYPE yylloc; ;} break; - case 59: + case 63: #line 149 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -310968,7 +325286,7 @@ YYLTYPE yylloc; ;} break; - case 60: + case 64: #line 158 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -310979,7 +325297,7 @@ YYLTYPE yylloc; ;} break; - case 61: + case 65: #line 167 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -310990,7 +325308,7 @@ YYLTYPE yylloc; ;} break; - case 62: + case 66: #line 176 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311001,7 +325319,7 @@ YYLTYPE yylloc; ;} break; - case 63: + case 67: #line 185 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311011,7 +325329,7 @@ YYLTYPE yylloc; ;} break; - case 64: + case 68: #line 193 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311021,7 +325339,7 @@ YYLTYPE yylloc; ;} break; - case 65: + case 69: #line 201 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311032,7 +325350,7 @@ YYLTYPE yylloc; ;} break; - case 66: + case 70: #line 210 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311043,7 +325361,7 @@ YYLTYPE yylloc; ;} break; - case 67: + case 71: #line 219 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311054,7 +325372,7 @@ YYLTYPE yylloc; ;} break; - case 68: + case 72: #line 228 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311065,7 +325383,7 @@ YYLTYPE yylloc; ;} break; - case 69: + case 73: #line 237 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311084,7 +325402,7 @@ YYLTYPE yylloc; ;} break; - case 70: + case 74: #line 254 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311095,7 +325413,7 @@ YYLTYPE yylloc; ;} break; - case 71: + case 75: #line 263 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311106,7 +325424,7 @@ YYLTYPE yylloc; ;} break; - case 72: + case 76: #line 272 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311117,7 +325435,7 @@ YYLTYPE yylloc; ;} break; - case 73: + case 77: #line 281 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311129,7 +325447,7 @@ YYLTYPE yylloc; ;} break; - case 74: + case 78: #line 291 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311141,7 +325459,7 @@ YYLTYPE yylloc; ;} break; - case 75: + case 79: #line 304 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311158,7 +325476,7 @@ YYLTYPE yylloc; ;} break; - case 76: + case 80: #line 319 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311169,7 +325487,7 @@ YYLTYPE yylloc; ;} break; - case 77: + case 81: #line 328 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311179,7 +325497,7 @@ YYLTYPE yylloc; ;} break; - case 78: + case 82: #line 336 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311196,7 +325514,7 @@ YYLTYPE yylloc; ;} break; - case 79: + case 83: #line 351 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311206,7 +325524,7 @@ YYLTYPE yylloc; ;} break; - case 80: + case 84: #line 359 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311218,7 +325536,7 @@ YYLTYPE yylloc; ;} break; - case 81: + case 85: #line 369 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311230,7 +325548,7 @@ YYLTYPE yylloc; ;} break; - case 82: + case 86: #line 379 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311239,7 +325557,7 @@ YYLTYPE yylloc; ;} break; - case 83: + case 87: #line 386 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311248,7 +325566,7 @@ YYLTYPE yylloc; ;} break; - case 84: + case 88: #line 393 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311258,7 +325576,7 @@ YYLTYPE yylloc; ;} break; - case 85: + case 89: #line 401 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311268,7 +325586,7 @@ YYLTYPE yylloc; ;} break; - case 86: + case 90: #line 408 "third_party/libpg_query/grammar/statements/alter_table.y" { PGAlterTableCmd *n = makeNode(PGAlterTableCmd); @@ -311278,24 +325596,24 @@ YYLTYPE yylloc; ;} break; - case 87: + case 91: #line 418 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 88: + case 92: #line 419 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.node) = NULL; ;} break; - case 89: + case 93: #line 425 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.defelt) = (yyvsp[(1) - (1)].defelt); ;} break; - case 90: + case 94: #line 429 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.defelt) = (yyvsp[(2) - (2)].defelt); @@ -311303,7 +325621,7 @@ YYLTYPE yylloc; ;} break; - case 91: + case 95: #line 434 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.defelt) = (yyvsp[(2) - (2)].defelt); @@ -311311,44 +325629,44 @@ YYLTYPE yylloc; ;} break; - case 92: + case 96: #line 439 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.defelt) = makeDefElemExtended(NULL, (yyvsp[(2) - (2)].str), NULL, DEFELEM_DROP, (yylsp[(2) - (2)])); ;} break; - case 93: + case 97: #line 446 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 94: + case 98: #line 447 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 95: + case 99: #line 452 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 96: + case 100: #line 456 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.ival) = 1; ;} break; - case 97: + case 101: #line 457 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.ival) = 0; ;} break; - case 98: + case 102: #line 458 "third_party/libpg_query/grammar/statements/alter_table.y" { (yyval.ival) = 0; ;} break; - case 99: + case 103: #line 8 "third_party/libpg_query/grammar/statements/deallocate.y" { PGDeallocateStmt *n = makeNode(PGDeallocateStmt); @@ -311357,7 +325675,7 @@ YYLTYPE yylloc; ;} break; - case 100: + case 104: #line 14 "third_party/libpg_query/grammar/statements/deallocate.y" { PGDeallocateStmt *n = makeNode(PGDeallocateStmt); @@ -311366,7 +325684,7 @@ YYLTYPE yylloc; ;} break; - case 101: + case 105: #line 20 "third_party/libpg_query/grammar/statements/deallocate.y" { PGDeallocateStmt *n = makeNode(PGDeallocateStmt); @@ -311375,7 +325693,7 @@ YYLTYPE yylloc; ;} break; - case 102: + case 106: #line 26 "third_party/libpg_query/grammar/statements/deallocate.y" { PGDeallocateStmt *n = makeNode(PGDeallocateStmt); @@ -311384,7 +325702,7 @@ YYLTYPE yylloc; ;} break; - case 103: + case 107: #line 7 "third_party/libpg_query/grammar/statements/rename.y" { PGRenameStmt *n = makeNode(PGRenameStmt); @@ -311396,7 +325714,7 @@ YYLTYPE yylloc; ;} break; - case 104: + case 108: #line 16 "third_party/libpg_query/grammar/statements/rename.y" { PGRenameStmt *n = makeNode(PGRenameStmt); @@ -311409,7 +325727,7 @@ YYLTYPE yylloc; ;} break; - case 105: + case 109: #line 26 "third_party/libpg_query/grammar/statements/rename.y" { PGRenameStmt *n = makeNode(PGRenameStmt); @@ -311422,7 +325740,7 @@ YYLTYPE yylloc; ;} break; - case 106: + case 110: #line 36 "third_party/libpg_query/grammar/statements/rename.y" { PGRenameStmt *n = makeNode(PGRenameStmt); @@ -311435,7 +325753,7 @@ YYLTYPE yylloc; ;} break; - case 107: + case 111: #line 46 "third_party/libpg_query/grammar/statements/rename.y" { PGRenameStmt *n = makeNode(PGRenameStmt); @@ -311448,7 +325766,7 @@ YYLTYPE yylloc; ;} break; - case 108: + case 112: #line 56 "third_party/libpg_query/grammar/statements/rename.y" { PGRenameStmt *n = makeNode(PGRenameStmt); @@ -311461,7 +325779,7 @@ YYLTYPE yylloc; ;} break; - case 109: + case 113: #line 66 "third_party/libpg_query/grammar/statements/rename.y" { PGRenameStmt *n = makeNode(PGRenameStmt); @@ -311474,7 +325792,7 @@ YYLTYPE yylloc; ;} break; - case 110: + case 114: #line 76 "third_party/libpg_query/grammar/statements/rename.y" { PGRenameStmt *n = makeNode(PGRenameStmt); @@ -311487,7 +325805,7 @@ YYLTYPE yylloc; ;} break; - case 111: + case 115: #line 86 "third_party/libpg_query/grammar/statements/rename.y" { PGRenameStmt *n = makeNode(PGRenameStmt); @@ -311500,7 +325818,7 @@ YYLTYPE yylloc; ;} break; - case 112: + case 116: #line 96 "third_party/libpg_query/grammar/statements/rename.y" { PGRenameStmt *n = makeNode(PGRenameStmt); @@ -311514,7 +325832,7 @@ YYLTYPE yylloc; ;} break; - case 113: + case 117: #line 107 "third_party/libpg_query/grammar/statements/rename.y" { PGRenameStmt *n = makeNode(PGRenameStmt); @@ -311528,7 +325846,7 @@ YYLTYPE yylloc; ;} break; - case 114: + case 118: #line 118 "third_party/libpg_query/grammar/statements/rename.y" { PGRenameStmt *n = makeNode(PGRenameStmt); @@ -311541,7 +325859,7 @@ YYLTYPE yylloc; ;} break; - case 115: + case 119: #line 128 "third_party/libpg_query/grammar/statements/rename.y" { PGRenameStmt *n = makeNode(PGRenameStmt); @@ -311554,29 +325872,30 @@ YYLTYPE yylloc; ;} break; - case 116: + case 120: #line 140 "third_party/libpg_query/grammar/statements/rename.y" { (yyval.ival) = COLUMN; ;} break; - case 117: + case 121: #line 141 "third_party/libpg_query/grammar/statements/rename.y" { (yyval.ival) = 0; ;} break; - case 118: -#line 10 "third_party/libpg_query/grammar/statements/insert.y" - { - (yyvsp[(5) - (7)].istmt)->relation = (yyvsp[(4) - (7)].range); - (yyvsp[(5) - (7)].istmt)->onConflictClause = (yyvsp[(6) - (7)].onconflict); - (yyvsp[(5) - (7)].istmt)->returningList = (yyvsp[(7) - (7)].list); - (yyvsp[(5) - (7)].istmt)->withClause = (yyvsp[(1) - (7)].with); - (yyval.node) = (PGNode *) (yyvsp[(5) - (7)].istmt); + case 122: +#line 11 "third_party/libpg_query/grammar/statements/insert.y" + { + (yyvsp[(6) - (8)].istmt)->relation = (yyvsp[(5) - (8)].range); + (yyvsp[(6) - (8)].istmt)->onConflictAlias = (yyvsp[(3) - (8)].onconflictshorthand); + (yyvsp[(6) - (8)].istmt)->onConflictClause = (yyvsp[(7) - (8)].onconflict); + (yyvsp[(6) - (8)].istmt)->returningList = (yyvsp[(8) - (8)].list); + (yyvsp[(6) - (8)].istmt)->withClause = (yyvsp[(1) - (8)].with); + (yyval.node) = (PGNode *) (yyvsp[(6) - (8)].istmt); ;} break; - case 119: -#line 22 "third_party/libpg_query/grammar/statements/insert.y" + case 123: +#line 24 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.istmt) = makeNode(PGInsertStmt); (yyval.istmt)->cols = NIL; @@ -311584,8 +325903,8 @@ YYLTYPE yylloc; ;} break; - case 120: -#line 28 "third_party/libpg_query/grammar/statements/insert.y" + case 124: +#line 30 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.istmt) = makeNode(PGInsertStmt); (yyval.istmt)->cols = NIL; @@ -311594,8 +325913,8 @@ YYLTYPE yylloc; ;} break; - case 121: -#line 35 "third_party/libpg_query/grammar/statements/insert.y" + case 125: +#line 37 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.istmt) = makeNode(PGInsertStmt); (yyval.istmt)->cols = (yyvsp[(2) - (4)].list); @@ -311603,8 +325922,8 @@ YYLTYPE yylloc; ;} break; - case 122: -#line 41 "third_party/libpg_query/grammar/statements/insert.y" + case 126: +#line 43 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.istmt) = makeNode(PGInsertStmt); (yyval.istmt)->cols = (yyvsp[(2) - (7)].list); @@ -311613,8 +325932,8 @@ YYLTYPE yylloc; ;} break; - case 123: -#line 48 "third_party/libpg_query/grammar/statements/insert.y" + case 127: +#line 50 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.istmt) = makeNode(PGInsertStmt); (yyval.istmt)->cols = NIL; @@ -311622,23 +325941,23 @@ YYLTYPE yylloc; ;} break; - case 124: -#line 58 "third_party/libpg_query/grammar/statements/insert.y" + case 128: +#line 60 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.range) = (yyvsp[(1) - (1)].range); ;} break; - case 125: -#line 62 "third_party/libpg_query/grammar/statements/insert.y" + case 129: +#line 64 "third_party/libpg_query/grammar/statements/insert.y" { (yyvsp[(1) - (3)].range)->alias = makeAlias((yyvsp[(3) - (3)].str), NIL); (yyval.range) = (yyvsp[(1) - (3)].range); ;} break; - case 126: -#line 71 "third_party/libpg_query/grammar/statements/insert.y" + case 130: +#line 73 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.infer) = makeNode(PGInferClause); (yyval.infer)->indexElems = (yyvsp[(2) - (4)].list); @@ -311648,8 +325967,8 @@ YYLTYPE yylloc; ;} break; - case 127: -#line 80 "third_party/libpg_query/grammar/statements/insert.y" + case 131: +#line 82 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.infer) = makeNode(PGInferClause); (yyval.infer)->indexElems = NIL; @@ -311659,25 +325978,25 @@ YYLTYPE yylloc; ;} break; - case 128: -#line 88 "third_party/libpg_query/grammar/statements/insert.y" + case 132: +#line 90 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.infer) = NULL; ;} break; - case 129: -#line 95 "third_party/libpg_query/grammar/statements/insert.y" + case 133: +#line 97 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.with) = (yyvsp[(1) - (1)].with); ;} break; - case 130: -#line 96 "third_party/libpg_query/grammar/statements/insert.y" + case 134: +#line 98 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.with) = NULL; ;} break; - case 131: -#line 102 "third_party/libpg_query/grammar/statements/insert.y" + case 135: +#line 104 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.target) = makeNode(PGResTarget); (yyval.target)->name = (yyvsp[(1) - (2)].str); @@ -311687,16 +326006,16 @@ YYLTYPE yylloc; ;} break; - case 132: -#line 114 "third_party/libpg_query/grammar/statements/insert.y" + case 136: +#line 116 "third_party/libpg_query/grammar/statements/insert.y" { (yyvsp[(1) - (3)].target)->val = (PGNode *) (yyvsp[(3) - (3)].node); (yyval.list) = list_make1((yyvsp[(1) - (3)].target)); ;} break; - case 133: -#line 119 "third_party/libpg_query/grammar/statements/insert.y" + case 137: +#line 121 "third_party/libpg_query/grammar/statements/insert.y" { int ncolumns = list_length((yyvsp[(2) - (5)].list)); int i = 1; @@ -311719,8 +326038,29 @@ YYLTYPE yylloc; ;} break; - case 134: -#line 144 "third_party/libpg_query/grammar/statements/insert.y" + case 138: +#line 146 "third_party/libpg_query/grammar/statements/insert.y" + { + (yyval.onconflictshorthand) = PG_ONCONFLICT_ALIAS_REPLACE; + ;} + break; + + case 139: +#line 151 "third_party/libpg_query/grammar/statements/insert.y" + { + (yyval.onconflictshorthand) = PG_ONCONFLICT_ALIAS_IGNORE; + ;} + break; + + case 140: +#line 155 "third_party/libpg_query/grammar/statements/insert.y" + { + (yyval.onconflictshorthand) = PG_ONCONFLICT_ALIAS_NONE; + ;} + break; + + case 141: +#line 162 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.onconflict) = makeNode(PGOnConflictClause); (yyval.onconflict)->action = PG_ONCONFLICT_UPDATE; @@ -311731,8 +326071,8 @@ YYLTYPE yylloc; ;} break; - case 135: -#line 154 "third_party/libpg_query/grammar/statements/insert.y" + case 142: +#line 172 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.onconflict) = makeNode(PGOnConflictClause); (yyval.onconflict)->action = PG_ONCONFLICT_NOTHING; @@ -311743,15 +326083,15 @@ YYLTYPE yylloc; ;} break; - case 136: -#line 163 "third_party/libpg_query/grammar/statements/insert.y" + case 143: +#line 181 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.onconflict) = NULL; ;} break; - case 137: -#line 170 "third_party/libpg_query/grammar/statements/insert.y" + case 144: +#line 188 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.ielem) = makeNode(PGIndexElem); (yyval.ielem)->name = (yyvsp[(1) - (5)].str); @@ -311764,8 +326104,8 @@ YYLTYPE yylloc; ;} break; - case 138: -#line 181 "third_party/libpg_query/grammar/statements/insert.y" + case 145: +#line 199 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.ielem) = makeNode(PGIndexElem); (yyval.ielem)->name = NULL; @@ -311778,8 +326118,8 @@ YYLTYPE yylloc; ;} break; - case 139: -#line 192 "third_party/libpg_query/grammar/statements/insert.y" + case 146: +#line 210 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.ielem) = makeNode(PGIndexElem); (yyval.ielem)->name = NULL; @@ -311792,98 +326132,98 @@ YYLTYPE yylloc; ;} break; - case 140: -#line 206 "third_party/libpg_query/grammar/statements/insert.y" + case 147: +#line 224 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.list) = (yyvsp[(2) - (2)].list); ;} break; - case 141: -#line 207 "third_party/libpg_query/grammar/statements/insert.y" + case 148: +#line 225 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.list) = NIL; ;} break; - case 142: -#line 213 "third_party/libpg_query/grammar/statements/insert.y" + case 149: +#line 231 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.override) = PG_OVERRIDING_USER_VALUE; ;} break; - case 143: -#line 214 "third_party/libpg_query/grammar/statements/insert.y" + case 150: +#line 232 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.override) = OVERRIDING_SYSTEM_VALUE; ;} break; - case 144: -#line 219 "third_party/libpg_query/grammar/statements/insert.y" + case 151: +#line 237 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].target)); ;} break; - case 145: -#line 220 "third_party/libpg_query/grammar/statements/insert.y" + case 152: +#line 238 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list),(yyvsp[(3) - (3)].target)); ;} break; - case 146: -#line 226 "third_party/libpg_query/grammar/statements/insert.y" + case 153: +#line 244 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.list) = (yyvsp[(2) - (2)].list); ;} break; - case 147: -#line 227 "third_party/libpg_query/grammar/statements/insert.y" + case 154: +#line 245 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.list) = NIL; ;} break; - case 148: -#line 231 "third_party/libpg_query/grammar/statements/insert.y" + case 155: +#line 249 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 149: -#line 232 "third_party/libpg_query/grammar/statements/insert.y" + case 156: +#line 250 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.list) = NIL; ;} break; - case 150: -#line 238 "third_party/libpg_query/grammar/statements/insert.y" + case 157: +#line 256 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].target)); ;} break; - case 151: -#line 240 "third_party/libpg_query/grammar/statements/insert.y" + case 158: +#line 258 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].target)); ;} break; - case 152: -#line 245 "third_party/libpg_query/grammar/statements/insert.y" + case 159: +#line 263 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 153: -#line 246 "third_party/libpg_query/grammar/statements/insert.y" + case 160: +#line 264 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.list) = list_concat((yyvsp[(1) - (3)].list),(yyvsp[(3) - (3)].list)); ;} break; - case 154: -#line 250 "third_party/libpg_query/grammar/statements/insert.y" + case 161: +#line 268 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 155: -#line 251 "third_party/libpg_query/grammar/statements/insert.y" + case 162: +#line 269 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; - case 156: -#line 254 "third_party/libpg_query/grammar/statements/insert.y" + case 163: +#line 272 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].ielem)); ;} break; - case 157: -#line 255 "third_party/libpg_query/grammar/statements/insert.y" + case 164: +#line 273 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].ielem)); ;} break; - case 158: -#line 261 "third_party/libpg_query/grammar/statements/insert.y" + case 165: +#line 279 "third_party/libpg_query/grammar/statements/insert.y" { (yyval.target) = makeNode(PGResTarget); (yyval.target)->name = (yyvsp[(1) - (2)].str); @@ -311893,11 +326233,11 @@ YYLTYPE yylloc; ;} break; - case 159: + case 166: #line 8 "third_party/libpg_query/grammar/statements/create_type.y" { PGCreateTypeStmt *n = makeNode(PGCreateTypeStmt); - n->typeName = (yyvsp[(3) - (6)].list); + n->typeName = (yyvsp[(3) - (6)].range); n->kind = PG_NEWTYPE_ENUM; n->query = (yyvsp[(6) - (6)].node); n->vals = NULL; @@ -311905,11 +326245,11 @@ YYLTYPE yylloc; ;} break; - case 160: + case 167: #line 17 "third_party/libpg_query/grammar/statements/create_type.y" { PGCreateTypeStmt *n = makeNode(PGCreateTypeStmt); - n->typeName = (yyvsp[(3) - (8)].list); + n->typeName = (yyvsp[(3) - (8)].range); n->kind = PG_NEWTYPE_ENUM; n->vals = (yyvsp[(7) - (8)].list); n->query = NULL; @@ -311917,11 +326257,11 @@ YYLTYPE yylloc; ;} break; - case 161: + case 168: #line 26 "third_party/libpg_query/grammar/statements/create_type.y" { PGCreateTypeStmt *n = makeNode(PGCreateTypeStmt); - n->typeName = (yyvsp[(3) - (5)].list); + n->typeName = (yyvsp[(3) - (5)].range); n->query = NULL; auto name = std::string(reinterpret_cast((yyvsp[(5) - (5)].typnam)->names->tail->data.ptr_value)->val.str); if (name == "enum") { @@ -311935,31 +326275,31 @@ YYLTYPE yylloc; ;} break; - case 162: + case 169: #line 46 "third_party/libpg_query/grammar/statements/create_type.y" { (yyval.list) = (yyvsp[(1) - (1)].list);;} break; - case 163: + case 170: #line 47 "third_party/libpg_query/grammar/statements/create_type.y" {(yyval.list) = NIL;;} break; - case 164: + case 171: #line 51 "third_party/libpg_query/grammar/statements/create_type.y" { (yyval.list) = list_make1(makeStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)]))); ;} break; - case 165: + case 172: #line 55 "third_party/libpg_query/grammar/statements/create_type.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), makeStringConst((yyvsp[(3) - (3)].str), (yylsp[(3) - (3)]))); ;} break; - case 166: + case 173: #line 8 "third_party/libpg_query/grammar/statements/pragma.y" { PGPragmaStmt *n = makeNode(PGPragmaStmt); @@ -311969,7 +326309,7 @@ YYLTYPE yylloc; ;} break; - case 167: + case 174: #line 15 "third_party/libpg_query/grammar/statements/pragma.y" { PGPragmaStmt *n = makeNode(PGPragmaStmt); @@ -311980,7 +326320,7 @@ YYLTYPE yylloc; ;} break; - case 168: + case 175: #line 23 "third_party/libpg_query/grammar/statements/pragma.y" { PGPragmaStmt *n = makeNode(PGPragmaStmt); @@ -311991,7 +326331,79 @@ YYLTYPE yylloc; ;} break; - case 169: + case 176: +#line 10 "third_party/libpg_query/grammar/statements/create_database.y" + { + PGCreateDatabaseStmt *n = makeNode(PGCreateDatabaseStmt); + n->name = (yyvsp[(3) - (3)].range); + (yyval.node) = (PGNode *)n; + ;} + break; + + case 177: +#line 16 "third_party/libpg_query/grammar/statements/create_database.y" + { + PGCreateDatabaseStmt *n = makeNode(PGCreateDatabaseStmt); + n->extension = (yyvsp[(2) - (4)].str); + n->name = (yyvsp[(4) - (4)].range); + (yyval.node) = (PGNode *)n; + ;} + break; + + case 178: +#line 23 "third_party/libpg_query/grammar/statements/create_database.y" + { + PGCreateDatabaseStmt *n = makeNode(PGCreateDatabaseStmt); + n->name = (yyvsp[(6) - (6)].range); + (yyval.node) = (PGNode *)n; + ;} + break; + + case 179: +#line 29 "third_party/libpg_query/grammar/statements/create_database.y" + { + PGCreateDatabaseStmt *n = makeNode(PGCreateDatabaseStmt); + n->name = (yyvsp[(5) - (5)].range); + (yyval.node) = (PGNode *)n; + ;} + break; + + case 180: +#line 35 "third_party/libpg_query/grammar/statements/create_database.y" + { + PGCreateDatabaseStmt *n = makeNode(PGCreateDatabaseStmt); + n->name = (yyvsp[(3) - (5)].range); + n->path = (yyvsp[(5) - (5)].str); + (yyval.node) = (PGNode *)n; + ;} + break; + + case 181: +#line 42 "third_party/libpg_query/grammar/statements/create_database.y" + { + PGCreateDatabaseStmt *n = makeNode(PGCreateDatabaseStmt); + n->name = (yyvsp[(6) - (8)].range); + n->path = (yyvsp[(8) - (8)].str); + (yyval.node) = (PGNode *)n; + ;} + break; + + case 182: +#line 49 "third_party/libpg_query/grammar/statements/create_database.y" + { + PGCreateDatabaseStmt *n = makeNode(PGCreateDatabaseStmt); + n->name = (yyvsp[(5) - (7)].range); + n->path = (yyvsp[(7) - (7)].str); + (yyval.node) = (PGNode *)n; + ;} + break; + + case 183: +#line 59 "third_party/libpg_query/grammar/statements/create_database.y" + { (yyval.str) = (yyvsp[(1) - (1)].str); ;} + break; + + case 184: #line 10 "third_party/libpg_query/grammar/statements/create_sequence.y" { PGCreateSeqStmt *n = makeNode(PGCreateSeqStmt); @@ -312004,7 +326416,7 @@ YYLTYPE yylloc; ;} break; - case 170: + case 185: #line 20 "third_party/libpg_query/grammar/statements/create_sequence.y" { PGCreateSeqStmt *n = makeNode(PGCreateSeqStmt); @@ -312017,17 +326429,17 @@ YYLTYPE yylloc; ;} break; - case 171: + case 186: #line 32 "third_party/libpg_query/grammar/statements/create_sequence.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 172: + case 187: #line 33 "third_party/libpg_query/grammar/statements/create_sequence.y" { (yyval.list) = NIL; ;} break; - case 173: + case 188: #line 8 "third_party/libpg_query/grammar/statements/execute.y" { PGExecuteStmt *n = makeNode(PGExecuteStmt); @@ -312037,7 +326449,7 @@ YYLTYPE yylloc; ;} break; - case 174: + case 189: #line 16 "third_party/libpg_query/grammar/statements/execute.y" { PGCreateTableAsStmt *ctas = makeNode(PGCreateTableAsStmt); @@ -312056,7 +326468,7 @@ YYLTYPE yylloc; ;} break; - case 175: + case 190: #line 33 "third_party/libpg_query/grammar/statements/execute.y" { PGCreateTableAsStmt *ctas = makeNode(PGCreateTableAsStmt); @@ -312075,17 +326487,17 @@ YYLTYPE yylloc; ;} break; - case 176: + case 191: #line 51 "third_party/libpg_query/grammar/statements/execute.y" { (yyval.list) = (yyvsp[(2) - (3)].list); ;} break; - case 177: + case 192: #line 52 "third_party/libpg_query/grammar/statements/execute.y" { (yyval.list) = NIL; ;} break; - case 178: + case 193: #line 10 "third_party/libpg_query/grammar/statements/alter_sequence.y" { PGAlterSeqStmt *n = makeNode(PGAlterSeqStmt); @@ -312096,7 +326508,7 @@ YYLTYPE yylloc; ;} break; - case 179: + case 194: #line 18 "third_party/libpg_query/grammar/statements/alter_sequence.y" { PGAlterSeqStmt *n = makeNode(PGAlterSeqStmt); @@ -312107,42 +326519,42 @@ YYLTYPE yylloc; ;} break; - case 180: + case 195: #line 29 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); ;} break; - case 181: + case 196: #line 30 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].defelt)); ;} break; - case 182: + case 197: #line 34 "third_party/libpg_query/grammar/statements/alter_sequence.y" {;} break; - case 183: + case 198: #line 35 "third_party/libpg_query/grammar/statements/alter_sequence.y" {;} break; - case 184: + case 199: #line 36 "third_party/libpg_query/grammar/statements/alter_sequence.y" {;} break; - case 185: + case 200: #line 41 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.value) = makeFloat((yyvsp[(1) - (1)].str)); ;} break; - case 186: + case 201: #line 42 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.value) = makeFloat((yyvsp[(2) - (2)].str)); ;} break; - case 187: + case 202: #line 44 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.value) = makeFloat((yyvsp[(2) - (2)].str)); @@ -312150,82 +326562,82 @@ YYLTYPE yylloc; ;} break; - case 188: + case 203: #line 48 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.value) = makeInteger((yyvsp[(1) - (1)].ival)); ;} break; - case 189: + case 204: #line 53 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.defelt) = makeDefElem("as", (PGNode *)(yyvsp[(2) - (2)].typnam), (yylsp[(1) - (2)])); ;} break; - case 190: + case 205: #line 57 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.defelt) = makeDefElem("cache", (PGNode *)(yyvsp[(2) - (2)].value), (yylsp[(1) - (2)])); ;} break; - case 191: + case 206: #line 61 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.defelt) = makeDefElem("cycle", (PGNode *)makeInteger(true), (yylsp[(1) - (1)])); ;} break; - case 192: + case 207: #line 65 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.defelt) = makeDefElem("cycle", (PGNode *)makeInteger(false), (yylsp[(1) - (2)])); ;} break; - case 193: + case 208: #line 69 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.defelt) = makeDefElem("increment", (PGNode *)(yyvsp[(3) - (3)].value), (yylsp[(1) - (3)])); ;} break; - case 194: + case 209: #line 73 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.defelt) = makeDefElem("maxvalue", (PGNode *)(yyvsp[(2) - (2)].value), (yylsp[(1) - (2)])); ;} break; - case 195: + case 210: #line 77 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.defelt) = makeDefElem("minvalue", (PGNode *)(yyvsp[(2) - (2)].value), (yylsp[(1) - (2)])); ;} break; - case 196: + case 211: #line 81 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.defelt) = makeDefElem("maxvalue", NULL, (yylsp[(1) - (2)])); ;} break; - case 197: + case 212: #line 85 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.defelt) = makeDefElem("minvalue", NULL, (yylsp[(1) - (2)])); ;} break; - case 198: + case 213: #line 89 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.defelt) = makeDefElem("owned_by", (PGNode *)(yyvsp[(3) - (3)].list), (yylsp[(1) - (3)])); ;} break; - case 199: + case 214: #line 93 "third_party/libpg_query/grammar/statements/alter_sequence.y" { /* not documented, only used by pg_dump */ @@ -312233,53 +326645,53 @@ YYLTYPE yylloc; ;} break; - case 200: + case 215: #line 98 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.defelt) = makeDefElem("start", (PGNode *)(yyvsp[(3) - (3)].value), (yylsp[(1) - (3)])); ;} break; - case 201: + case 216: #line 102 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.defelt) = makeDefElem("restart", NULL, (yylsp[(1) - (1)])); ;} break; - case 202: + case 217: #line 106 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.defelt) = makeDefElem("restart", (PGNode *)(yyvsp[(3) - (3)].value), (yylsp[(1) - (3)])); ;} break; - case 203: + case 218: #line 112 "third_party/libpg_query/grammar/statements/alter_sequence.y" {;} break; - case 204: + case 219: #line 113 "third_party/libpg_query/grammar/statements/alter_sequence.y" {;} break; - case 205: + case 220: #line 117 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.ival) = (yyvsp[(1) - (1)].ival); ;} break; - case 206: + case 221: #line 118 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.ival) = + (yyvsp[(2) - (2)].ival); ;} break; - case 207: + case 222: #line 119 "third_party/libpg_query/grammar/statements/alter_sequence.y" { (yyval.ival) = - (yyvsp[(2) - (2)].ival); ;} break; - case 208: + case 223: #line 3 "third_party/libpg_query/grammar/statements/transaction.y" { PGTransactionStmt *n = makeNode(PGTransactionStmt); @@ -312289,7 +326701,7 @@ YYLTYPE yylloc; ;} break; - case 209: + case 224: #line 10 "third_party/libpg_query/grammar/statements/transaction.y" { PGTransactionStmt *n = makeNode(PGTransactionStmt); @@ -312298,7 +326710,7 @@ YYLTYPE yylloc; ;} break; - case 210: + case 225: #line 16 "third_party/libpg_query/grammar/statements/transaction.y" { PGTransactionStmt *n = makeNode(PGTransactionStmt); @@ -312307,7 +326719,7 @@ YYLTYPE yylloc; ;} break; - case 211: + case 226: #line 22 "third_party/libpg_query/grammar/statements/transaction.y" { PGTransactionStmt *n = makeNode(PGTransactionStmt); @@ -312317,7 +326729,7 @@ YYLTYPE yylloc; ;} break; - case 212: + case 227: #line 29 "third_party/libpg_query/grammar/statements/transaction.y" { PGTransactionStmt *n = makeNode(PGTransactionStmt); @@ -312327,7 +326739,7 @@ YYLTYPE yylloc; ;} break; - case 213: + case 228: #line 36 "third_party/libpg_query/grammar/statements/transaction.y" { PGTransactionStmt *n = makeNode(PGTransactionStmt); @@ -312337,22 +326749,31 @@ YYLTYPE yylloc; ;} break; - case 214: + case 229: #line 45 "third_party/libpg_query/grammar/statements/transaction.y" {;} break; - case 215: + case 230: #line 46 "third_party/libpg_query/grammar/statements/transaction.y" {;} break; - case 216: + case 231: #line 47 "third_party/libpg_query/grammar/statements/transaction.y" {;} break; - case 217: + case 232: +#line 3 "third_party/libpg_query/grammar/statements/use.y" + { + PGUseStmt *n = makeNode(PGUseStmt); + n->name = (yyvsp[(2) - (2)].range); + (yyval.node) = (PGNode *) n; + ;} + break; + + case 233: #line 9 "third_party/libpg_query/grammar/statements/create.y" { PGCreateStmt *n = makeNode(PGCreateStmt); @@ -312368,7 +326789,7 @@ YYLTYPE yylloc; ;} break; - case 218: + case 234: #line 24 "third_party/libpg_query/grammar/statements/create.y" { PGCreateStmt *n = makeNode(PGCreateStmt); @@ -312384,7 +326805,7 @@ YYLTYPE yylloc; ;} break; - case 219: + case 235: #line 39 "third_party/libpg_query/grammar/statements/create.y" { PGCreateStmt *n = makeNode(PGCreateStmt); @@ -312400,12 +326821,12 @@ YYLTYPE yylloc; ;} break; - case 220: + case 236: #line 56 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = 0; ;} break; - case 221: + case 237: #line 58 "third_party/libpg_query/grammar/statements/create.y" { /* @@ -312432,77 +326853,77 @@ YYLTYPE yylloc; ;} break; - case 222: + case 238: #line 84 "third_party/libpg_query/grammar/statements/create.y" { (yyval.node) = (PGNode *)(yyvsp[(1) - (1)].typnam); ;} break; - case 223: + case 239: #line 85 "third_party/libpg_query/grammar/statements/create.y" { (yyval.node) = (PGNode *)makeString(pstrdup((yyvsp[(1) - (1)].keyword))); ;} break; - case 224: + case 240: #line 86 "third_party/libpg_query/grammar/statements/create.y" { (yyval.node) = (PGNode *)(yyvsp[(1) - (1)].list); ;} break; - case 225: + case 241: #line 87 "third_party/libpg_query/grammar/statements/create.y" { (yyval.node) = (PGNode *)(yyvsp[(1) - (1)].value); ;} break; - case 226: + case 242: #line 88 "third_party/libpg_query/grammar/statements/create.y" { (yyval.node) = (PGNode *)makeString((yyvsp[(1) - (1)].str)); ;} break; - case 227: + case 243: #line 89 "third_party/libpg_query/grammar/statements/create.y" { (yyval.node) = (PGNode *)makeString(pstrdup((yyvsp[(1) - (1)].keyword))); ;} break; - case 228: + case 244: #line 93 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = (yyvsp[(2) - (3)].list); ;} break; - case 229: + case 245: #line 94 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = NIL; ;} break; - case 230: + case 246: #line 99 "third_party/libpg_query/grammar/statements/create.y" { (yyval.node) = (PGNode *) makeString((yyvsp[(1) - (1)].str)); ;} break; - case 231: + case 247: #line 104 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_FKCONSTR_ACTION_NOACTION; ;} break; - case 232: + case 248: #line 105 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_FKCONSTR_ACTION_RESTRICT; ;} break; - case 233: + case 249: #line 106 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_FKCONSTR_ACTION_CASCADE; ;} break; - case 234: + case 250: #line 107 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_FKCONSTR_ACTION_SETNULL; ;} break; - case 235: + case 251: #line 108 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_FKCONSTR_ACTION_SETDEFAULT; ;} break; - case 236: + case 252: #line 114 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = castNode(PGConstraint, (yyvsp[(3) - (3)].node)); @@ -312512,17 +326933,17 @@ YYLTYPE yylloc; ;} break; - case 237: + case 253: #line 120 "third_party/libpg_query/grammar/statements/create.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 238: + case 254: #line 121 "third_party/libpg_query/grammar/statements/create.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 239: + case 255: #line 123 "third_party/libpg_query/grammar/statements/create.y" { /* @@ -312538,7 +326959,7 @@ YYLTYPE yylloc; ;} break; - case 240: + case 256: #line 140 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -312548,7 +326969,7 @@ YYLTYPE yylloc; ;} break; - case 241: + case 257: #line 147 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -312558,7 +326979,7 @@ YYLTYPE yylloc; ;} break; - case 242: + case 258: #line 154 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -312571,7 +326992,7 @@ YYLTYPE yylloc; ;} break; - case 243: + case 259: #line 164 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -312584,7 +327005,7 @@ YYLTYPE yylloc; ;} break; - case 244: + case 260: #line 174 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -312599,7 +327020,7 @@ YYLTYPE yylloc; ;} break; - case 245: + case 261: #line 186 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -312610,7 +327031,7 @@ YYLTYPE yylloc; ;} break; - case 246: + case 262: #line 194 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -312622,7 +327043,7 @@ YYLTYPE yylloc; ;} break; - case 247: + case 263: #line 203 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -312640,27 +327061,27 @@ YYLTYPE yylloc; ;} break; - case 248: + case 264: #line 220 "third_party/libpg_query/grammar/statements/create.y" { (yyval.constr) = PG_CONSTR_GENERATED_VIRTUAL; ;} break; - case 249: + case 265: #line 221 "third_party/libpg_query/grammar/statements/create.y" { (yyval.constr) = PG_CONSTR_GENERATED_STORED; ;} break; - case 250: + case 266: #line 225 "third_party/libpg_query/grammar/statements/create.y" { (yyval.constr) = (yyvsp[(1) - (1)].constr); ;} break; - case 251: + case 267: #line 226 "third_party/libpg_query/grammar/statements/create.y" { (yyval.constr) = PG_CONSTR_GENERATED_VIRTUAL; ;} break; - case 252: + case 268: #line 231 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -312672,7 +327093,7 @@ YYLTYPE yylloc; ;} break; - case 253: + case 269: #line 240 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -312698,7 +327119,7 @@ YYLTYPE yylloc; ;} break; - case 254: + case 270: #line 263 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -312711,79 +327132,79 @@ YYLTYPE yylloc; ;} break; - case 255: + case 271: #line 277 "third_party/libpg_query/grammar/statements/create.y" { (yyval.defelt) = makeDefElem((yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 256: + case 272: #line 283 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = (yyvsp[(3) - (3)].ival); ;} break; - case 257: + case 273: #line 289 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = ((yyvsp[(1) - (1)].ival) << 8) | (PG_FKCONSTR_ACTION_NOACTION & 0xFF); ;} break; - case 258: + case 274: #line 291 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = (PG_FKCONSTR_ACTION_NOACTION << 8) | ((yyvsp[(1) - (1)].ival) & 0xFF); ;} break; - case 259: + case 275: #line 293 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = ((yyvsp[(1) - (2)].ival) << 8) | ((yyvsp[(2) - (2)].ival) & 0xFF); ;} break; - case 260: + case 276: #line 295 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = ((yyvsp[(2) - (2)].ival) << 8) | ((yyvsp[(1) - (2)].ival) & 0xFF); ;} break; - case 261: + case 277: #line 297 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = (PG_FKCONSTR_ACTION_NOACTION << 8) | (PG_FKCONSTR_ACTION_NOACTION & 0xFF); ;} break; - case 262: + case 278: #line 300 "third_party/libpg_query/grammar/statements/create.y" { (yyval.oncommit) = ONCOMMIT_DROP; ;} break; - case 263: + case 279: #line 301 "third_party/libpg_query/grammar/statements/create.y" { (yyval.oncommit) = PG_ONCOMMIT_DELETE_ROWS; ;} break; - case 264: + case 280: #line 302 "third_party/libpg_query/grammar/statements/create.y" { (yyval.oncommit) = PG_ONCOMMIT_PRESERVE_ROWS; ;} break; - case 265: + case 281: #line 303 "third_party/libpg_query/grammar/statements/create.y" { (yyval.oncommit) = PG_ONCOMMIT_NOOP; ;} break; - case 266: + case 282: #line 308 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = (yyvsp[(2) - (3)].list); ;} break; - case 267: + case 283: #line 312 "third_party/libpg_query/grammar/statements/create.y" { (yyval.boolean) = true; ;} break; - case 268: + case 284: #line 313 "third_party/libpg_query/grammar/statements/create.y" { (yyval.boolean) = false; ;} break; - case 269: + case 285: #line 319 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = castNode(PGConstraint, (yyvsp[(3) - (3)].node)); @@ -312793,67 +327214,67 @@ YYLTYPE yylloc; ;} break; - case 270: + case 286: #line 325 "third_party/libpg_query/grammar/statements/create.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 271: + case 287: #line 330 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_CREATE_TABLE_LIKE_COMMENTS; ;} break; - case 272: + case 288: #line 331 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_CREATE_TABLE_LIKE_CONSTRAINTS; ;} break; - case 273: + case 289: #line 332 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_CREATE_TABLE_LIKE_DEFAULTS; ;} break; - case 274: + case 290: #line 333 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_CREATE_TABLE_LIKE_IDENTITY; ;} break; - case 275: + case 291: #line 334 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_CREATE_TABLE_LIKE_INDEXES; ;} break; - case 276: + case 292: #line 335 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_CREATE_TABLE_LIKE_STATISTICS; ;} break; - case 277: + case 293: #line 336 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_CREATE_TABLE_LIKE_STORAGE; ;} break; - case 278: + case 294: #line 337 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_CREATE_TABLE_LIKE_ALL; ;} break; - case 279: + case 295: #line 343 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); ;} break; - case 280: + case 296: #line 344 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt)); ;} break; - case 281: + case 297: #line 348 "third_party/libpg_query/grammar/statements/create.y" { (yyval.str) = (yyvsp[(3) - (3)].str); ;} break; - case 282: + case 298: #line 354 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -312863,7 +327284,7 @@ YYLTYPE yylloc; ;} break; - case 283: + case 299: #line 361 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -312873,7 +327294,7 @@ YYLTYPE yylloc; ;} break; - case 284: + case 300: #line 368 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -312883,7 +327304,7 @@ YYLTYPE yylloc; ;} break; - case 285: + case 301: #line 375 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -312893,82 +327314,82 @@ YYLTYPE yylloc; ;} break; - case 286: + case 302: #line 386 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = (yyvsp[(2) - (2)].list); ;} break; - case 287: + case 303: #line 387 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = list_make1(makeDefElem("oids", (PGNode *) makeInteger(true), (yylsp[(1) - (2)]))); ;} break; - case 288: + case 304: #line 388 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = list_make1(makeDefElem("oids", (PGNode *) makeInteger(false), (yylsp[(1) - (2)]))); ;} break; - case 289: + case 305: #line 389 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = NIL; ;} break; - case 290: + case 306: #line 393 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = (yyvsp[(2) - (3)].list); ;} break; - case 291: + case 307: #line 398 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = (yyvsp[(1) - (3)].ival) | (yyvsp[(3) - (3)].ival); ;} break; - case 292: + case 308: #line 399 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = (yyvsp[(1) - (3)].ival) & ~(yyvsp[(3) - (3)].ival); ;} break; - case 293: + case 309: #line 400 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = 0; ;} break; - case 294: + case 310: #line 405 "third_party/libpg_query/grammar/statements/create.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 295: + case 311: #line 410 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = CAS_NOT_DEFERRABLE; ;} break; - case 296: + case 312: #line 411 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = CAS_DEFERRABLE; ;} break; - case 297: + case 313: #line 412 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = CAS_INITIALLY_IMMEDIATE; ;} break; - case 298: + case 314: #line 413 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = CAS_INITIALLY_DEFERRED; ;} break; - case 299: + case 315: #line 414 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = CAS_NOT_VALID; ;} break; - case 300: + case 316: #line 415 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = CAS_NO_INHERIT; ;} break; - case 301: + case 317: #line 421 "third_party/libpg_query/grammar/statements/create.y" { PGColumnDef *n = makeNode(PGColumnDef); @@ -312990,7 +327411,7 @@ YYLTYPE yylloc; ;} break; - case 302: + case 318: #line 441 "third_party/libpg_query/grammar/statements/create.y" { PGColumnDef *n = makeNode(PGColumnDef); @@ -313019,122 +327440,122 @@ YYLTYPE yylloc; ;} break; - case 303: + case 319: #line 469 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); ;} break; - case 304: + case 320: #line 470 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt)); ;} break; - case 305: + case 321: #line 474 "third_party/libpg_query/grammar/statements/create.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 306: + case 322: #line 478 "third_party/libpg_query/grammar/statements/create.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 307: + case 323: #line 479 "third_party/libpg_query/grammar/statements/create.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 308: + case 324: #line 480 "third_party/libpg_query/grammar/statements/create.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 309: + case 325: #line 485 "third_party/libpg_query/grammar/statements/create.y" { (yyval.defelt) = makeDefElem((yyvsp[(1) - (3)].str), (PGNode *) (yyvsp[(3) - (3)].node), (yylsp[(1) - (3)])); ;} break; - case 310: + case 326: #line 489 "third_party/libpg_query/grammar/statements/create.y" { (yyval.defelt) = makeDefElem((yyvsp[(1) - (1)].str), NULL, (yylsp[(1) - (1)])); ;} break; - case 311: + case 327: #line 496 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = (yyvsp[(2) - (2)].list); ;} break; - case 312: + case 328: #line 497 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = NIL; ;} break; - case 313: + case 329: #line 502 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 314: + case 330: #line 503 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; - case 315: + case 331: #line 504 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = NIL; ;} break; - case 316: + case 332: #line 509 "third_party/libpg_query/grammar/statements/create.y" { (yyval.node) = (PGNode *) makeString((yyvsp[(1) - (1)].str)); ;} break; - case 317: + case 333: #line 516 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = (yyvsp[(2) - (3)].list); ;} break; - case 318: + case 334: #line 517 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = NIL; ;} break; - case 319: + case 335: #line 522 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); ;} break; - case 320: + case 336: #line 523 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = NIL; ;} break; - case 321: + case 337: #line 527 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = (yyvsp[(3) - (3)].ival); ;} break; - case 322: + case 338: #line 533 "third_party/libpg_query/grammar/statements/create.y" { (yyval.defelt) = makeDefElem((yyvsp[(1) - (3)].str), (PGNode *) (yyvsp[(3) - (3)].node), (yylsp[(1) - (3)])); ;} break; - case 323: + case 339: #line 537 "third_party/libpg_query/grammar/statements/create.y" { (yyval.defelt) = makeDefElem((yyvsp[(1) - (1)].str), NULL, (yylsp[(1) - (1)])); ;} break; - case 324: + case 340: #line 541 "third_party/libpg_query/grammar/statements/create.y" { (yyval.defelt) = makeDefElemExtended((yyvsp[(1) - (5)].str), (yyvsp[(3) - (5)].str), (PGNode *) (yyvsp[(5) - (5)].node), @@ -313142,39 +327563,39 @@ YYLTYPE yylloc; ;} break; - case 325: + case 341: #line 546 "third_party/libpg_query/grammar/statements/create.y" { (yyval.defelt) = makeDefElemExtended((yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].str), NULL, PG_DEFELEM_UNSPEC, (yylsp[(1) - (3)])); ;} break; - case 326: + case 342: #line 553 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 327: + case 343: #line 554 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 328: + case 344: #line 558 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 329: + case 345: #line 559 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; - case 330: + case 346: #line 563 "third_party/libpg_query/grammar/statements/create.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 331: + case 347: #line 565 "third_party/libpg_query/grammar/statements/create.y" { (yyval.typnam) = makeTypeNameFromNameList(lcons(makeString((yyvsp[(1) - (4)].str)), (yyvsp[(2) - (4)].list))); @@ -313183,7 +327604,7 @@ YYLTYPE yylloc; ;} break; - case 332: + case 348: #line 571 "third_party/libpg_query/grammar/statements/create.y" { (yyval.typnam) = makeTypeNameFromNameList(lcons(makeString((yyvsp[(2) - (5)].str)), (yyvsp[(3) - (5)].list))); @@ -313193,7 +327614,7 @@ YYLTYPE yylloc; ;} break; - case 333: + case 349: #line 582 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -313209,7 +327630,7 @@ YYLTYPE yylloc; ;} break; - case 334: + case 350: #line 596 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -313225,7 +327646,7 @@ YYLTYPE yylloc; ;} break; - case 335: + case 351: #line 609 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -313242,7 +327663,7 @@ YYLTYPE yylloc; ;} break; - case 336: + case 352: #line 624 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -313258,7 +327679,7 @@ YYLTYPE yylloc; ;} break; - case 337: + case 353: #line 637 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -313275,7 +327696,7 @@ YYLTYPE yylloc; ;} break; - case 338: + case 354: #line 652 "third_party/libpg_query/grammar/statements/create.y" { PGConstraint *n = makeNode(PGConstraint); @@ -313296,28 +327717,28 @@ YYLTYPE yylloc; ;} break; - case 339: + case 355: #line 674 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 340: + case 356: #line 678 "third_party/libpg_query/grammar/statements/create.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 341: + case 357: #line 685 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_FKCONSTR_MATCH_FULL; ;} break; - case 342: + case 358: #line 689 "third_party/libpg_query/grammar/statements/create.y" { ereport(ERROR, @@ -313328,21 +327749,21 @@ YYLTYPE yylloc; ;} break; - case 343: + case 359: #line 697 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_FKCONSTR_MATCH_SIMPLE; ;} break; - case 344: + case 360: #line 701 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_FKCONSTR_MATCH_SIMPLE; ;} break; - case 345: + case 361: #line 709 "third_party/libpg_query/grammar/statements/create.y" { PGTableLikeClause *n = makeNode(PGTableLikeClause); @@ -313352,27 +327773,27 @@ YYLTYPE yylloc; ;} break; - case 346: + case 362: #line 718 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_RELPERSISTENCE_TEMP; ;} break; - case 347: + case 363: #line 719 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_RELPERSISTENCE_TEMP; ;} break; - case 348: + case 364: #line 720 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_RELPERSISTENCE_TEMP; ;} break; - case 349: + case 365: #line 721 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_RELPERSISTENCE_TEMP; ;} break; - case 350: + case 366: #line 723 "third_party/libpg_query/grammar/statements/create.y" { ereport(PGWARNING, @@ -313382,7 +327803,7 @@ YYLTYPE yylloc; ;} break; - case 351: + case 367: #line 730 "third_party/libpg_query/grammar/statements/create.y" { ereport(PGWARNING, @@ -313392,27 +327813,27 @@ YYLTYPE yylloc; ;} break; - case 352: + case 368: #line 736 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_RELPERSISTENCE_UNLOGGED; ;} break; - case 353: + case 369: #line 737 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = RELPERSISTENCE_PERMANENT; ;} break; - case 354: + case 370: #line 742 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = PG_ATTRIBUTE_IDENTITY_ALWAYS; ;} break; - case 355: + case 371: #line 743 "third_party/libpg_query/grammar/statements/create.y" { (yyval.ival) = ATTRIBUTE_IDENTITY_BY_DEFAULT; ;} break; - case 356: + case 372: #line 10 "third_party/libpg_query/grammar/statements/drop.y" { PGDropStmt *n = makeNode(PGDropStmt); @@ -313425,7 +327846,7 @@ YYLTYPE yylloc; ;} break; - case 357: + case 373: #line 20 "third_party/libpg_query/grammar/statements/drop.y" { PGDropStmt *n = makeNode(PGDropStmt); @@ -313438,7 +327859,7 @@ YYLTYPE yylloc; ;} break; - case 358: + case 374: #line 30 "third_party/libpg_query/grammar/statements/drop.y" { PGDropStmt *n = makeNode(PGDropStmt); @@ -313451,7 +327872,7 @@ YYLTYPE yylloc; ;} break; - case 359: + case 375: #line 40 "third_party/libpg_query/grammar/statements/drop.y" { PGDropStmt *n = makeNode(PGDropStmt); @@ -313464,7 +327885,7 @@ YYLTYPE yylloc; ;} break; - case 360: + case 376: #line 50 "third_party/libpg_query/grammar/statements/drop.y" { PGDropStmt *n = makeNode(PGDropStmt); @@ -313477,7 +327898,7 @@ YYLTYPE yylloc; ;} break; - case 361: + case 377: #line 60 "third_party/libpg_query/grammar/statements/drop.y" { PGDropStmt *n = makeNode(PGDropStmt); @@ -313490,7 +327911,7 @@ YYLTYPE yylloc; ;} break; - case 362: + case 378: #line 70 "third_party/libpg_query/grammar/statements/drop.y" { PGDropStmt *n = makeNode(PGDropStmt); @@ -313503,7 +327924,7 @@ YYLTYPE yylloc; ;} break; - case 363: + case 379: #line 80 "third_party/libpg_query/grammar/statements/drop.y" { PGDropStmt *n = makeNode(PGDropStmt); @@ -313516,172 +327937,177 @@ YYLTYPE yylloc; ;} break; - case 364: + case 380: #line 93 "third_party/libpg_query/grammar/statements/drop.y" { (yyval.objtype) = PG_OBJECT_TABLE; ;} break; - case 365: + case 381: #line 94 "third_party/libpg_query/grammar/statements/drop.y" - { (yyval.objtype) = PG_OBJECT_SEQUENCE; ;} + { (yyval.objtype) = PG_OBJECT_DATABASE; ;} break; - case 366: + case 382: #line 95 "third_party/libpg_query/grammar/statements/drop.y" - { (yyval.objtype) = PG_OBJECT_FUNCTION; ;} + { (yyval.objtype) = PG_OBJECT_SEQUENCE; ;} break; - case 367: + case 383: #line 96 "third_party/libpg_query/grammar/statements/drop.y" { (yyval.objtype) = PG_OBJECT_FUNCTION; ;} break; - case 368: + case 384: #line 97 "third_party/libpg_query/grammar/statements/drop.y" - { (yyval.objtype) = PG_OBJECT_TABLE_MACRO; ;} + { (yyval.objtype) = PG_OBJECT_FUNCTION; ;} break; - case 369: + case 385: #line 98 "third_party/libpg_query/grammar/statements/drop.y" - { (yyval.objtype) = PG_OBJECT_VIEW; ;} + { (yyval.objtype) = PG_OBJECT_TABLE_MACRO; ;} break; - case 370: + case 386: #line 99 "third_party/libpg_query/grammar/statements/drop.y" - { (yyval.objtype) = PG_OBJECT_MATVIEW; ;} + { (yyval.objtype) = PG_OBJECT_VIEW; ;} break; - case 371: + case 387: #line 100 "third_party/libpg_query/grammar/statements/drop.y" - { (yyval.objtype) = PG_OBJECT_INDEX; ;} + { (yyval.objtype) = PG_OBJECT_MATVIEW; ;} break; - case 372: + case 388: #line 101 "third_party/libpg_query/grammar/statements/drop.y" - { (yyval.objtype) = PG_OBJECT_FOREIGN_TABLE; ;} + { (yyval.objtype) = PG_OBJECT_INDEX; ;} break; - case 373: + case 389: #line 102 "third_party/libpg_query/grammar/statements/drop.y" - { (yyval.objtype) = PG_OBJECT_COLLATION; ;} + { (yyval.objtype) = PG_OBJECT_FOREIGN_TABLE; ;} break; - case 374: + case 390: #line 103 "third_party/libpg_query/grammar/statements/drop.y" - { (yyval.objtype) = PG_OBJECT_CONVERSION; ;} + { (yyval.objtype) = PG_OBJECT_COLLATION; ;} break; - case 375: + case 391: #line 104 "third_party/libpg_query/grammar/statements/drop.y" - { (yyval.objtype) = PG_OBJECT_STATISTIC_EXT; ;} + { (yyval.objtype) = PG_OBJECT_CONVERSION; ;} break; - case 376: + case 392: #line 105 "third_party/libpg_query/grammar/statements/drop.y" - { (yyval.objtype) = PG_OBJECT_TSPARSER; ;} + { (yyval.objtype) = PG_OBJECT_SCHEMA; ;} break; - case 377: + case 393: #line 106 "third_party/libpg_query/grammar/statements/drop.y" - { (yyval.objtype) = PG_OBJECT_TSDICTIONARY; ;} + { (yyval.objtype) = PG_OBJECT_STATISTIC_EXT; ;} break; - case 378: + case 394: #line 107 "third_party/libpg_query/grammar/statements/drop.y" - { (yyval.objtype) = PG_OBJECT_TSTEMPLATE; ;} + { (yyval.objtype) = PG_OBJECT_TSPARSER; ;} break; - case 379: + case 395: #line 108 "third_party/libpg_query/grammar/statements/drop.y" - { (yyval.objtype) = PG_OBJECT_TSCONFIGURATION; ;} + { (yyval.objtype) = PG_OBJECT_TSDICTIONARY; ;} break; - case 380: -#line 113 "third_party/libpg_query/grammar/statements/drop.y" - { (yyval.objtype) = PG_OBJECT_ACCESS_METHOD; ;} + case 396: +#line 109 "third_party/libpg_query/grammar/statements/drop.y" + { (yyval.objtype) = PG_OBJECT_TSTEMPLATE; ;} break; - case 381: -#line 114 "third_party/libpg_query/grammar/statements/drop.y" - { (yyval.objtype) = PG_OBJECT_EVENT_TRIGGER; ;} + case 397: +#line 110 "third_party/libpg_query/grammar/statements/drop.y" + { (yyval.objtype) = PG_OBJECT_TSCONFIGURATION; ;} break; - case 382: + case 398: #line 115 "third_party/libpg_query/grammar/statements/drop.y" - { (yyval.objtype) = PG_OBJECT_EXTENSION; ;} + { (yyval.objtype) = PG_OBJECT_ACCESS_METHOD; ;} break; - case 383: + case 399: #line 116 "third_party/libpg_query/grammar/statements/drop.y" - { (yyval.objtype) = PG_OBJECT_FDW; ;} + { (yyval.objtype) = PG_OBJECT_EVENT_TRIGGER; ;} break; - case 384: + case 400: #line 117 "third_party/libpg_query/grammar/statements/drop.y" - { (yyval.objtype) = PG_OBJECT_PUBLICATION; ;} + { (yyval.objtype) = PG_OBJECT_EXTENSION; ;} break; - case 385: + case 401: #line 118 "third_party/libpg_query/grammar/statements/drop.y" - { (yyval.objtype) = PG_OBJECT_SCHEMA; ;} + { (yyval.objtype) = PG_OBJECT_FDW; ;} break; - case 386: + case 402: #line 119 "third_party/libpg_query/grammar/statements/drop.y" + { (yyval.objtype) = PG_OBJECT_PUBLICATION; ;} + break; + + case 403: +#line 120 "third_party/libpg_query/grammar/statements/drop.y" { (yyval.objtype) = PG_OBJECT_FOREIGN_SERVER; ;} break; - case 387: -#line 124 "third_party/libpg_query/grammar/statements/drop.y" + case 404: +#line 125 "third_party/libpg_query/grammar/statements/drop.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].list)); ;} break; - case 388: -#line 125 "third_party/libpg_query/grammar/statements/drop.y" + case 405: +#line 126 "third_party/libpg_query/grammar/statements/drop.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); ;} break; - case 389: -#line 130 "third_party/libpg_query/grammar/statements/drop.y" + case 406: +#line 131 "third_party/libpg_query/grammar/statements/drop.y" { (yyval.dbehavior) = PG_DROP_CASCADE; ;} break; - case 390: -#line 131 "third_party/libpg_query/grammar/statements/drop.y" + case 407: +#line 132 "third_party/libpg_query/grammar/statements/drop.y" { (yyval.dbehavior) = PG_DROP_RESTRICT; ;} break; - case 391: -#line 132 "third_party/libpg_query/grammar/statements/drop.y" + case 408: +#line 133 "third_party/libpg_query/grammar/statements/drop.y" { (yyval.dbehavior) = PG_DROP_RESTRICT; /* default */ ;} break; - case 392: -#line 137 "third_party/libpg_query/grammar/statements/drop.y" + case 409: +#line 138 "third_party/libpg_query/grammar/statements/drop.y" { (yyval.objtype) = PG_OBJECT_POLICY; ;} break; - case 393: -#line 138 "third_party/libpg_query/grammar/statements/drop.y" + case 410: +#line 139 "third_party/libpg_query/grammar/statements/drop.y" { (yyval.objtype) = PG_OBJECT_RULE; ;} break; - case 394: -#line 139 "third_party/libpg_query/grammar/statements/drop.y" + case 411: +#line 140 "third_party/libpg_query/grammar/statements/drop.y" { (yyval.objtype) = PG_OBJECT_TRIGGER; ;} break; - case 395: -#line 142 "third_party/libpg_query/grammar/statements/drop.y" + case 412: +#line 143 "third_party/libpg_query/grammar/statements/drop.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].typnam)); ;} break; - case 396: -#line 143 "third_party/libpg_query/grammar/statements/drop.y" + case 413: +#line 144 "third_party/libpg_query/grammar/statements/drop.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].typnam)); ;} break; - case 397: + case 414: #line 9 "third_party/libpg_query/grammar/statements/create_function.y" { PGCreateFunctionStmt *n = makeNode(PGCreateFunctionStmt); @@ -313695,7 +328121,7 @@ YYLTYPE yylloc; ;} break; - case 398: + case 415: #line 21 "third_party/libpg_query/grammar/statements/create_function.y" { PGCreateFunctionStmt *n = makeNode(PGCreateFunctionStmt); @@ -313710,7 +328136,7 @@ YYLTYPE yylloc; ;} break; - case 399: + case 416: #line 34 "third_party/libpg_query/grammar/statements/create_function.y" { PGCreateFunctionStmt *n = makeNode(PGCreateFunctionStmt); @@ -313725,7 +328151,7 @@ YYLTYPE yylloc; ;} break; - case 400: + case 417: #line 47 "third_party/libpg_query/grammar/statements/create_function.y" { PGCreateFunctionStmt *n = makeNode(PGCreateFunctionStmt); @@ -313739,7 +328165,7 @@ YYLTYPE yylloc; ;} break; - case 401: + case 418: #line 59 "third_party/libpg_query/grammar/statements/create_function.y" { PGCreateFunctionStmt *n = makeNode(PGCreateFunctionStmt); @@ -313753,7 +328179,7 @@ YYLTYPE yylloc; ;} break; - case 402: + case 419: #line 71 "third_party/libpg_query/grammar/statements/create_function.y" { PGCreateFunctionStmt *n = makeNode(PGCreateFunctionStmt); @@ -313767,21 +328193,21 @@ YYLTYPE yylloc; ;} break; - case 405: + case 422: #line 92 "third_party/libpg_query/grammar/statements/create_function.y" { (yyval.list) = NIL; ;} break; - case 406: + case 423: #line 96 "third_party/libpg_query/grammar/statements/create_function.y" { (yyval.list) = (yyvsp[(2) - (3)].list); ;} break; - case 407: + case 424: #line 12 "third_party/libpg_query/grammar/statements/update.y" { PGUpdateStmt *n = makeNode(PGUpdateStmt); @@ -313795,7 +328221,7 @@ YYLTYPE yylloc; ;} break; - case 408: + case 425: #line 3 "third_party/libpg_query/grammar/statements/copy.y" { PGCopyStmt *n = makeNode(PGCopyStmt); @@ -313826,7 +328252,7 @@ YYLTYPE yylloc; ;} break; - case 409: + case 426: #line 31 "third_party/libpg_query/grammar/statements/copy.y" { PGCopyStmt *n = makeNode(PGCopyStmt); @@ -313848,296 +328274,310 @@ YYLTYPE yylloc; ;} break; - case 410: + case 427: #line 53 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.boolean) = true; ;} break; - case 411: + case 428: #line 54 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.boolean) = false; ;} break; - case 412: + case 429: #line 60 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.defelt) = makeDefElem("delimiter", (PGNode *)makeString((yyvsp[(3) - (3)].str)), (yylsp[(2) - (3)])); ;} break; - case 413: + case 430: #line 63 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.defelt) = NULL; ;} break; - case 414: + case 431: #line 69 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 415: + case 432: #line 73 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 416: + case 433: #line 80 "third_party/libpg_query/grammar/statements/copy.y" {;} break; - case 417: + case 434: #line 81 "third_party/libpg_query/grammar/statements/copy.y" {;} break; - case 418: + case 435: #line 85 "third_party/libpg_query/grammar/statements/copy.y" {;} break; - case 419: + case 436: #line 86 "third_party/libpg_query/grammar/statements/copy.y" {;} break; - case 420: + case 437: #line 91 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.boolean) = true; ;} break; - case 421: + case 438: #line 92 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.boolean) = false; ;} break; - case 422: + case 439: #line 96 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 423: + case 440: #line 97 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.list) = (yyvsp[(2) - (3)].list); ;} break; - case 424: + case 441: #line 102 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.node) = (PGNode *) makeString((yyvsp[(1) - (1)].str)); ;} break; - case 425: + case 442: #line 103 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.node) = (PGNode *) (yyvsp[(1) - (1)].value); ;} break; - case 426: + case 443: #line 104 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.node) = (PGNode *) makeNode(PGAStar); ;} break; - case 427: + case 444: #line 105 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.node) = (PGNode *) (yyvsp[(2) - (3)].list); ;} break; - case 428: + case 445: #line 106 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.node) = NULL; ;} break; - case 429: + case 446: #line 112 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.defelt) = makeDefElem((yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 430: + case 447: #line 120 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.defelt) = makeDefElem("oids", (PGNode *)makeInteger(true), (yylsp[(1) - (2)])); ;} break; - case 431: + case 448: #line 123 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.defelt) = NULL; ;} break; - case 432: + case 449: #line 128 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].defelt)); ;} break; - case 433: + case 450: #line 129 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.list) = NIL; ;} break; - case 434: + case 451: #line 135 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.defelt) = makeDefElem("format", (PGNode *)makeString("binary"), (yylsp[(1) - (1)])); ;} break; - case 435: + case 452: #line 138 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.defelt) = NULL; ;} break; - case 436: + case 453: #line 144 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.defelt) = makeDefElem("format", (PGNode *)makeString("binary"), (yylsp[(1) - (1)])); ;} break; - case 437: + case 454: #line 148 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.defelt) = makeDefElem("oids", (PGNode *)makeInteger(true), (yylsp[(1) - (1)])); ;} break; - case 438: + case 455: #line 152 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.defelt) = makeDefElem("freeze", (PGNode *)makeInteger(true), (yylsp[(1) - (1)])); ;} break; - case 439: + case 456: #line 156 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.defelt) = makeDefElem("delimiter", (PGNode *)makeString((yyvsp[(3) - (3)].str)), (yylsp[(1) - (3)])); ;} break; - case 440: + case 457: #line 160 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.defelt) = makeDefElem("null", (PGNode *)makeString((yyvsp[(3) - (3)].str)), (yylsp[(1) - (3)])); ;} break; - case 441: + case 458: #line 164 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.defelt) = makeDefElem("format", (PGNode *)makeString("csv"), (yylsp[(1) - (1)])); ;} break; - case 442: + case 459: #line 168 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.defelt) = makeDefElem("header", (PGNode *)makeInteger(true), (yylsp[(1) - (1)])); ;} break; - case 443: + case 460: #line 172 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.defelt) = makeDefElem("quote", (PGNode *)makeString((yyvsp[(3) - (3)].str)), (yylsp[(1) - (3)])); ;} break; - case 444: + case 461: #line 176 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.defelt) = makeDefElem("escape", (PGNode *)makeString((yyvsp[(3) - (3)].str)), (yylsp[(1) - (3)])); ;} break; - case 445: + case 462: #line 180 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.defelt) = makeDefElem("force_quote", (PGNode *)(yyvsp[(3) - (3)].list), (yylsp[(1) - (3)])); ;} break; - case 446: + case 463: #line 184 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.defelt) = makeDefElem("force_quote", (PGNode *)makeNode(PGAStar), (yylsp[(1) - (3)])); ;} break; - case 447: + case 464: #line 188 "third_party/libpg_query/grammar/statements/copy.y" { - (yyval.defelt) = makeDefElem("force_not_null", (PGNode *)(yyvsp[(4) - (4)].list), (yylsp[(1) - (4)])); + (yyval.defelt) = makeDefElem("partition_by", (PGNode *)(yyvsp[(3) - (3)].list), (yylsp[(1) - (3)])); ;} break; - case 448: + case 465: #line 192 "third_party/libpg_query/grammar/statements/copy.y" { - (yyval.defelt) = makeDefElem("force_null", (PGNode *)(yyvsp[(3) - (3)].list), (yylsp[(1) - (3)])); + (yyval.defelt) = makeDefElem("partition_by", (PGNode *)makeNode(PGAStar), (yylsp[(1) - (3)])); ;} break; - case 449: + case 466: #line 196 "third_party/libpg_query/grammar/statements/copy.y" + { + (yyval.defelt) = makeDefElem("force_not_null", (PGNode *)(yyvsp[(4) - (4)].list), (yylsp[(1) - (4)])); + ;} + break; + + case 467: +#line 200 "third_party/libpg_query/grammar/statements/copy.y" + { + (yyval.defelt) = makeDefElem("force_null", (PGNode *)(yyvsp[(3) - (3)].list), (yylsp[(1) - (3)])); + ;} + break; + + case 468: +#line 204 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.defelt) = makeDefElem("encoding", (PGNode *)makeString((yyvsp[(2) - (2)].str)), (yylsp[(1) - (2)])); ;} break; - case 450: -#line 203 "third_party/libpg_query/grammar/statements/copy.y" + case 469: +#line 211 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.node) = (PGNode *) makeString((yyvsp[(1) - (1)].str)); ;} break; - case 451: -#line 209 "third_party/libpg_query/grammar/statements/copy.y" + case 470: +#line 217 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 452: -#line 210 "third_party/libpg_query/grammar/statements/copy.y" + case 471: +#line 218 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.str) = NULL; ;} break; - case 453: -#line 211 "third_party/libpg_query/grammar/statements/copy.y" + case 472: +#line 219 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.str) = NULL; ;} break; - case 454: -#line 217 "third_party/libpg_query/grammar/statements/copy.y" + case 473: +#line 225 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); ;} break; - case 455: -#line 221 "third_party/libpg_query/grammar/statements/copy.y" + case 474: +#line 229 "third_party/libpg_query/grammar/statements/copy.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt)); ;} break; - case 458: + case 477: #line 52 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (3)].node); ;} break; - case 459: + case 478: #line 53 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (3)].node); ;} break; - case 460: + case 479: #line 68 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 461: + case 480: #line 70 "third_party/libpg_query/grammar/statements/select.y" { insertSelectOptions((PGSelectStmt *) (yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].list), NIL, @@ -314147,7 +328587,7 @@ YYLTYPE yylloc; ;} break; - case 462: + case 481: #line 77 "third_party/libpg_query/grammar/statements/select.y" { insertSelectOptions((PGSelectStmt *) (yyvsp[(1) - (4)].node), (yyvsp[(2) - (4)].list), (yyvsp[(3) - (4)].list), @@ -314158,7 +328598,7 @@ YYLTYPE yylloc; ;} break; - case 463: + case 482: #line 85 "third_party/libpg_query/grammar/statements/select.y" { insertSelectOptions((PGSelectStmt *) (yyvsp[(1) - (4)].node), (yyvsp[(2) - (4)].list), (yyvsp[(4) - (4)].list), @@ -314169,7 +328609,7 @@ YYLTYPE yylloc; ;} break; - case 464: + case 483: #line 93 "third_party/libpg_query/grammar/statements/select.y" { insertSelectOptions((PGSelectStmt *) (yyvsp[(2) - (2)].node), NULL, NIL, @@ -314180,7 +328620,7 @@ YYLTYPE yylloc; ;} break; - case 465: + case 484: #line 101 "third_party/libpg_query/grammar/statements/select.y" { insertSelectOptions((PGSelectStmt *) (yyvsp[(2) - (3)].node), (yyvsp[(3) - (3)].list), NIL, @@ -314191,7 +328631,7 @@ YYLTYPE yylloc; ;} break; - case 466: + case 485: #line 109 "third_party/libpg_query/grammar/statements/select.y" { insertSelectOptions((PGSelectStmt *) (yyvsp[(2) - (5)].node), (yyvsp[(3) - (5)].list), (yyvsp[(4) - (5)].list), @@ -314202,7 +328642,7 @@ YYLTYPE yylloc; ;} break; - case 467: + case 486: #line 117 "third_party/libpg_query/grammar/statements/select.y" { insertSelectOptions((PGSelectStmt *) (yyvsp[(2) - (5)].node), (yyvsp[(3) - (5)].list), (yyvsp[(5) - (5)].list), @@ -314213,24 +328653,24 @@ YYLTYPE yylloc; ;} break; - case 468: + case 487: #line 127 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 469: + case 488: #line 128 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 470: + case 489: #line 156 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (3)].list); ;} break; - case 471: + case 490: #line 160 "third_party/libpg_query/grammar/statements/select.y" { PGAStar *star = makeNode(PGAStar); @@ -314238,7 +328678,7 @@ YYLTYPE yylloc; ;} break; - case 472: + case 491: #line 171 "third_party/libpg_query/grammar/statements/select.y" { PGSelectStmt *n = makeNode(PGSelectStmt); @@ -314255,7 +328695,7 @@ YYLTYPE yylloc; ;} break; - case 473: + case 492: #line 187 "third_party/libpg_query/grammar/statements/select.y" { PGSelectStmt *n = makeNode(PGSelectStmt); @@ -314273,7 +328713,7 @@ YYLTYPE yylloc; ;} break; - case 474: + case 493: #line 204 "third_party/libpg_query/grammar/statements/select.y" { PGSelectStmt *n = makeNode(PGSelectStmt); @@ -314290,7 +328730,7 @@ YYLTYPE yylloc; ;} break; - case 475: + case 494: #line 221 "third_party/libpg_query/grammar/statements/select.y" { PGSelectStmt *n = makeNode(PGSelectStmt); @@ -314308,12 +328748,12 @@ YYLTYPE yylloc; ;} break; - case 476: + case 495: #line 235 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 477: + case 496: #line 237 "third_party/libpg_query/grammar/statements/select.y" { /* same as SELECT * FROM relation_expr */ @@ -314335,35 +328775,35 @@ YYLTYPE yylloc; ;} break; - case 478: + case 497: #line 256 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSetOp(PG_SETOP_UNION_BY_NAME, (yyvsp[(3) - (5)].boolean), (yyvsp[(1) - (5)].node), (yyvsp[(5) - (5)].node)); ;} break; - case 479: + case 498: #line 260 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSetOp(PG_SETOP_UNION, (yyvsp[(3) - (4)].boolean), (yyvsp[(1) - (4)].node), (yyvsp[(4) - (4)].node)); ;} break; - case 480: + case 499: #line 264 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSetOp(PG_SETOP_INTERSECT, (yyvsp[(3) - (4)].boolean), (yyvsp[(1) - (4)].node), (yyvsp[(4) - (4)].node)); ;} break; - case 481: + case 500: #line 268 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSetOp(PG_SETOP_EXCEPT, (yyvsp[(3) - (4)].boolean), (yyvsp[(1) - (4)].node), (yyvsp[(4) - (4)].node)); ;} break; - case 482: + case 501: #line 285 "third_party/libpg_query/grammar/statements/select.y" { (yyval.with) = makeNode(PGWithClause); @@ -314373,7 +328813,7 @@ YYLTYPE yylloc; ;} break; - case 483: + case 502: #line 292 "third_party/libpg_query/grammar/statements/select.y" { (yyval.with) = makeNode(PGWithClause); @@ -314383,7 +328823,7 @@ YYLTYPE yylloc; ;} break; - case 484: + case 503: #line 299 "third_party/libpg_query/grammar/statements/select.y" { (yyval.with) = makeNode(PGWithClause); @@ -314393,17 +328833,17 @@ YYLTYPE yylloc; ;} break; - case 485: + case 504: #line 308 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 486: + case 505: #line 309 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 487: + case 506: #line 313 "third_party/libpg_query/grammar/statements/select.y" { PGCommonTableExpr *n = makeNode(PGCommonTableExpr); @@ -314415,7 +328855,7 @@ YYLTYPE yylloc; ;} break; - case 488: + case 507: #line 325 "third_party/libpg_query/grammar/statements/select.y" { (yyval.into) = makeNode(PGIntoClause); @@ -314428,12 +328868,12 @@ YYLTYPE yylloc; ;} break; - case 489: + case 508: #line 335 "third_party/libpg_query/grammar/statements/select.y" { (yyval.into) = NULL; ;} break; - case 490: + case 509: #line 344 "third_party/libpg_query/grammar/statements/select.y" { (yyval.range) = (yyvsp[(3) - (3)].range); @@ -314441,7 +328881,7 @@ YYLTYPE yylloc; ;} break; - case 491: + case 510: #line 349 "third_party/libpg_query/grammar/statements/select.y" { (yyval.range) = (yyvsp[(3) - (3)].range); @@ -314449,7 +328889,7 @@ YYLTYPE yylloc; ;} break; - case 492: + case 511: #line 354 "third_party/libpg_query/grammar/statements/select.y" { (yyval.range) = (yyvsp[(4) - (4)].range); @@ -314457,7 +328897,7 @@ YYLTYPE yylloc; ;} break; - case 493: + case 512: #line 359 "third_party/libpg_query/grammar/statements/select.y" { (yyval.range) = (yyvsp[(4) - (4)].range); @@ -314465,7 +328905,7 @@ YYLTYPE yylloc; ;} break; - case 494: + case 513: #line 364 "third_party/libpg_query/grammar/statements/select.y" { ereport(PGWARNING, @@ -314476,7 +328916,7 @@ YYLTYPE yylloc; ;} break; - case 495: + case 514: #line 372 "third_party/libpg_query/grammar/statements/select.y" { ereport(PGWARNING, @@ -314487,7 +328927,7 @@ YYLTYPE yylloc; ;} break; - case 496: + case 515: #line 380 "third_party/libpg_query/grammar/statements/select.y" { (yyval.range) = (yyvsp[(3) - (3)].range); @@ -314495,7 +328935,7 @@ YYLTYPE yylloc; ;} break; - case 497: + case 516: #line 385 "third_party/libpg_query/grammar/statements/select.y" { (yyval.range) = (yyvsp[(2) - (2)].range); @@ -314503,7 +328943,7 @@ YYLTYPE yylloc; ;} break; - case 498: + case 517: #line 390 "third_party/libpg_query/grammar/statements/select.y" { (yyval.range) = (yyvsp[(1) - (1)].range); @@ -314511,87 +328951,87 @@ YYLTYPE yylloc; ;} break; - case 499: + case 518: #line 396 "third_party/libpg_query/grammar/statements/select.y" {;} break; - case 500: + case 519: #line 397 "third_party/libpg_query/grammar/statements/select.y" {;} break; - case 501: + case 520: #line 401 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = true; ;} break; - case 502: + case 521: #line 402 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = false; ;} break; - case 503: + case 522: #line 403 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = false; ;} break; - case 504: + case 523: #line 407 "third_party/libpg_query/grammar/statements/select.y" { ;} break; - case 505: + case 524: #line 414 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(NIL); ;} break; - case 506: + case 525: #line 415 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(4) - (5)].list); ;} break; - case 507: + case 526: #line 419 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL;;} break; - case 508: + case 527: #line 420 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 509: + case 528: #line 424 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = true;;} break; - case 510: + case 529: #line 425 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = false;;} break; - case 511: + case 530: #line 426 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = false; ;} break; - case 512: + case 531: #line 430 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list);;} break; - case 513: + case 532: #line 431 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 514: + case 533: #line 435 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (3)].list); ;} break; - case 515: + case 534: #line 437 "third_party/libpg_query/grammar/statements/select.y" { PGSortBy *sort = makeNode(PGSortBy); @@ -314604,7 +329044,7 @@ YYLTYPE yylloc; ;} break; - case 516: + case 535: #line 447 "third_party/libpg_query/grammar/statements/select.y" { PGSortBy *sort = makeNode(PGSortBy); @@ -314617,17 +329057,17 @@ YYLTYPE yylloc; ;} break; - case 517: + case 536: #line 459 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].sortby)); ;} break; - case 518: + case 537: #line 460 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].sortby)); ;} break; - case 519: + case 538: #line 464 "third_party/libpg_query/grammar/statements/select.y" { (yyval.sortby) = makeNode(PGSortBy); @@ -314639,7 +329079,7 @@ YYLTYPE yylloc; ;} break; - case 520: + case 539: #line 473 "third_party/libpg_query/grammar/statements/select.y" { (yyval.sortby) = makeNode(PGSortBy); @@ -314651,72 +329091,72 @@ YYLTYPE yylloc; ;} break; - case 521: + case 540: #line 483 "third_party/libpg_query/grammar/statements/select.y" { (yyval.sortorder) = PG_SORTBY_ASC; ;} break; - case 522: + case 541: #line 484 "third_party/libpg_query/grammar/statements/select.y" { (yyval.sortorder) = PG_SORTBY_DESC; ;} break; - case 523: + case 542: #line 485 "third_party/libpg_query/grammar/statements/select.y" { (yyval.sortorder) = PG_SORTBY_DEFAULT; ;} break; - case 524: + case 543: #line 488 "third_party/libpg_query/grammar/statements/select.y" { (yyval.nullorder) = PG_SORTBY_NULLS_FIRST; ;} break; - case 525: + case 544: #line 489 "third_party/libpg_query/grammar/statements/select.y" { (yyval.nullorder) = PG_SORTBY_NULLS_LAST; ;} break; - case 526: + case 545: #line 490 "third_party/libpg_query/grammar/statements/select.y" { (yyval.nullorder) = PG_SORTBY_NULLS_DEFAULT; ;} break; - case 527: + case 546: #line 494 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].node)); ;} break; - case 528: + case 547: #line 495 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node)); ;} break; - case 529: + case 548: #line 496 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2(NULL, (yyvsp[(1) - (1)].node)); ;} break; - case 530: + case 549: #line 497 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(1) - (1)].node), NULL); ;} break; - case 531: + case 550: #line 501 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 532: + case 551: #line 502 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2(NULL,NULL); ;} break; - case 533: + case 552: #line 507 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 534: + case 553: #line 509 "third_party/libpg_query/grammar/statements/select.y" { /* Disabled because it was too confusing, bjm 2002-02-18 */ @@ -314728,91 +329168,91 @@ YYLTYPE yylloc; ;} break; - case 535: + case 554: #line 525 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(3) - (5)].node); ;} break; - case 536: + case 555: #line 527 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeIntConst(1, -1); ;} break; - case 537: + case 556: #line 532 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 538: + case 557: #line 535 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (3)].node); ;} break; - case 539: + case 558: #line 543 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSampleSize(makeFloat((yyvsp[(1) - (2)].str)), true); ;} break; - case 540: + case 559: #line 547 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSampleSize(makeInteger((yyvsp[(1) - (2)].ival)), true); ;} break; - case 541: + case 560: #line 551 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSampleSize(makeFloat((yyvsp[(1) - (2)].str)), true); ;} break; - case 542: + case 561: #line 555 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSampleSize(makeInteger((yyvsp[(1) - (2)].ival)), true); ;} break; - case 543: + case 562: #line 559 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSampleSize(makeInteger((yyvsp[(1) - (1)].ival)), false); ;} break; - case 544: + case 563: #line 563 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSampleSize(makeInteger((yyvsp[(1) - (2)].ival)), false); ;} break; - case 545: + case 564: #line 570 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(3) - (3)].node); ;} break; - case 546: + case 565: #line 574 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 547: + case 566: #line 581 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 548: + case 567: #line 582 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = NULL; ;} break; - case 549: + case 568: #line 587 "third_party/libpg_query/grammar/statements/select.y" { int seed = (yyvsp[(5) - (5)].ival); @@ -314820,21 +329260,21 @@ YYLTYPE yylloc; ;} break; - case 550: + case 569: #line 592 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSampleOptions((yyvsp[(1) - (1)].node), NULL, NULL, (yylsp[(1) - (1)])); ;} break; - case 551: + case 570: #line 596 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSampleOptions((yyvsp[(1) - (4)].node), (yyvsp[(3) - (4)].str), NULL, (yylsp[(1) - (4)])); ;} break; - case 552: + case 571: #line 600 "third_party/libpg_query/grammar/statements/select.y" { int seed = (yyvsp[(5) - (6)].ival); @@ -314842,39 +329282,39 @@ YYLTYPE yylloc; ;} break; - case 553: + case 572: #line 608 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 554: + case 573: #line 614 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 555: + case 574: #line 615 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 556: + case 575: #line 620 "third_party/libpg_query/grammar/statements/select.y" { (yyval.ival) = (yyvsp[(3) - (4)].ival); ;} break; - case 557: + case 576: #line 621 "third_party/libpg_query/grammar/statements/select.y" { (yyval.ival) = -1; ;} break; - case 558: + case 577: #line 625 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 559: + case 578: #line 627 "third_party/libpg_query/grammar/statements/select.y" { /* LIMIT ALL is represented as a NULL constant */ @@ -314882,77 +329322,77 @@ YYLTYPE yylloc; ;} break; - case 560: + case 579: #line 632 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeLimitPercent((yyvsp[(1) - (2)].node)); ;} break; - case 561: + case 580: #line 634 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeLimitPercent(makeFloatConst((yyvsp[(1) - (2)].str),(yylsp[(1) - (2)]))); ;} break; - case 562: + case 581: #line 636 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeLimitPercent(makeIntConst((yyvsp[(1) - (2)].ival),(yylsp[(1) - (2)]))); ;} break; - case 563: + case 582: #line 640 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 564: + case 583: #line 660 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 565: + case 584: #line 662 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "+", NULL, (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 566: + case 585: #line 664 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = doNegate((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 567: + case 586: #line 668 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeIntConst((yyvsp[(1) - (1)].ival),(yylsp[(1) - (1)])); ;} break; - case 568: + case 587: #line 669 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeFloatConst((yyvsp[(1) - (1)].str),(yylsp[(1) - (1)])); ;} break; - case 569: + case 588: #line 673 "third_party/libpg_query/grammar/statements/select.y" { (yyval.ival) = 0; ;} break; - case 570: + case 589: #line 674 "third_party/libpg_query/grammar/statements/select.y" { (yyval.ival) = 0; ;} break; - case 571: + case 590: #line 677 "third_party/libpg_query/grammar/statements/select.y" { (yyval.ival) = 0; ;} break; - case 572: + case 591: #line 678 "third_party/libpg_query/grammar/statements/select.y" { (yyval.ival) = 0; ;} break; - case 573: + case 592: #line 703 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (3)].list); ;} break; - case 574: + case 593: #line 705 "third_party/libpg_query/grammar/statements/select.y" { PGNode *node = (PGNode *) makeGroupingSet(GROUPING_SET_ALL, NIL, (yylsp[(3) - (3)])); @@ -314960,7 +329400,7 @@ YYLTYPE yylloc; ;} break; - case 575: + case 594: #line 710 "third_party/libpg_query/grammar/statements/select.y" { PGNode *node = (PGNode *) makeGroupingSet(GROUPING_SET_ALL, NIL, (yylsp[(3) - (3)])); @@ -314968,145 +329408,145 @@ YYLTYPE yylloc; ;} break; - case 576: + case 595: #line 714 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 577: + case 596: #line 718 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 578: + case 597: #line 719 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list),(yyvsp[(3) - (3)].node)); ;} break; - case 579: + case 598: #line 723 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 580: + case 599: #line 724 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; - case 581: + case 600: #line 728 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 582: + case 601: #line 729 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 583: + case 602: #line 730 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 584: + case 603: #line 731 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 585: + case 604: #line 732 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 586: + case 605: #line 737 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeGroupingSet(GROUPING_SET_EMPTY, NIL, (yylsp[(1) - (2)])); ;} break; - case 587: + case 606: #line 750 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeGroupingSet(GROUPING_SET_ROLLUP, (yyvsp[(3) - (4)].list), (yylsp[(1) - (4)])); ;} break; - case 588: + case 607: #line 757 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeGroupingSet(GROUPING_SET_CUBE, (yyvsp[(3) - (4)].list), (yylsp[(1) - (4)])); ;} break; - case 589: + case 608: #line 764 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeGroupingSet(GROUPING_SET_SETS, (yyvsp[(4) - (5)].list), (yylsp[(1) - (5)])); ;} break; - case 590: + case 609: #line 770 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 591: + case 610: #line 771 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 592: + case 611: #line 775 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 593: + case 612: #line 776 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 594: + case 613: #line 780 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 595: + case 614: #line 781 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 596: + case 615: #line 785 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 597: + case 616: #line 786 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 598: + case 617: #line 790 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 599: + case 618: #line 791 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 600: + case 619: #line 795 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 601: + case 620: #line 796 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); ;} break; - case 602: + case 621: #line 801 "third_party/libpg_query/grammar/statements/select.y" { PGLockingClause *n = makeNode(PGLockingClause); @@ -315117,52 +329557,52 @@ YYLTYPE yylloc; ;} break; - case 603: + case 622: #line 811 "third_party/libpg_query/grammar/statements/select.y" { (yyval.lockstrength) = LCS_FORUPDATE; ;} break; - case 604: + case 623: #line 812 "third_party/libpg_query/grammar/statements/select.y" { (yyval.lockstrength) = PG_LCS_FORNOKEYUPDATE; ;} break; - case 605: + case 624: #line 813 "third_party/libpg_query/grammar/statements/select.y" { (yyval.lockstrength) = PG_LCS_FORSHARE; ;} break; - case 606: + case 625: #line 814 "third_party/libpg_query/grammar/statements/select.y" { (yyval.lockstrength) = PG_LCS_FORKEYSHARE; ;} break; - case 607: + case 626: #line 818 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(2) - (2)].list); ;} break; - case 608: + case 627: #line 819 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 609: + case 628: #line 824 "third_party/libpg_query/grammar/statements/select.y" { (yyval.lockwaitpolicy) = LockWaitError; ;} break; - case 610: + case 629: #line 825 "third_party/libpg_query/grammar/statements/select.y" { (yyval.lockwaitpolicy) = PGLockWaitSkip; ;} break; - case 611: + case 630: #line 826 "third_party/libpg_query/grammar/statements/select.y" { (yyval.lockwaitpolicy) = PGLockWaitBlock; ;} break; - case 612: + case 631: #line 836 "third_party/libpg_query/grammar/statements/select.y" { PGSelectStmt *n = makeNode(PGSelectStmt); @@ -315171,7 +329611,7 @@ YYLTYPE yylloc; ;} break; - case 613: + case 632: #line 842 "third_party/libpg_query/grammar/statements/select.y" { PGSelectStmt *n = (PGSelectStmt *) (yyvsp[(1) - (5)].node); @@ -315180,47 +329620,47 @@ YYLTYPE yylloc; ;} break; - case 614: + case 633: #line 850 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 615: + case 634: #line 851 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (2)].node); ;} break; - case 616: + case 635: #line 864 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(2) - (2)].list); ;} break; - case 617: + case 636: #line 865 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 618: + case 637: #line 869 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 619: + case 638: #line 870 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 620: + case 639: #line 874 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 621: + case 640: #line 875 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; - case 622: + case 641: #line 882 "third_party/libpg_query/grammar/statements/select.y" { (yyvsp[(1) - (3)].range)->alias = (yyvsp[(2) - (3)].alias); @@ -315229,7 +329669,7 @@ YYLTYPE yylloc; ;} break; - case 623: + case 642: #line 888 "third_party/libpg_query/grammar/statements/select.y" { PGRangeFunction *n = (PGRangeFunction *) (yyvsp[(1) - (3)].node); @@ -315240,7 +329680,7 @@ YYLTYPE yylloc; ;} break; - case 624: + case 643: #line 896 "third_party/libpg_query/grammar/statements/select.y" { PGRangeSubselect *n = makeNode(PGRangeSubselect); @@ -315252,7 +329692,7 @@ YYLTYPE yylloc; ;} break; - case 625: + case 644: #line 905 "third_party/libpg_query/grammar/statements/select.y" { PGRangeFunction *n = (PGRangeFunction *) (yyvsp[(2) - (3)].node); @@ -315263,7 +329703,7 @@ YYLTYPE yylloc; ;} break; - case 626: + case 645: #line 913 "third_party/libpg_query/grammar/statements/select.y" { PGRangeSubselect *n = makeNode(PGRangeSubselect); @@ -315275,7 +329715,7 @@ YYLTYPE yylloc; ;} break; - case 627: + case 646: #line 922 "third_party/libpg_query/grammar/statements/select.y" { PGRangeSubselect *n = makeNode(PGRangeSubselect); @@ -315287,14 +329727,14 @@ YYLTYPE yylloc; ;} break; - case 628: + case 647: #line 931 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) (yyvsp[(1) - (1)].jexpr); ;} break; - case 629: + case 648: #line 935 "third_party/libpg_query/grammar/statements/select.y" { (yyvsp[(2) - (4)].jexpr)->alias = (yyvsp[(4) - (4)].alias); @@ -315302,15 +329742,15 @@ YYLTYPE yylloc; ;} break; - case 630: -#line 961 "third_party/libpg_query/grammar/statements/select.y" + case 649: +#line 962 "third_party/libpg_query/grammar/statements/select.y" { (yyval.jexpr) = (yyvsp[(2) - (3)].jexpr); ;} break; - case 631: -#line 965 "third_party/libpg_query/grammar/statements/select.y" + case 650: +#line 966 "third_party/libpg_query/grammar/statements/select.y" { /* CROSS JOIN is same as unqualified inner join */ PGJoinExpr *n = makeNode(PGJoinExpr); @@ -315325,8 +329765,8 @@ YYLTYPE yylloc; ;} break; - case 632: -#line 978 "third_party/libpg_query/grammar/statements/select.y" + case 651: +#line 979 "third_party/libpg_query/grammar/statements/select.y" { PGJoinExpr *n = makeNode(PGJoinExpr); n->jointype = (yyvsp[(2) - (5)].jtype); @@ -315342,8 +329782,8 @@ YYLTYPE yylloc; ;} break; - case 633: -#line 992 "third_party/libpg_query/grammar/statements/select.y" + case 652: +#line 993 "third_party/libpg_query/grammar/statements/select.y" { /* letting join_type reduce to empty doesn't work */ PGJoinExpr *n = makeNode(PGJoinExpr); @@ -315360,8 +329800,8 @@ YYLTYPE yylloc; ;} break; - case 634: -#line 1007 "third_party/libpg_query/grammar/statements/select.y" + case 653: +#line 1008 "third_party/libpg_query/grammar/statements/select.y" { PGJoinExpr *n = makeNode(PGJoinExpr); n->jointype = (yyvsp[(3) - (5)].jtype); @@ -315375,8 +329815,8 @@ YYLTYPE yylloc; ;} break; - case 635: -#line 1019 "third_party/libpg_query/grammar/statements/select.y" + case 654: +#line 1020 "third_party/libpg_query/grammar/statements/select.y" { /* letting join_type reduce to empty doesn't work */ PGJoinExpr *n = makeNode(PGJoinExpr); @@ -315391,8 +329831,24 @@ YYLTYPE yylloc; ;} break; - case 636: -#line 1035 "third_party/libpg_query/grammar/statements/select.y" + case 655: +#line 1033 "third_party/libpg_query/grammar/statements/select.y" + { + /* POSITIONAL JOIN is a coordinated scan */ + PGJoinExpr *n = makeNode(PGJoinExpr); + n->jointype = PG_JOIN_POSITION; + n->isNatural = false; + n->larg = (yyvsp[(1) - (4)].node); + n->rarg = (yyvsp[(4) - (4)].node); + n->usingClause = NIL; + n->quals = NULL; + n->location = (yylsp[(2) - (4)]); + (yyval.jexpr) = n; + ;} + break; + + case 656: +#line 1049 "third_party/libpg_query/grammar/statements/select.y" { (yyval.alias) = makeNode(PGAlias); (yyval.alias)->aliasname = (yyvsp[(2) - (5)].str); @@ -315400,16 +329856,16 @@ YYLTYPE yylloc; ;} break; - case 637: -#line 1041 "third_party/libpg_query/grammar/statements/select.y" + case 657: +#line 1055 "third_party/libpg_query/grammar/statements/select.y" { (yyval.alias) = makeNode(PGAlias); (yyval.alias)->aliasname = (yyvsp[(2) - (2)].str); ;} break; - case 638: -#line 1046 "third_party/libpg_query/grammar/statements/select.y" + case 658: +#line 1060 "third_party/libpg_query/grammar/statements/select.y" { (yyval.alias) = makeNode(PGAlias); (yyval.alias)->aliasname = (yyvsp[(1) - (4)].str); @@ -315417,40 +329873,40 @@ YYLTYPE yylloc; ;} break; - case 639: -#line 1052 "third_party/libpg_query/grammar/statements/select.y" + case 659: +#line 1066 "third_party/libpg_query/grammar/statements/select.y" { (yyval.alias) = makeNode(PGAlias); (yyval.alias)->aliasname = (yyvsp[(1) - (1)].str); ;} break; - case 640: -#line 1058 "third_party/libpg_query/grammar/statements/select.y" + case 660: +#line 1072 "third_party/libpg_query/grammar/statements/select.y" { (yyval.alias) = (yyvsp[(1) - (1)].alias); ;} break; - case 641: -#line 1059 "third_party/libpg_query/grammar/statements/select.y" + case 661: +#line 1073 "third_party/libpg_query/grammar/statements/select.y" { (yyval.alias) = NULL; ;} break; - case 642: -#line 1068 "third_party/libpg_query/grammar/statements/select.y" + case 662: +#line 1082 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(1) - (1)].alias), NIL); ;} break; - case 643: -#line 1072 "third_party/libpg_query/grammar/statements/select.y" + case 663: +#line 1086 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2(NULL, (yyvsp[(3) - (4)].list)); ;} break; - case 644: -#line 1076 "third_party/libpg_query/grammar/statements/select.y" + case 664: +#line 1090 "third_party/libpg_query/grammar/statements/select.y" { PGAlias *a = makeNode(PGAlias); a->aliasname = (yyvsp[(2) - (5)].str); @@ -315458,8 +329914,8 @@ YYLTYPE yylloc; ;} break; - case 645: -#line 1082 "third_party/libpg_query/grammar/statements/select.y" + case 665: +#line 1096 "third_party/libpg_query/grammar/statements/select.y" { PGAlias *a = makeNode(PGAlias); a->aliasname = (yyvsp[(1) - (4)].str); @@ -315467,55 +329923,55 @@ YYLTYPE yylloc; ;} break; - case 646: -#line 1088 "third_party/libpg_query/grammar/statements/select.y" + case 666: +#line 1102 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2(NULL, NIL); ;} break; - case 647: -#line 1093 "third_party/libpg_query/grammar/statements/select.y" + case 667: +#line 1107 "third_party/libpg_query/grammar/statements/select.y" { (yyval.jtype) = PG_JOIN_FULL; ;} break; - case 648: -#line 1094 "third_party/libpg_query/grammar/statements/select.y" + case 668: +#line 1108 "third_party/libpg_query/grammar/statements/select.y" { (yyval.jtype) = PG_JOIN_LEFT; ;} break; - case 649: -#line 1095 "third_party/libpg_query/grammar/statements/select.y" + case 669: +#line 1109 "third_party/libpg_query/grammar/statements/select.y" { (yyval.jtype) = PG_JOIN_RIGHT; ;} break; - case 650: -#line 1096 "third_party/libpg_query/grammar/statements/select.y" + case 670: +#line 1110 "third_party/libpg_query/grammar/statements/select.y" { (yyval.jtype) = PG_JOIN_INNER; ;} break; - case 651: -#line 1100 "third_party/libpg_query/grammar/statements/select.y" + case 671: +#line 1114 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 652: -#line 1101 "third_party/libpg_query/grammar/statements/select.y" + case 672: +#line 1115 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 653: -#line 1113 "third_party/libpg_query/grammar/statements/select.y" + case 673: +#line 1127 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) (yyvsp[(3) - (4)].list); ;} break; - case 654: -#line 1114 "third_party/libpg_query/grammar/statements/select.y" + case 674: +#line 1128 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 655: -#line 1120 "third_party/libpg_query/grammar/statements/select.y" + case 675: +#line 1134 "third_party/libpg_query/grammar/statements/select.y" { /* inheritance query, implicitly */ (yyval.range) = (yyvsp[(1) - (1)].range); @@ -315524,8 +329980,8 @@ YYLTYPE yylloc; ;} break; - case 656: -#line 1127 "third_party/libpg_query/grammar/statements/select.y" + case 676: +#line 1141 "third_party/libpg_query/grammar/statements/select.y" { /* inheritance query, explicitly */ (yyval.range) = (yyvsp[(1) - (2)].range); @@ -315534,8 +329990,8 @@ YYLTYPE yylloc; ;} break; - case 657: -#line 1134 "third_party/libpg_query/grammar/statements/select.y" + case 677: +#line 1148 "third_party/libpg_query/grammar/statements/select.y" { /* no inheritance */ (yyval.range) = (yyvsp[(2) - (2)].range); @@ -315544,8 +330000,8 @@ YYLTYPE yylloc; ;} break; - case 658: -#line 1141 "third_party/libpg_query/grammar/statements/select.y" + case 678: +#line 1155 "third_party/libpg_query/grammar/statements/select.y" { /* no inheritance, SQL99-style syntax */ (yyval.range) = (yyvsp[(3) - (4)].range); @@ -315554,8 +330010,8 @@ YYLTYPE yylloc; ;} break; - case 659: -#line 1173 "third_party/libpg_query/grammar/statements/select.y" + case 679: +#line 1187 "third_party/libpg_query/grammar/statements/select.y" { PGRangeFunction *n = makeNode(PGRangeFunction); n->lateral = false; @@ -315568,8 +330024,8 @@ YYLTYPE yylloc; ;} break; - case 660: -#line 1184 "third_party/libpg_query/grammar/statements/select.y" + case 680: +#line 1198 "third_party/libpg_query/grammar/statements/select.y" { PGRangeFunction *n = makeNode(PGRangeFunction); n->lateral = false; @@ -315582,67 +330038,67 @@ YYLTYPE yylloc; ;} break; - case 661: -#line 1197 "third_party/libpg_query/grammar/statements/select.y" + case 681: +#line 1211 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].list)); ;} break; - case 662: -#line 1201 "third_party/libpg_query/grammar/statements/select.y" + case 682: +#line 1215 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].list)); ;} break; - case 663: -#line 1202 "third_party/libpg_query/grammar/statements/select.y" + case 683: +#line 1216 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); ;} break; - case 664: -#line 1205 "third_party/libpg_query/grammar/statements/select.y" + case 684: +#line 1219 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 665: -#line 1206 "third_party/libpg_query/grammar/statements/select.y" + case 685: +#line 1220 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 666: -#line 1209 "third_party/libpg_query/grammar/statements/select.y" + case 686: +#line 1223 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = true; ;} break; - case 667: -#line 1210 "third_party/libpg_query/grammar/statements/select.y" + case 687: +#line 1224 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = false; ;} break; - case 668: -#line 1215 "third_party/libpg_query/grammar/statements/select.y" + case 688: +#line 1229 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 669: -#line 1216 "third_party/libpg_query/grammar/statements/select.y" + case 689: +#line 1230 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 670: -#line 1222 "third_party/libpg_query/grammar/statements/select.y" + case 690: +#line 1236 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 671: -#line 1226 "third_party/libpg_query/grammar/statements/select.y" + case 691: +#line 1240 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 672: -#line 1232 "third_party/libpg_query/grammar/statements/select.y" + case 692: +#line 1246 "third_party/libpg_query/grammar/statements/select.y" { PGColumnDef *n = makeNode(PGColumnDef); n->colname = (yyvsp[(1) - (3)].str); @@ -315662,8 +330118,8 @@ YYLTYPE yylloc; ;} break; - case 673: -#line 1253 "third_party/libpg_query/grammar/statements/select.y" + case 693: +#line 1267 "third_party/libpg_query/grammar/statements/select.y" { PGCollateClause *n = makeNode(PGCollateClause); n->arg = NULL; @@ -315673,45 +330129,45 @@ YYLTYPE yylloc; ;} break; - case 674: -#line 1260 "third_party/libpg_query/grammar/statements/select.y" + case 694: +#line 1274 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 675: -#line 1273 "third_party/libpg_query/grammar/statements/select.y" + case 695: +#line 1287 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(list_make2(makeString((yyvsp[(1) - (2)].str)), (yyvsp[(2) - (2)].typnam))); ;} break; - case 676: -#line 1276 "third_party/libpg_query/grammar/statements/select.y" + case 696: +#line 1290 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (4)].list), list_make2(makeString((yyvsp[(3) - (4)].str)), (yyvsp[(4) - (4)].typnam))); ;} break; - case 679: -#line 1283 "third_party/libpg_query/grammar/statements/select.y" + case 699: +#line 1297 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 680: -#line 1284 "third_party/libpg_query/grammar/statements/select.y" + case 700: +#line 1298 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = NULL; ;} break; - case 681: -#line 1287 "third_party/libpg_query/grammar/statements/select.y" + case 701: +#line 1301 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (2)].typnam); (yyval.typnam)->arrayBounds = (yyvsp[(2) - (2)].list); ;} break; - case 682: -#line 1292 "third_party/libpg_query/grammar/statements/select.y" + case 702: +#line 1306 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(2) - (3)].typnam); (yyval.typnam)->arrayBounds = (yyvsp[(3) - (3)].list); @@ -315719,16 +330175,16 @@ YYLTYPE yylloc; ;} break; - case 683: -#line 1299 "third_party/libpg_query/grammar/statements/select.y" + case 703: +#line 1313 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (5)].typnam); (yyval.typnam)->arrayBounds = list_make1(makeInteger((yyvsp[(4) - (5)].ival))); ;} break; - case 684: -#line 1304 "third_party/libpg_query/grammar/statements/select.y" + case 704: +#line 1318 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(2) - (6)].typnam); (yyval.typnam)->arrayBounds = list_make1(makeInteger((yyvsp[(5) - (6)].ival))); @@ -315736,16 +330192,16 @@ YYLTYPE yylloc; ;} break; - case 685: -#line 1310 "third_party/libpg_query/grammar/statements/select.y" + case 705: +#line 1324 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (2)].typnam); (yyval.typnam)->arrayBounds = list_make1(makeInteger(-1)); ;} break; - case 686: -#line 1315 "third_party/libpg_query/grammar/statements/select.y" + case 706: +#line 1329 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(2) - (3)].typnam); (yyval.typnam)->arrayBounds = list_make1(makeInteger(-1)); @@ -315753,8 +330209,8 @@ YYLTYPE yylloc; ;} break; - case 687: -#line 1320 "third_party/libpg_query/grammar/statements/select.y" + case 707: +#line 1334 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("struct"); (yyval.typnam)->arrayBounds = (yyvsp[(5) - (5)].list); @@ -315763,8 +330219,8 @@ YYLTYPE yylloc; ;} break; - case 688: -#line 1326 "third_party/libpg_query/grammar/statements/select.y" + case 708: +#line 1340 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("map"); (yyval.typnam)->arrayBounds = (yyvsp[(5) - (5)].list); @@ -315773,8 +330229,8 @@ YYLTYPE yylloc; ;} break; - case 689: -#line 1332 "third_party/libpg_query/grammar/statements/select.y" + case 709: +#line 1346 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("union"); (yyval.typnam)->arrayBounds = (yyvsp[(5) - (5)].list); @@ -315783,56 +330239,56 @@ YYLTYPE yylloc; ;} break; - case 690: -#line 1342 "third_party/libpg_query/grammar/statements/select.y" + case 710: +#line 1356 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), makeInteger(-1)); ;} break; - case 691: -#line 1344 "third_party/libpg_query/grammar/statements/select.y" + case 711: +#line 1358 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (4)].list), makeInteger((yyvsp[(3) - (4)].ival))); ;} break; - case 692: -#line 1346 "third_party/libpg_query/grammar/statements/select.y" + case 712: +#line 1360 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 693: -#line 1350 "third_party/libpg_query/grammar/statements/select.y" + case 713: +#line 1364 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 694: -#line 1351 "third_party/libpg_query/grammar/statements/select.y" + case 714: +#line 1365 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 695: -#line 1352 "third_party/libpg_query/grammar/statements/select.y" + case 715: +#line 1366 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 696: -#line 1353 "third_party/libpg_query/grammar/statements/select.y" + case 716: +#line 1367 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 697: -#line 1354 "third_party/libpg_query/grammar/statements/select.y" + case 717: +#line 1368 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 698: -#line 1356 "third_party/libpg_query/grammar/statements/select.y" + case 718: +#line 1370 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (2)].typnam); (yyval.typnam)->typmods = (yyvsp[(2) - (2)].list); ;} break; - case 699: -#line 1361 "third_party/libpg_query/grammar/statements/select.y" + case 719: +#line 1375 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (4)].typnam); (yyval.typnam)->typmods = list_make2(makeIntConst(INTERVAL_FULL_RANGE, -1), @@ -315840,28 +330296,28 @@ YYLTYPE yylloc; ;} break; - case 700: -#line 1380 "third_party/libpg_query/grammar/statements/select.y" + case 720: +#line 1394 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 701: -#line 1381 "third_party/libpg_query/grammar/statements/select.y" + case 721: +#line 1395 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 702: -#line 1382 "third_party/libpg_query/grammar/statements/select.y" + case 722: +#line 1396 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 703: -#line 1383 "third_party/libpg_query/grammar/statements/select.y" + case 723: +#line 1397 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 704: -#line 1395 "third_party/libpg_query/grammar/statements/select.y" + case 724: +#line 1409 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = makeTypeName((yyvsp[(1) - (2)].str)); (yyval.typnam)->typmods = (yyvsp[(2) - (2)].list); @@ -315869,74 +330325,74 @@ YYLTYPE yylloc; ;} break; - case 705: -#line 1408 "third_party/libpg_query/grammar/statements/select.y" + case 725: +#line 1422 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(2) - (3)].list); ;} break; - case 706: -#line 1409 "third_party/libpg_query/grammar/statements/select.y" + case 726: +#line 1423 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 707: -#line 1416 "third_party/libpg_query/grammar/statements/select.y" + case 727: +#line 1430 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("int4"); (yyval.typnam)->location = (yylsp[(1) - (1)]); ;} break; - case 708: -#line 1421 "third_party/libpg_query/grammar/statements/select.y" + case 728: +#line 1435 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("int4"); (yyval.typnam)->location = (yylsp[(1) - (1)]); ;} break; - case 709: -#line 1426 "third_party/libpg_query/grammar/statements/select.y" + case 729: +#line 1440 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("int2"); (yyval.typnam)->location = (yylsp[(1) - (1)]); ;} break; - case 710: -#line 1431 "third_party/libpg_query/grammar/statements/select.y" + case 730: +#line 1445 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("int8"); (yyval.typnam)->location = (yylsp[(1) - (1)]); ;} break; - case 711: -#line 1436 "third_party/libpg_query/grammar/statements/select.y" + case 731: +#line 1450 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("float4"); (yyval.typnam)->location = (yylsp[(1) - (1)]); ;} break; - case 712: -#line 1441 "third_party/libpg_query/grammar/statements/select.y" + case 732: +#line 1455 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(2) - (2)].typnam); (yyval.typnam)->location = (yylsp[(1) - (2)]); ;} break; - case 713: -#line 1446 "third_party/libpg_query/grammar/statements/select.y" + case 733: +#line 1460 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("float8"); (yyval.typnam)->location = (yylsp[(1) - (2)]); ;} break; - case 714: -#line 1451 "third_party/libpg_query/grammar/statements/select.y" + case 734: +#line 1465 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("numeric"); (yyval.typnam)->typmods = (yyvsp[(2) - (2)].list); @@ -315944,8 +330400,8 @@ YYLTYPE yylloc; ;} break; - case 715: -#line 1457 "third_party/libpg_query/grammar/statements/select.y" + case 735: +#line 1471 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("numeric"); (yyval.typnam)->typmods = (yyvsp[(2) - (2)].list); @@ -315953,8 +330409,8 @@ YYLTYPE yylloc; ;} break; - case 716: -#line 1463 "third_party/libpg_query/grammar/statements/select.y" + case 736: +#line 1477 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("numeric"); (yyval.typnam)->typmods = (yyvsp[(2) - (2)].list); @@ -315962,16 +330418,16 @@ YYLTYPE yylloc; ;} break; - case 717: -#line 1469 "third_party/libpg_query/grammar/statements/select.y" + case 737: +#line 1483 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("bool"); (yyval.typnam)->location = (yylsp[(1) - (1)]); ;} break; - case 718: -#line 1476 "third_party/libpg_query/grammar/statements/select.y" + case 738: +#line 1490 "third_party/libpg_query/grammar/statements/select.y" { /* * Check FLOAT() precision limits assuming IEEE floating @@ -315994,44 +330450,44 @@ YYLTYPE yylloc; ;} break; - case 719: -#line 1497 "third_party/libpg_query/grammar/statements/select.y" + case 739: +#line 1511 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("float4"); ;} break; - case 720: -#line 1507 "third_party/libpg_query/grammar/statements/select.y" + case 740: +#line 1521 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 721: -#line 1511 "third_party/libpg_query/grammar/statements/select.y" + case 741: +#line 1525 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 722: -#line 1519 "third_party/libpg_query/grammar/statements/select.y" + case 742: +#line 1533 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 723: -#line 1523 "third_party/libpg_query/grammar/statements/select.y" + case 743: +#line 1537 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); (yyval.typnam)->typmods = NIL; ;} break; - case 724: -#line 1531 "third_party/libpg_query/grammar/statements/select.y" + case 744: +#line 1545 "third_party/libpg_query/grammar/statements/select.y" { const char *typname; @@ -316042,8 +330498,8 @@ YYLTYPE yylloc; ;} break; - case 725: -#line 1543 "third_party/libpg_query/grammar/statements/select.y" + case 745: +#line 1557 "third_party/libpg_query/grammar/statements/select.y" { /* bit defaults to bit(1), varbit to no limit */ if ((yyvsp[(2) - (2)].boolean)) @@ -316059,29 +330515,29 @@ YYLTYPE yylloc; ;} break; - case 726: -#line 1564 "third_party/libpg_query/grammar/statements/select.y" + case 746: +#line 1578 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 727: -#line 1568 "third_party/libpg_query/grammar/statements/select.y" + case 747: +#line 1582 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 728: -#line 1574 "third_party/libpg_query/grammar/statements/select.y" + case 748: +#line 1588 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = (yyvsp[(1) - (1)].typnam); ;} break; - case 729: -#line 1578 "third_party/libpg_query/grammar/statements/select.y" + case 749: +#line 1592 "third_party/libpg_query/grammar/statements/select.y" { /* Length was not specified so allow to be unrestricted. * This handles problems with fixed-length (bpchar) strings @@ -316094,8 +330550,8 @@ YYLTYPE yylloc; ;} break; - case 730: -#line 1591 "third_party/libpg_query/grammar/statements/select.y" + case 750: +#line 1605 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName((yyvsp[(1) - (4)].conststr)); (yyval.typnam)->typmods = list_make1(makeIntConst((yyvsp[(3) - (4)].ival), (yylsp[(3) - (4)]))); @@ -316103,8 +330559,8 @@ YYLTYPE yylloc; ;} break; - case 731: -#line 1599 "third_party/libpg_query/grammar/statements/select.y" + case 751: +#line 1613 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName((yyvsp[(1) - (1)].conststr)); /* char defaults to char(1), varchar to no limit */ @@ -316114,48 +330570,48 @@ YYLTYPE yylloc; ;} break; - case 732: -#line 1609 "third_party/libpg_query/grammar/statements/select.y" + case 752: +#line 1623 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = (yyvsp[(2) - (2)].boolean) ? "varchar": "bpchar"; ;} break; - case 733: -#line 1611 "third_party/libpg_query/grammar/statements/select.y" + case 753: +#line 1625 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = (yyvsp[(2) - (2)].boolean) ? "varchar": "bpchar"; ;} break; - case 734: -#line 1613 "third_party/libpg_query/grammar/statements/select.y" + case 754: +#line 1627 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "varchar"; ;} break; - case 735: -#line 1615 "third_party/libpg_query/grammar/statements/select.y" + case 755: +#line 1629 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = (yyvsp[(3) - (3)].boolean) ? "varchar": "bpchar"; ;} break; - case 736: -#line 1617 "third_party/libpg_query/grammar/statements/select.y" + case 756: +#line 1631 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = (yyvsp[(3) - (3)].boolean) ? "varchar": "bpchar"; ;} break; - case 737: -#line 1619 "third_party/libpg_query/grammar/statements/select.y" + case 757: +#line 1633 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = (yyvsp[(2) - (2)].boolean) ? "varchar": "bpchar"; ;} break; - case 738: -#line 1623 "third_party/libpg_query/grammar/statements/select.y" + case 758: +#line 1637 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = true; ;} break; - case 739: -#line 1624 "third_party/libpg_query/grammar/statements/select.y" + case 759: +#line 1638 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = false; ;} break; - case 740: -#line 1632 "third_party/libpg_query/grammar/statements/select.y" + case 760: +#line 1646 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(5) - (5)].boolean)) (yyval.typnam) = SystemTypeName("timestamptz"); @@ -316166,8 +330622,8 @@ YYLTYPE yylloc; ;} break; - case 741: -#line 1641 "third_party/libpg_query/grammar/statements/select.y" + case 761: +#line 1655 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(2) - (2)].boolean)) (yyval.typnam) = SystemTypeName("timestamptz"); @@ -316177,8 +330633,8 @@ YYLTYPE yylloc; ;} break; - case 742: -#line 1649 "third_party/libpg_query/grammar/statements/select.y" + case 762: +#line 1663 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(5) - (5)].boolean)) (yyval.typnam) = SystemTypeName("timetz"); @@ -316189,8 +330645,8 @@ YYLTYPE yylloc; ;} break; - case 743: -#line 1658 "third_party/libpg_query/grammar/statements/select.y" + case 763: +#line 1672 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(2) - (2)].boolean)) (yyval.typnam) = SystemTypeName("timetz"); @@ -316200,87 +330656,87 @@ YYLTYPE yylloc; ;} break; - case 744: -#line 1669 "third_party/libpg_query/grammar/statements/select.y" + case 764: +#line 1683 "third_party/libpg_query/grammar/statements/select.y" { (yyval.typnam) = SystemTypeName("interval"); (yyval.typnam)->location = (yylsp[(1) - (1)]); ;} break; - case 745: -#line 1676 "third_party/libpg_query/grammar/statements/select.y" + case 765: +#line 1690 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = true; ;} break; - case 746: -#line 1677 "third_party/libpg_query/grammar/statements/select.y" + case 766: +#line 1691 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = false; ;} break; - case 747: -#line 1678 "third_party/libpg_query/grammar/statements/select.y" + case 767: +#line 1692 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = false; ;} break; - case 764: -#line 1707 "third_party/libpg_query/grammar/statements/select.y" + case 784: +#line 1721 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(YEAR), (yylsp[(1) - (1)]))); ;} break; - case 765: -#line 1709 "third_party/libpg_query/grammar/statements/select.y" + case 785: +#line 1723 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MONTH), (yylsp[(1) - (1)]))); ;} break; - case 766: -#line 1711 "third_party/libpg_query/grammar/statements/select.y" + case 786: +#line 1725 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY), (yylsp[(1) - (1)]))); ;} break; - case 767: -#line 1713 "third_party/libpg_query/grammar/statements/select.y" + case 787: +#line 1727 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(HOUR), (yylsp[(1) - (1)]))); ;} break; - case 768: -#line 1715 "third_party/libpg_query/grammar/statements/select.y" + case 788: +#line 1729 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MINUTE), (yylsp[(1) - (1)]))); ;} break; - case 769: -#line 1717 "third_party/libpg_query/grammar/statements/select.y" + case 789: +#line 1731 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(SECOND), (yylsp[(1) - (1)]))); ;} break; - case 770: -#line 1719 "third_party/libpg_query/grammar/statements/select.y" + case 790: +#line 1733 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MILLISECOND), (yylsp[(1) - (1)]))); ;} break; - case 771: -#line 1721 "third_party/libpg_query/grammar/statements/select.y" + case 791: +#line 1735 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MICROSECOND), (yylsp[(1) - (1)]))); ;} break; - case 772: -#line 1723 "third_party/libpg_query/grammar/statements/select.y" + case 792: +#line 1737 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(YEAR) | INTERVAL_MASK(MONTH), (yylsp[(1) - (3)]))); ;} break; - case 773: -#line 1728 "third_party/libpg_query/grammar/statements/select.y" + case 793: +#line 1742 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR), (yylsp[(1) - (3)]))); ;} break; - case 774: -#line 1733 "third_party/libpg_query/grammar/statements/select.y" + case 794: +#line 1747 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) | @@ -316288,8 +330744,8 @@ YYLTYPE yylloc; ;} break; - case 775: -#line 1739 "third_party/libpg_query/grammar/statements/select.y" + case 795: +#line 1753 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(DAY) | INTERVAL_MASK(HOUR) | @@ -316298,16 +330754,16 @@ YYLTYPE yylloc; ;} break; - case 776: -#line 1746 "third_party/libpg_query/grammar/statements/select.y" + case 796: +#line 1760 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE), (yylsp[(1) - (3)]))); ;} break; - case 777: -#line 1751 "third_party/libpg_query/grammar/statements/select.y" + case 797: +#line 1765 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(HOUR) | INTERVAL_MASK(MINUTE) | @@ -316315,31 +330771,31 @@ YYLTYPE yylloc; ;} break; - case 778: -#line 1757 "third_party/libpg_query/grammar/statements/select.y" + case 798: +#line 1771 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeIntConst(INTERVAL_MASK(MINUTE) | INTERVAL_MASK(SECOND), (yylsp[(1) - (3)]))); ;} break; - case 779: -#line 1762 "third_party/libpg_query/grammar/statements/select.y" + case 799: +#line 1776 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 780: -#line 1793 "third_party/libpg_query/grammar/statements/select.y" + case 800: +#line 1807 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 781: -#line 1796 "third_party/libpg_query/grammar/statements/select.y" + case 801: +#line 1810 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeTypeCast((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].typnam), 0, (yylsp[(2) - (3)])); ;} break; - case 782: -#line 1798 "third_party/libpg_query/grammar/statements/select.y" + case 802: +#line 1812 "third_party/libpg_query/grammar/statements/select.y" { PGCollateClause *n = makeNode(PGCollateClause); n->arg = (yyvsp[(1) - (3)].node); @@ -316349,8 +330805,8 @@ YYLTYPE yylloc; ;} break; - case 783: -#line 1806 "third_party/libpg_query/grammar/statements/select.y" + case 803: +#line 1820 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("timezone"), list_make2((yyvsp[(5) - (5)].node), (yyvsp[(1) - (5)].node)), @@ -316358,134 +330814,134 @@ YYLTYPE yylloc; ;} break; - case 784: -#line 1821 "third_party/libpg_query/grammar/statements/select.y" + case 804: +#line 1835 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "+", NULL, (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 785: -#line 1823 "third_party/libpg_query/grammar/statements/select.y" + case 805: +#line 1837 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = doNegate((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 786: -#line 1825 "third_party/libpg_query/grammar/statements/select.y" + case 806: +#line 1839 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "+", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 787: -#line 1827 "third_party/libpg_query/grammar/statements/select.y" + case 807: +#line 1841 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "-", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 788: -#line 1829 "third_party/libpg_query/grammar/statements/select.y" + case 808: +#line 1843 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "*", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 789: -#line 1831 "third_party/libpg_query/grammar/statements/select.y" + case 809: +#line 1845 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "/", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 790: -#line 1833 "third_party/libpg_query/grammar/statements/select.y" + case 810: +#line 1847 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "%", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 791: -#line 1835 "third_party/libpg_query/grammar/statements/select.y" + case 811: +#line 1849 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "^", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 792: -#line 1837 "third_party/libpg_query/grammar/statements/select.y" + case 812: +#line 1851 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "**", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 793: -#line 1839 "third_party/libpg_query/grammar/statements/select.y" + case 813: +#line 1853 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "<", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 794: -#line 1841 "third_party/libpg_query/grammar/statements/select.y" + case 814: +#line 1855 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, ">", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 795: -#line 1843 "third_party/libpg_query/grammar/statements/select.y" + case 815: +#line 1857 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "=", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 796: -#line 1845 "third_party/libpg_query/grammar/statements/select.y" + case 816: +#line 1859 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "<=", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 797: -#line 1847 "third_party/libpg_query/grammar/statements/select.y" + case 817: +#line 1861 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, ">=", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 798: -#line 1849 "third_party/libpg_query/grammar/statements/select.y" + case 818: +#line 1863 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "<>", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 799: -#line 1852 "third_party/libpg_query/grammar/statements/select.y" + case 819: +#line 1866 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeAExpr(PG_AEXPR_OP, (yyvsp[(2) - (3)].list), (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 800: -#line 1854 "third_party/libpg_query/grammar/statements/select.y" + case 820: +#line 1868 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeAExpr(PG_AEXPR_OP, (yyvsp[(1) - (2)].list), NULL, (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 801: -#line 1856 "third_party/libpg_query/grammar/statements/select.y" + case 821: +#line 1870 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeAExpr(PG_AEXPR_OP, (yyvsp[(2) - (2)].list), (yyvsp[(1) - (2)].node), NULL, (yylsp[(2) - (2)])); ;} break; - case 802: -#line 1859 "third_party/libpg_query/grammar/statements/select.y" + case 822: +#line 1873 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeAndExpr((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 803: -#line 1861 "third_party/libpg_query/grammar/statements/select.y" + case 823: +#line 1875 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeOrExpr((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 804: -#line 1863 "third_party/libpg_query/grammar/statements/select.y" + case 824: +#line 1877 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeNotExpr((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 805: -#line 1865 "third_party/libpg_query/grammar/statements/select.y" + case 825: +#line 1879 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeNotExpr((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 806: -#line 1867 "third_party/libpg_query/grammar/statements/select.y" + case 826: +#line 1881 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_GLOB, "~~~", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 807: -#line 1872 "third_party/libpg_query/grammar/statements/select.y" + case 827: +#line 1886 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_LIKE, "~~", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 808: -#line 1877 "third_party/libpg_query/grammar/statements/select.y" + case 828: +#line 1891 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("like_escape"), list_make3((yyvsp[(1) - (5)].node), (yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].node)), @@ -316494,16 +330950,16 @@ YYLTYPE yylloc; ;} break; - case 809: -#line 1884 "third_party/libpg_query/grammar/statements/select.y" + case 829: +#line 1898 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_LIKE, "!~~", (yyvsp[(1) - (4)].node), (yyvsp[(4) - (4)].node), (yylsp[(2) - (4)])); ;} break; - case 810: -#line 1889 "third_party/libpg_query/grammar/statements/select.y" + case 830: +#line 1903 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("not_like_escape"), list_make3((yyvsp[(1) - (6)].node), (yyvsp[(4) - (6)].node), (yyvsp[(6) - (6)].node)), @@ -316512,16 +330968,16 @@ YYLTYPE yylloc; ;} break; - case 811: -#line 1896 "third_party/libpg_query/grammar/statements/select.y" + case 831: +#line 1910 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_ILIKE, "~~*", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 812: -#line 1901 "third_party/libpg_query/grammar/statements/select.y" + case 832: +#line 1915 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("ilike_escape"), list_make3((yyvsp[(1) - (5)].node), (yyvsp[(3) - (5)].node), (yyvsp[(5) - (5)].node)), @@ -316530,16 +330986,16 @@ YYLTYPE yylloc; ;} break; - case 813: -#line 1908 "third_party/libpg_query/grammar/statements/select.y" + case 833: +#line 1922 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_ILIKE, "!~~*", (yyvsp[(1) - (4)].node), (yyvsp[(4) - (4)].node), (yylsp[(2) - (4)])); ;} break; - case 814: -#line 1913 "third_party/libpg_query/grammar/statements/select.y" + case 834: +#line 1927 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("not_ilike_escape"), list_make3((yyvsp[(1) - (6)].node), (yyvsp[(4) - (6)].node), (yyvsp[(6) - (6)].node)), @@ -316548,8 +331004,8 @@ YYLTYPE yylloc; ;} break; - case 815: -#line 1921 "third_party/libpg_query/grammar/statements/select.y" + case 835: +#line 1935 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), list_make2((yyvsp[(4) - (4)].node), makeNullAConst(-1)), @@ -316559,8 +331015,8 @@ YYLTYPE yylloc; ;} break; - case 816: -#line 1929 "third_party/libpg_query/grammar/statements/select.y" + case 836: +#line 1943 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), list_make2((yyvsp[(4) - (6)].node), (yyvsp[(6) - (6)].node)), @@ -316570,8 +331026,8 @@ YYLTYPE yylloc; ;} break; - case 817: -#line 1937 "third_party/libpg_query/grammar/statements/select.y" + case 837: +#line 1951 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), list_make2((yyvsp[(5) - (5)].node), makeNullAConst(-1)), @@ -316581,8 +331037,8 @@ YYLTYPE yylloc; ;} break; - case 818: -#line 1945 "third_party/libpg_query/grammar/statements/select.y" + case 838: +#line 1959 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("similar_escape"), list_make2((yyvsp[(5) - (7)].node), (yyvsp[(7) - (7)].node)), @@ -316592,8 +331048,8 @@ YYLTYPE yylloc; ;} break; - case 819: -#line 1963 "third_party/libpg_query/grammar/statements/select.y" + case 839: +#line 1977 "third_party/libpg_query/grammar/statements/select.y" { PGNullTest *n = makeNode(PGNullTest); n->arg = (PGExpr *) (yyvsp[(1) - (3)].node); @@ -316603,8 +331059,8 @@ YYLTYPE yylloc; ;} break; - case 820: -#line 1971 "third_party/libpg_query/grammar/statements/select.y" + case 840: +#line 1985 "third_party/libpg_query/grammar/statements/select.y" { PGNullTest *n = makeNode(PGNullTest); n->arg = (PGExpr *) (yyvsp[(1) - (2)].node); @@ -316614,8 +331070,8 @@ YYLTYPE yylloc; ;} break; - case 821: -#line 1979 "third_party/libpg_query/grammar/statements/select.y" + case 841: +#line 1993 "third_party/libpg_query/grammar/statements/select.y" { PGNullTest *n = makeNode(PGNullTest); n->arg = (PGExpr *) (yyvsp[(1) - (4)].node); @@ -316625,8 +331081,8 @@ YYLTYPE yylloc; ;} break; - case 822: -#line 1987 "third_party/libpg_query/grammar/statements/select.y" + case 842: +#line 2001 "third_party/libpg_query/grammar/statements/select.y" { PGNullTest *n = makeNode(PGNullTest); n->arg = (PGExpr *) (yyvsp[(1) - (3)].node); @@ -316636,8 +331092,8 @@ YYLTYPE yylloc; ;} break; - case 823: -#line 1995 "third_party/libpg_query/grammar/statements/select.y" + case 843: +#line 2009 "third_party/libpg_query/grammar/statements/select.y" { PGNullTest *n = makeNode(PGNullTest); n->arg = (PGExpr *) (yyvsp[(1) - (2)].node); @@ -316647,8 +331103,8 @@ YYLTYPE yylloc; ;} break; - case 824: -#line 2003 "third_party/libpg_query/grammar/statements/select.y" + case 844: +#line 2017 "third_party/libpg_query/grammar/statements/select.y" { PGLambdaFunction *n = makeNode(PGLambdaFunction); n->lhs = (yyvsp[(1) - (3)].node); @@ -316658,15 +331114,15 @@ YYLTYPE yylloc; ;} break; - case 825: -#line 2011 "third_party/libpg_query/grammar/statements/select.y" + case 845: +#line 2025 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "->>", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 826: -#line 2015 "third_party/libpg_query/grammar/statements/select.y" + case 846: +#line 2029 "third_party/libpg_query/grammar/statements/select.y" { if (list_length((yyvsp[(1) - (3)].list)) != 2) ereport(ERROR, @@ -316684,8 +331140,8 @@ YYLTYPE yylloc; ;} break; - case 827: -#line 2031 "third_party/libpg_query/grammar/statements/select.y" + case 847: +#line 2045 "third_party/libpg_query/grammar/statements/select.y" { PGBooleanTest *b = makeNode(PGBooleanTest); b->arg = (PGExpr *) (yyvsp[(1) - (3)].node); @@ -316695,8 +331151,8 @@ YYLTYPE yylloc; ;} break; - case 828: -#line 2039 "third_party/libpg_query/grammar/statements/select.y" + case 848: +#line 2053 "third_party/libpg_query/grammar/statements/select.y" { PGBooleanTest *b = makeNode(PGBooleanTest); b->arg = (PGExpr *) (yyvsp[(1) - (4)].node); @@ -316706,8 +331162,8 @@ YYLTYPE yylloc; ;} break; - case 829: -#line 2047 "third_party/libpg_query/grammar/statements/select.y" + case 849: +#line 2061 "third_party/libpg_query/grammar/statements/select.y" { PGBooleanTest *b = makeNode(PGBooleanTest); b->arg = (PGExpr *) (yyvsp[(1) - (3)].node); @@ -316717,8 +331173,8 @@ YYLTYPE yylloc; ;} break; - case 830: -#line 2055 "third_party/libpg_query/grammar/statements/select.y" + case 850: +#line 2069 "third_party/libpg_query/grammar/statements/select.y" { PGBooleanTest *b = makeNode(PGBooleanTest); b->arg = (PGExpr *) (yyvsp[(1) - (4)].node); @@ -316728,8 +331184,8 @@ YYLTYPE yylloc; ;} break; - case 831: -#line 2063 "third_party/libpg_query/grammar/statements/select.y" + case 851: +#line 2077 "third_party/libpg_query/grammar/statements/select.y" { PGBooleanTest *b = makeNode(PGBooleanTest); b->arg = (PGExpr *) (yyvsp[(1) - (3)].node); @@ -316739,8 +331195,8 @@ YYLTYPE yylloc; ;} break; - case 832: -#line 2071 "third_party/libpg_query/grammar/statements/select.y" + case 852: +#line 2085 "third_party/libpg_query/grammar/statements/select.y" { PGBooleanTest *b = makeNode(PGBooleanTest); b->arg = (PGExpr *) (yyvsp[(1) - (4)].node); @@ -316750,36 +331206,36 @@ YYLTYPE yylloc; ;} break; - case 833: -#line 2079 "third_party/libpg_query/grammar/statements/select.y" + case 853: +#line 2093 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_DISTINCT, "=", (yyvsp[(1) - (5)].node), (yyvsp[(5) - (5)].node), (yylsp[(2) - (5)])); ;} break; - case 834: -#line 2083 "third_party/libpg_query/grammar/statements/select.y" + case 854: +#line 2097 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_NOT_DISTINCT, "=", (yyvsp[(1) - (6)].node), (yyvsp[(6) - (6)].node), (yylsp[(2) - (6)])); ;} break; - case 835: -#line 2087 "third_party/libpg_query/grammar/statements/select.y" + case 855: +#line 2101 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OF, "=", (yyvsp[(1) - (6)].node), (PGNode *) (yyvsp[(5) - (6)].list), (yylsp[(2) - (6)])); ;} break; - case 836: -#line 2091 "third_party/libpg_query/grammar/statements/select.y" + case 856: +#line 2105 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OF, "<>", (yyvsp[(1) - (7)].node), (PGNode *) (yyvsp[(6) - (7)].list), (yylsp[(2) - (7)])); ;} break; - case 837: -#line 2095 "third_party/libpg_query/grammar/statements/select.y" + case 857: +#line 2109 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_BETWEEN, "BETWEEN", @@ -316789,8 +331245,8 @@ YYLTYPE yylloc; ;} break; - case 838: -#line 2103 "third_party/libpg_query/grammar/statements/select.y" + case 858: +#line 2117 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_NOT_BETWEEN, "NOT BETWEEN", @@ -316800,8 +331256,8 @@ YYLTYPE yylloc; ;} break; - case 839: -#line 2111 "third_party/libpg_query/grammar/statements/select.y" + case 859: +#line 2125 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_BETWEEN_SYM, "BETWEEN SYMMETRIC", @@ -316811,8 +331267,8 @@ YYLTYPE yylloc; ;} break; - case 840: -#line 2119 "third_party/libpg_query/grammar/statements/select.y" + case 860: +#line 2133 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_NOT_BETWEEN_SYM, "NOT BETWEEN SYMMETRIC", @@ -316822,8 +331278,8 @@ YYLTYPE yylloc; ;} break; - case 841: -#line 2127 "third_party/libpg_query/grammar/statements/select.y" + case 861: +#line 2141 "third_party/libpg_query/grammar/statements/select.y" { /* in_expr returns a PGSubLink or a list of a_exprs */ if (IsA((yyvsp[(3) - (3)].node), PGSubLink)) @@ -316845,8 +331301,8 @@ YYLTYPE yylloc; ;} break; - case 842: -#line 2147 "third_party/libpg_query/grammar/statements/select.y" + case 862: +#line 2161 "third_party/libpg_query/grammar/statements/select.y" { /* in_expr returns a PGSubLink or a list of a_exprs */ if (IsA((yyvsp[(4) - (4)].node), PGSubLink)) @@ -316870,8 +331326,8 @@ YYLTYPE yylloc; ;} break; - case 843: -#line 2169 "third_party/libpg_query/grammar/statements/select.y" + case 863: +#line 2183 "third_party/libpg_query/grammar/statements/select.y" { PGSubLink *n = makeNode(PGSubLink); n->subLinkType = (yyvsp[(3) - (4)].subquerytype); @@ -316884,8 +331340,8 @@ YYLTYPE yylloc; ;} break; - case 844: -#line 2180 "third_party/libpg_query/grammar/statements/select.y" + case 864: +#line 2194 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(3) - (6)].subquerytype) == PG_ANY_SUBLINK) (yyval.node) = (PGNode *) makeAExpr(PG_AEXPR_OP_ANY, (yyvsp[(2) - (6)].list), (yyvsp[(1) - (6)].node), (yyvsp[(5) - (6)].node), (yylsp[(2) - (6)])); @@ -316894,8 +331350,8 @@ YYLTYPE yylloc; ;} break; - case 845: -#line 2187 "third_party/libpg_query/grammar/statements/select.y" + case 865: +#line 2201 "third_party/libpg_query/grammar/statements/select.y" { /* * The SQL spec only allows DEFAULT in "contextually typed @@ -316911,8 +331367,8 @@ YYLTYPE yylloc; ;} break; - case 846: -#line 2201 "third_party/libpg_query/grammar/statements/select.y" + case 866: +#line 2215 "third_party/libpg_query/grammar/statements/select.y" { PGAStar *star = makeNode(PGAStar); star->except_list = (yyvsp[(4) - (6)].list); @@ -316923,8 +331379,8 @@ YYLTYPE yylloc; ;} break; - case 847: -#line 2210 "third_party/libpg_query/grammar/statements/select.y" + case 867: +#line 2224 "third_party/libpg_query/grammar/statements/select.y" { PGAStar *star = makeNode(PGAStar); star->regex = (yyvsp[(3) - (4)].str); @@ -316934,146 +331390,146 @@ YYLTYPE yylloc; ;} break; - case 848: -#line 2229 "third_party/libpg_query/grammar/statements/select.y" + case 868: +#line 2243 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 849: -#line 2231 "third_party/libpg_query/grammar/statements/select.y" + case 869: +#line 2245 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeTypeCast((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].typnam), 0, (yylsp[(2) - (3)])); ;} break; - case 850: -#line 2233 "third_party/libpg_query/grammar/statements/select.y" + case 870: +#line 2247 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "+", NULL, (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 851: -#line 2235 "third_party/libpg_query/grammar/statements/select.y" + case 871: +#line 2249 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = doNegate((yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 852: -#line 2237 "third_party/libpg_query/grammar/statements/select.y" + case 872: +#line 2251 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "+", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 853: -#line 2239 "third_party/libpg_query/grammar/statements/select.y" + case 873: +#line 2253 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "-", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 854: -#line 2241 "third_party/libpg_query/grammar/statements/select.y" + case 874: +#line 2255 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "*", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 855: -#line 2243 "third_party/libpg_query/grammar/statements/select.y" + case 875: +#line 2257 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "/", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 856: -#line 2245 "third_party/libpg_query/grammar/statements/select.y" + case 876: +#line 2259 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "%", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 857: -#line 2247 "third_party/libpg_query/grammar/statements/select.y" + case 877: +#line 2261 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "^", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 858: -#line 2249 "third_party/libpg_query/grammar/statements/select.y" + case 878: +#line 2263 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "**", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 859: -#line 2251 "third_party/libpg_query/grammar/statements/select.y" + case 879: +#line 2265 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "<", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 860: -#line 2253 "third_party/libpg_query/grammar/statements/select.y" + case 880: +#line 2267 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, ">", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 861: -#line 2255 "third_party/libpg_query/grammar/statements/select.y" + case 881: +#line 2269 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "=", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 862: -#line 2257 "third_party/libpg_query/grammar/statements/select.y" + case 882: +#line 2271 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "<=", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 863: -#line 2259 "third_party/libpg_query/grammar/statements/select.y" + case 883: +#line 2273 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, ">=", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 864: -#line 2261 "third_party/libpg_query/grammar/statements/select.y" + case 884: +#line 2275 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OP, "<>", (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 865: -#line 2263 "third_party/libpg_query/grammar/statements/select.y" + case 885: +#line 2277 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeAExpr(PG_AEXPR_OP, (yyvsp[(2) - (3)].list), (yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yylsp[(2) - (3)])); ;} break; - case 866: -#line 2265 "third_party/libpg_query/grammar/statements/select.y" + case 886: +#line 2279 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeAExpr(PG_AEXPR_OP, (yyvsp[(1) - (2)].list), NULL, (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 867: -#line 2267 "third_party/libpg_query/grammar/statements/select.y" + case 887: +#line 2281 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeAExpr(PG_AEXPR_OP, (yyvsp[(2) - (2)].list), (yyvsp[(1) - (2)].node), NULL, (yylsp[(2) - (2)])); ;} break; - case 868: -#line 2269 "third_party/libpg_query/grammar/statements/select.y" + case 888: +#line 2283 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_DISTINCT, "=", (yyvsp[(1) - (5)].node), (yyvsp[(5) - (5)].node), (yylsp[(2) - (5)])); ;} break; - case 869: -#line 2273 "third_party/libpg_query/grammar/statements/select.y" + case 889: +#line 2287 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_NOT_DISTINCT, "=", (yyvsp[(1) - (6)].node), (yyvsp[(6) - (6)].node), (yylsp[(2) - (6)])); ;} break; - case 870: -#line 2277 "third_party/libpg_query/grammar/statements/select.y" + case 890: +#line 2291 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OF, "=", (yyvsp[(1) - (6)].node), (PGNode *) (yyvsp[(5) - (6)].list), (yylsp[(2) - (6)])); ;} break; - case 871: -#line 2281 "third_party/libpg_query/grammar/statements/select.y" + case 891: +#line 2295 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_OF, "<>", (yyvsp[(1) - (7)].node), (PGNode *) (yyvsp[(6) - (7)].list), (yylsp[(2) - (7)])); ;} break; - case 872: -#line 2294 "third_party/libpg_query/grammar/statements/select.y" + case 892: +#line 2308 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 873: -#line 2295 "third_party/libpg_query/grammar/statements/select.y" + case 893: +#line 2309 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 874: -#line 2297 "third_party/libpg_query/grammar/statements/select.y" + case 894: +#line 2311 "third_party/libpg_query/grammar/statements/select.y" { PGPositionalReference *n = makeNode(PGPositionalReference); n->position = (yyvsp[(2) - (2)].ival); @@ -317082,87 +331538,53 @@ YYLTYPE yylloc; ;} break; - case 875: -#line 2304 "third_party/libpg_query/grammar/statements/select.y" - { - if ((yyvsp[(2) - (2)].list)) - { - PGAIndirection *n = makeNode(PGAIndirection); - n->arg = makeParamRef(0, (yylsp[(1) - (2)])); - n->indirection = check_indirection((yyvsp[(2) - (2)].list), yyscanner); - (yyval.node) = (PGNode *) n; - } - else - (yyval.node) = makeParamRef(0, (yylsp[(1) - (2)])); - ;} - break; - - case 876: -#line 2316 "third_party/libpg_query/grammar/statements/select.y" + case 895: +#line 2318 "third_party/libpg_query/grammar/statements/select.y" { - PGParamRef *p = makeNode(PGParamRef); - p->number = (yyvsp[(1) - (2)].ival); - p->location = (yylsp[(1) - (2)]); if ((yyvsp[(2) - (2)].list)) { PGAIndirection *n = makeNode(PGAIndirection); - n->arg = (PGNode *) p; + n->arg = (PGNode *) (yyvsp[(1) - (2)].node); n->indirection = check_indirection((yyvsp[(2) - (2)].list), yyscanner); (yyval.node) = (PGNode *) n; } else - (yyval.node) = (PGNode *) p; + (yyval.node) = (PGNode *) (yyvsp[(1) - (2)].node); ;} break; - case 877: -#line 2331 "third_party/libpg_query/grammar/statements/select.y" + case 896: +#line 2330 "third_party/libpg_query/grammar/statements/select.y" { - if ((yyvsp[(4) - (4)].list)) - { - PGAIndirection *n = makeNode(PGAIndirection); - n->arg = (yyvsp[(2) - (4)].node); - n->indirection = check_indirection((yyvsp[(4) - (4)].list), yyscanner); - (yyval.node) = (PGNode *)n; - } - else - (yyval.node) = (yyvsp[(2) - (4)].node); + (yyval.node) = makeNamedParamRef((yyvsp[(2) - (2)].str), (yylsp[(1) - (2)])); ;} break; - case 878: -#line 2342 "third_party/libpg_query/grammar/statements/select.y" + case 897: +#line 2333 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("row"), (yyvsp[(1) - (1)].list), (yylsp[(1) - (1)])); (yyval.node) = (PGNode *) n; ;} break; - case 879: -#line 2346 "third_party/libpg_query/grammar/statements/select.y" - { - PGFuncCall *n = makeFuncCall(SystemFuncName("struct_pack"), (yyvsp[(2) - (3)].list), (yylsp[(2) - (3)])); - (yyval.node) = (PGNode *) n; - ;} - break; - - case 880: -#line 2350 "third_party/libpg_query/grammar/statements/select.y" + case 898: +#line 2337 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall(SystemFuncName("list_value"), (yyvsp[(2) - (3)].list), (yylsp[(2) - (3)])); (yyval.node) = (PGNode *) n; ;} break; - case 881: -#line 2354 "third_party/libpg_query/grammar/statements/select.y" + case 899: +#line 2341 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 882: -#line 2358 "third_party/libpg_query/grammar/statements/select.y" + case 900: +#line 2345 "third_party/libpg_query/grammar/statements/select.y" { PGSubLink *n = makeNode(PGSubLink); n->subLinkType = PG_ARRAY_SUBLINK; @@ -317175,8 +331597,8 @@ YYLTYPE yylloc; ;} break; - case 883: -#line 2368 "third_party/libpg_query/grammar/statements/select.y" + case 901: +#line 2355 "third_party/libpg_query/grammar/statements/select.y" { PGList *func_name = list_make1(makeString("construct_array")); PGFuncCall *n = makeFuncCall(func_name, (yyvsp[(3) - (4)].list), (yylsp[(1) - (4)])); @@ -317184,28 +331606,13 @@ YYLTYPE yylloc; ;} break; - case 884: -#line 2374 "third_party/libpg_query/grammar/statements/select.y" + case 902: +#line 2361 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 885: -#line 2376 "third_party/libpg_query/grammar/statements/select.y" - { - if ((yyvsp[(2) - (2)].list)) { - PGAIndirection *n = makeNode(PGAIndirection); - n->arg = (yyvsp[(1) - (2)].node); - n->indirection = check_indirection((yyvsp[(2) - (2)].list), yyscanner); - (yyval.node) = (PGNode *)n; - } - else { - (yyval.node) = (yyvsp[(1) - (2)].node); - } - ;} - break; - - case 886: -#line 2388 "third_party/libpg_query/grammar/statements/select.y" + case 903: +#line 2363 "third_party/libpg_query/grammar/statements/select.y" { PGSubLink *n = makeNode(PGSubLink); n->subLinkType = PG_EXPR_SUBLINK; @@ -317218,8 +331625,8 @@ YYLTYPE yylloc; ;} break; - case 887: -#line 2399 "third_party/libpg_query/grammar/statements/select.y" + case 904: +#line 2374 "third_party/libpg_query/grammar/statements/select.y" { /* * Because the select_with_parens nonterminal is designed @@ -317245,8 +331652,8 @@ YYLTYPE yylloc; ;} break; - case 888: -#line 2423 "third_party/libpg_query/grammar/statements/select.y" + case 905: +#line 2398 "third_party/libpg_query/grammar/statements/select.y" { PGSubLink *n = makeNode(PGSubLink); n->subLinkType = PG_EXISTS_SUBLINK; @@ -317259,8 +331666,8 @@ YYLTYPE yylloc; ;} break; - case 889: -#line 2434 "third_party/libpg_query/grammar/statements/select.y" + case 906: +#line 2409 "third_party/libpg_query/grammar/statements/select.y" { PGGroupingFunc *g = makeNode(PGGroupingFunc); g->args = (yyvsp[(3) - (4)].list); @@ -317269,15 +331676,54 @@ YYLTYPE yylloc; ;} break; - case 890: -#line 2443 "third_party/libpg_query/grammar/statements/select.y" + case 907: +#line 2420 "third_party/libpg_query/grammar/statements/select.y" + { + (yyval.node) = makeParamRef(0, (yylsp[(1) - (1)])); + ;} + break; + + case 908: +#line 2424 "third_party/libpg_query/grammar/statements/select.y" + { + PGParamRef *p = makeNode(PGParamRef); + p->number = (yyvsp[(1) - (1)].ival); + p->location = (yylsp[(1) - (1)]); + (yyval.node) = (PGNode *) p; + ;} + break; + + case 909: +#line 2431 "third_party/libpg_query/grammar/statements/select.y" + { + (yyval.node) = (yyvsp[(2) - (3)].node); + ;} + break; + + case 910: +#line 2435 "third_party/libpg_query/grammar/statements/select.y" + { + PGFuncCall *f = makeFuncCall(SystemFuncName("struct_pack"), (yyvsp[(2) - (3)].list), (yylsp[(2) - (3)])); + (yyval.node) = (PGNode *) f; + ;} + break; + + case 911: +#line 2440 "third_party/libpg_query/grammar/statements/select.y" + { + (yyval.node) = (yyvsp[(1) - (1)].node); + ;} + break; + + case 912: +#line 2445 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall((yyvsp[(1) - (3)].list), NIL, (yylsp[(1) - (3)])); ;} break; - case 891: -#line 2447 "third_party/libpg_query/grammar/statements/select.y" + case 913: +#line 2449 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall((yyvsp[(1) - (6)].list), (yyvsp[(3) - (6)].list), (yylsp[(1) - (6)])); n->agg_order = (yyvsp[(4) - (6)].list); @@ -317286,8 +331732,8 @@ YYLTYPE yylloc; ;} break; - case 892: -#line 2454 "third_party/libpg_query/grammar/statements/select.y" + case 914: +#line 2456 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall((yyvsp[(1) - (7)].list), list_make1((yyvsp[(4) - (7)].node)), (yylsp[(1) - (7)])); n->func_variadic = true; @@ -317297,8 +331743,8 @@ YYLTYPE yylloc; ;} break; - case 893: -#line 2462 "third_party/libpg_query/grammar/statements/select.y" + case 915: +#line 2464 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall((yyvsp[(1) - (9)].list), lappend((yyvsp[(3) - (9)].list), (yyvsp[(6) - (9)].node)), (yylsp[(1) - (9)])); n->func_variadic = true; @@ -317308,8 +331754,8 @@ YYLTYPE yylloc; ;} break; - case 894: -#line 2470 "third_party/libpg_query/grammar/statements/select.y" + case 916: +#line 2472 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall((yyvsp[(1) - (7)].list), (yyvsp[(4) - (7)].list), (yylsp[(1) - (7)])); n->agg_order = (yyvsp[(5) - (7)].list); @@ -317322,8 +331768,8 @@ YYLTYPE yylloc; ;} break; - case 895: -#line 2481 "third_party/libpg_query/grammar/statements/select.y" + case 917: +#line 2483 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = makeFuncCall((yyvsp[(1) - (7)].list), (yyvsp[(4) - (7)].list), (yylsp[(1) - (7)])); n->agg_order = (yyvsp[(5) - (7)].list); @@ -317333,8 +331779,8 @@ YYLTYPE yylloc; ;} break; - case 896: -#line 2489 "third_party/libpg_query/grammar/statements/select.y" + case 918: +#line 2491 "third_party/libpg_query/grammar/statements/select.y" { /* * We consider AGGREGATE(*) to invoke a parameterless @@ -317352,8 +331798,8 @@ YYLTYPE yylloc; ;} break; - case 897: -#line 2517 "third_party/libpg_query/grammar/statements/select.y" + case 919: +#line 2519 "third_party/libpg_query/grammar/statements/select.y" { PGFuncCall *n = (PGFuncCall *) (yyvsp[(1) - (5)].node); /* @@ -317391,23 +331837,23 @@ YYLTYPE yylloc; ;} break; - case 898: -#line 2553 "third_party/libpg_query/grammar/statements/select.y" + case 920: +#line 2555 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 899: -#line 2563 "third_party/libpg_query/grammar/statements/select.y" + case 921: +#line 2565 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 900: -#line 2564 "third_party/libpg_query/grammar/statements/select.y" + case 922: +#line 2566 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 901: -#line 2572 "third_party/libpg_query/grammar/statements/select.y" + case 923: +#line 2574 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("pg_collation_for"), list_make1((yyvsp[(4) - (5)].node)), @@ -317415,130 +331861,130 @@ YYLTYPE yylloc; ;} break; - case 902: -#line 2578 "third_party/libpg_query/grammar/statements/select.y" + case 924: +#line 2580 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_DATE, -1, (yylsp[(1) - (1)])); ;} break; - case 903: -#line 2582 "third_party/libpg_query/grammar/statements/select.y" + case 925: +#line 2584 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_TIME, -1, (yylsp[(1) - (1)])); ;} break; - case 904: -#line 2586 "third_party/libpg_query/grammar/statements/select.y" + case 926: +#line 2588 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_TIME_N, (yyvsp[(3) - (4)].ival), (yylsp[(1) - (4)])); ;} break; - case 905: -#line 2590 "third_party/libpg_query/grammar/statements/select.y" + case 927: +#line 2592 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_TIMESTAMP, -1, (yylsp[(1) - (1)])); ;} break; - case 906: -#line 2594 "third_party/libpg_query/grammar/statements/select.y" + case 928: +#line 2596 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_TIMESTAMP_N, (yyvsp[(3) - (4)].ival), (yylsp[(1) - (4)])); ;} break; - case 907: -#line 2598 "third_party/libpg_query/grammar/statements/select.y" + case 929: +#line 2600 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_LOCALTIME, -1, (yylsp[(1) - (1)])); ;} break; - case 908: -#line 2602 "third_party/libpg_query/grammar/statements/select.y" + case 930: +#line 2604 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_LOCALTIME_N, (yyvsp[(3) - (4)].ival), (yylsp[(1) - (4)])); ;} break; - case 909: -#line 2606 "third_party/libpg_query/grammar/statements/select.y" + case 931: +#line 2608 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_LOCALTIMESTAMP, -1, (yylsp[(1) - (1)])); ;} break; - case 910: -#line 2610 "third_party/libpg_query/grammar/statements/select.y" + case 932: +#line 2612 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_LOCALTIMESTAMP_N, (yyvsp[(3) - (4)].ival), (yylsp[(1) - (4)])); ;} break; - case 911: -#line 2614 "third_party/libpg_query/grammar/statements/select.y" + case 933: +#line 2616 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_ROLE, -1, (yylsp[(1) - (1)])); ;} break; - case 912: -#line 2618 "third_party/libpg_query/grammar/statements/select.y" + case 934: +#line 2620 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_USER, -1, (yylsp[(1) - (1)])); ;} break; - case 913: -#line 2622 "third_party/libpg_query/grammar/statements/select.y" + case 935: +#line 2624 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_SESSION_USER, -1, (yylsp[(1) - (1)])); ;} break; - case 914: -#line 2626 "third_party/libpg_query/grammar/statements/select.y" + case 936: +#line 2628 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_USER, -1, (yylsp[(1) - (1)])); ;} break; - case 915: -#line 2630 "third_party/libpg_query/grammar/statements/select.y" + case 937: +#line 2632 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_CATALOG, -1, (yylsp[(1) - (1)])); ;} break; - case 916: -#line 2634 "third_party/libpg_query/grammar/statements/select.y" + case 938: +#line 2636 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeSQLValueFunction(PG_SVFOP_CURRENT_SCHEMA, -1, (yylsp[(1) - (1)])); ;} break; - case 917: -#line 2638 "third_party/libpg_query/grammar/statements/select.y" + case 939: +#line 2640 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeTypeCast((yyvsp[(3) - (6)].node), (yyvsp[(5) - (6)].typnam), 0, (yylsp[(1) - (6)])); ;} break; - case 918: -#line 2640 "third_party/libpg_query/grammar/statements/select.y" + case 940: +#line 2642 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeTypeCast((yyvsp[(3) - (6)].node), (yyvsp[(5) - (6)].typnam), 1, (yylsp[(1) - (6)])); ;} break; - case 919: -#line 2642 "third_party/libpg_query/grammar/statements/select.y" + case 941: +#line 2644 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("date_part"), (yyvsp[(3) - (4)].list), (yylsp[(1) - (4)])); ;} break; - case 920: -#line 2646 "third_party/libpg_query/grammar/statements/select.y" + case 942: +#line 2648 "third_party/libpg_query/grammar/statements/select.y" { /* overlay(A PLACING B FROM C FOR D) is converted to * overlay(A, B, C, D) @@ -317549,16 +331995,16 @@ YYLTYPE yylloc; ;} break; - case 921: -#line 2655 "third_party/libpg_query/grammar/statements/select.y" + case 943: +#line 2657 "third_party/libpg_query/grammar/statements/select.y" { /* position(A in B) is converted to position(B, A) */ (yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("position"), (yyvsp[(3) - (4)].list), (yylsp[(1) - (4)])); ;} break; - case 922: -#line 2660 "third_party/libpg_query/grammar/statements/select.y" + case 944: +#line 2662 "third_party/libpg_query/grammar/statements/select.y" { /* substring(A from B for C) is converted to * substring(A, B, C) - thomas 2000-11-28 @@ -317567,8 +332013,8 @@ YYLTYPE yylloc; ;} break; - case 923: -#line 2667 "third_party/libpg_query/grammar/statements/select.y" + case 945: +#line 2669 "third_party/libpg_query/grammar/statements/select.y" { /* TREAT(expr AS target) converts expr of a particular type to target, * which is defined to be a subtype of the original expression. @@ -317585,8 +332031,8 @@ YYLTYPE yylloc; ;} break; - case 924: -#line 2682 "third_party/libpg_query/grammar/statements/select.y" + case 946: +#line 2684 "third_party/libpg_query/grammar/statements/select.y" { /* various trim expressions are defined in SQL * - thomas 1997-07-19 @@ -317595,36 +332041,36 @@ YYLTYPE yylloc; ;} break; - case 925: -#line 2689 "third_party/libpg_query/grammar/statements/select.y" + case 947: +#line 2691 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("ltrim"), (yyvsp[(4) - (5)].list), (yylsp[(1) - (5)])); ;} break; - case 926: -#line 2693 "third_party/libpg_query/grammar/statements/select.y" + case 948: +#line 2695 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("rtrim"), (yyvsp[(4) - (5)].list), (yylsp[(1) - (5)])); ;} break; - case 927: -#line 2697 "third_party/libpg_query/grammar/statements/select.y" + case 949: +#line 2699 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeFuncCall(SystemFuncName("trim"), (yyvsp[(3) - (4)].list), (yylsp[(1) - (4)])); ;} break; - case 928: -#line 2701 "third_party/libpg_query/grammar/statements/select.y" + case 950: +#line 2703 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeSimpleAExpr(PG_AEXPR_NULLIF, "=", (yyvsp[(3) - (6)].node), (yyvsp[(5) - (6)].node), (yylsp[(1) - (6)])); ;} break; - case 929: -#line 2705 "third_party/libpg_query/grammar/statements/select.y" + case 951: +#line 2707 "third_party/libpg_query/grammar/statements/select.y" { PGCoalesceExpr *c = makeNode(PGCoalesceExpr); c->args = (yyvsp[(3) - (4)].list); @@ -317633,8 +332079,8 @@ YYLTYPE yylloc; ;} break; - case 930: -#line 2715 "third_party/libpg_query/grammar/statements/select.y" + case 952: +#line 2717 "third_party/libpg_query/grammar/statements/select.y" { PGLambdaFunction *lambda = makeNode(PGLambdaFunction); lambda->lhs = makeColumnRef((yyvsp[(4) - (7)].str), NIL, (yylsp[(4) - (7)]), yyscanner); @@ -317645,8 +332091,8 @@ YYLTYPE yylloc; ;} break; - case 931: -#line 2724 "third_party/libpg_query/grammar/statements/select.y" + case 953: +#line 2726 "third_party/libpg_query/grammar/statements/select.y" { PGLambdaFunction *lambda = makeNode(PGLambdaFunction); lambda->lhs = makeColumnRef((yyvsp[(4) - (9)].str), NIL, (yylsp[(4) - (9)]), yyscanner); @@ -317663,63 +332109,63 @@ YYLTYPE yylloc; ;} break; - case 932: -#line 2745 "third_party/libpg_query/grammar/statements/select.y" + case 954: +#line 2747 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(4) - (5)].list); ;} break; - case 933: -#line 2746 "third_party/libpg_query/grammar/statements/select.y" + case 955: +#line 2748 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 934: -#line 2750 "third_party/libpg_query/grammar/statements/select.y" + case 956: +#line 2752 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(4) - (5)].node); ;} break; - case 935: -#line 2751 "third_party/libpg_query/grammar/statements/select.y" + case 957: +#line 2753 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(3) - (4)].node); ;} break; - case 936: -#line 2752 "third_party/libpg_query/grammar/statements/select.y" + case 958: +#line 2754 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 937: -#line 2756 "third_party/libpg_query/grammar/statements/select.y" + case 959: +#line 2758 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = true; ;} break; - case 938: -#line 2757 "third_party/libpg_query/grammar/statements/select.y" + case 960: +#line 2759 "third_party/libpg_query/grammar/statements/select.y" { (yyval.boolean) = false; ;} break; - case 939: -#line 2764 "third_party/libpg_query/grammar/statements/select.y" + case 961: +#line 2766 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(2) - (2)].list); ;} break; - case 940: -#line 2765 "third_party/libpg_query/grammar/statements/select.y" + case 962: +#line 2767 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 941: -#line 2769 "third_party/libpg_query/grammar/statements/select.y" + case 963: +#line 2771 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].windef)); ;} break; - case 942: -#line 2771 "third_party/libpg_query/grammar/statements/select.y" + case 964: +#line 2773 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].windef)); ;} break; - case 943: -#line 2776 "third_party/libpg_query/grammar/statements/select.y" + case 965: +#line 2778 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = (yyvsp[(3) - (3)].windef); n->name = (yyvsp[(1) - (3)].str); @@ -317727,13 +332173,13 @@ YYLTYPE yylloc; ;} break; - case 944: -#line 2784 "third_party/libpg_query/grammar/statements/select.y" + case 966: +#line 2786 "third_party/libpg_query/grammar/statements/select.y" { (yyval.windef) = (yyvsp[(2) - (2)].windef); ;} break; - case 945: -#line 2786 "third_party/libpg_query/grammar/statements/select.y" + case 967: +#line 2788 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); n->name = (yyvsp[(2) - (2)].str); @@ -317748,13 +332194,13 @@ YYLTYPE yylloc; ;} break; - case 946: -#line 2799 "third_party/libpg_query/grammar/statements/select.y" + case 968: +#line 2801 "third_party/libpg_query/grammar/statements/select.y" { (yyval.windef) = NULL; ;} break; - case 947: -#line 2804 "third_party/libpg_query/grammar/statements/select.y" + case 969: +#line 2806 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); n->name = NULL; @@ -317770,28 +332216,28 @@ YYLTYPE yylloc; ;} break; - case 948: -#line 2829 "third_party/libpg_query/grammar/statements/select.y" + case 970: +#line 2831 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 949: -#line 2830 "third_party/libpg_query/grammar/statements/select.y" + case 971: +#line 2832 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = NULL; ;} break; - case 950: -#line 2833 "third_party/libpg_query/grammar/statements/select.y" + case 972: +#line 2835 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (3)].list); ;} break; - case 951: -#line 2834 "third_party/libpg_query/grammar/statements/select.y" + case 973: +#line 2836 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 952: -#line 2846 "third_party/libpg_query/grammar/statements/select.y" + case 974: +#line 2848 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = (yyvsp[(2) - (2)].windef); n->frameOptions |= FRAMEOPTION_NONDEFAULT | FRAMEOPTION_RANGE; @@ -317799,8 +332245,8 @@ YYLTYPE yylloc; ;} break; - case 953: -#line 2852 "third_party/libpg_query/grammar/statements/select.y" + case 975: +#line 2854 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = (yyvsp[(2) - (2)].windef); n->frameOptions |= FRAMEOPTION_NONDEFAULT | FRAMEOPTION_ROWS; @@ -317808,8 +332254,8 @@ YYLTYPE yylloc; ;} break; - case 954: -#line 2858 "third_party/libpg_query/grammar/statements/select.y" + case 976: +#line 2860 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); n->frameOptions = FRAMEOPTION_DEFAULTS; @@ -317819,8 +332265,8 @@ YYLTYPE yylloc; ;} break; - case 955: -#line 2868 "third_party/libpg_query/grammar/statements/select.y" + case 977: +#line 2870 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = (yyvsp[(1) - (1)].windef); /* reject invalid cases */ @@ -317839,8 +332285,8 @@ YYLTYPE yylloc; ;} break; - case 956: -#line 2885 "third_party/libpg_query/grammar/statements/select.y" + case 978: +#line 2887 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n1 = (yyvsp[(2) - (4)].windef); PGWindowDef *n2 = (yyvsp[(4) - (4)].windef); @@ -317879,8 +332325,8 @@ YYLTYPE yylloc; ;} break; - case 957: -#line 2930 "third_party/libpg_query/grammar/statements/select.y" + case 979: +#line 2932 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); n->frameOptions = FRAMEOPTION_START_UNBOUNDED_PRECEDING; @@ -317890,8 +332336,8 @@ YYLTYPE yylloc; ;} break; - case 958: -#line 2938 "third_party/libpg_query/grammar/statements/select.y" + case 980: +#line 2940 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); n->frameOptions = FRAMEOPTION_START_UNBOUNDED_FOLLOWING; @@ -317901,8 +332347,8 @@ YYLTYPE yylloc; ;} break; - case 959: -#line 2946 "third_party/libpg_query/grammar/statements/select.y" + case 981: +#line 2948 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); n->frameOptions = FRAMEOPTION_START_CURRENT_ROW; @@ -317912,8 +332358,8 @@ YYLTYPE yylloc; ;} break; - case 960: -#line 2954 "third_party/libpg_query/grammar/statements/select.y" + case 982: +#line 2956 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); n->frameOptions = FRAMEOPTION_START_VALUE_PRECEDING; @@ -317923,8 +332369,8 @@ YYLTYPE yylloc; ;} break; - case 961: -#line 2962 "third_party/libpg_query/grammar/statements/select.y" + case 983: +#line 2964 "third_party/libpg_query/grammar/statements/select.y" { PGWindowDef *n = makeNode(PGWindowDef); n->frameOptions = FRAMEOPTION_START_VALUE_FOLLOWING; @@ -317934,28 +332380,28 @@ YYLTYPE yylloc; ;} break; - case 962: -#line 2982 "third_party/libpg_query/grammar/statements/select.y" + case 984: +#line 2984 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 963: -#line 2983 "third_party/libpg_query/grammar/statements/select.y" + case 985: +#line 2985 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 964: -#line 2986 "third_party/libpg_query/grammar/statements/select.y" + case 986: +#line 2988 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list);;} break; - case 965: -#line 2987 "third_party/libpg_query/grammar/statements/select.y" + case 987: +#line 2989 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(2) - (5)].list), (yyvsp[(4) - (5)].node)); ;} break; - case 966: -#line 2991 "third_party/libpg_query/grammar/statements/select.y" + case 988: +#line 2993 "third_party/libpg_query/grammar/statements/select.y" { PGNamedArgExpr *na = makeNode(PGNamedArgExpr); na->name = (yyvsp[(1) - (3)].str); @@ -317966,251 +332412,251 @@ YYLTYPE yylloc; ;} break; - case 967: -#line 3001 "third_party/libpg_query/grammar/statements/select.y" + case 989: +#line 3003 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 968: -#line 3002 "third_party/libpg_query/grammar/statements/select.y" + case 990: +#line 3004 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 969: -#line 3006 "third_party/libpg_query/grammar/statements/select.y" + case 991: +#line 3008 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 970: -#line 3007 "third_party/libpg_query/grammar/statements/select.y" + case 992: +#line 3009 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; - case 971: -#line 3011 "third_party/libpg_query/grammar/statements/select.y" + case 993: +#line 3013 "third_party/libpg_query/grammar/statements/select.y" { (yyval.subquerytype) = PG_ANY_SUBLINK; ;} break; - case 972: -#line 3012 "third_party/libpg_query/grammar/statements/select.y" + case 994: +#line 3014 "third_party/libpg_query/grammar/statements/select.y" { (yyval.subquerytype) = PG_ANY_SUBLINK; ;} break; - case 973: -#line 3013 "third_party/libpg_query/grammar/statements/select.y" + case 995: +#line 3015 "third_party/libpg_query/grammar/statements/select.y" { (yyval.subquerytype) = PG_ALL_SUBLINK; ;} break; - case 974: -#line 3016 "third_party/libpg_query/grammar/statements/select.y" + case 996: +#line 3018 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 975: -#line 3017 "third_party/libpg_query/grammar/statements/select.y" + case 997: +#line 3019 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) (yyvsp[(1) - (1)].conststr); ;} break; - case 976: -#line 3020 "third_party/libpg_query/grammar/statements/select.y" + case 998: +#line 3022 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "+"; ;} break; - case 977: -#line 3021 "third_party/libpg_query/grammar/statements/select.y" + case 999: +#line 3023 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "-"; ;} break; - case 978: -#line 3022 "third_party/libpg_query/grammar/statements/select.y" + case 1000: +#line 3024 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "*"; ;} break; - case 979: -#line 3023 "third_party/libpg_query/grammar/statements/select.y" + case 1001: +#line 3025 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "/"; ;} break; - case 980: -#line 3024 "third_party/libpg_query/grammar/statements/select.y" + case 1002: +#line 3026 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "%"; ;} break; - case 981: -#line 3025 "third_party/libpg_query/grammar/statements/select.y" + case 1003: +#line 3027 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "^"; ;} break; - case 982: -#line 3026 "third_party/libpg_query/grammar/statements/select.y" + case 1004: +#line 3028 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "**"; ;} break; - case 983: -#line 3027 "third_party/libpg_query/grammar/statements/select.y" + case 1005: +#line 3029 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "<"; ;} break; - case 984: -#line 3028 "third_party/libpg_query/grammar/statements/select.y" + case 1006: +#line 3030 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = ">"; ;} break; - case 985: -#line 3029 "third_party/libpg_query/grammar/statements/select.y" + case 1007: +#line 3031 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "="; ;} break; - case 986: -#line 3030 "third_party/libpg_query/grammar/statements/select.y" + case 1008: +#line 3032 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "<="; ;} break; - case 987: -#line 3031 "third_party/libpg_query/grammar/statements/select.y" + case 1009: +#line 3033 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = ">="; ;} break; - case 988: -#line 3032 "third_party/libpg_query/grammar/statements/select.y" + case 1010: +#line 3034 "third_party/libpg_query/grammar/statements/select.y" { (yyval.conststr) = "<>"; ;} break; - case 989: -#line 3036 "third_party/libpg_query/grammar/statements/select.y" + case 1011: +#line 3038 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 990: -#line 3038 "third_party/libpg_query/grammar/statements/select.y" + case 1012: +#line 3040 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 991: -#line 3043 "third_party/libpg_query/grammar/statements/select.y" + case 1013: +#line 3045 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 992: -#line 3045 "third_party/libpg_query/grammar/statements/select.y" + case 1014: +#line 3047 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 993: -#line 3050 "third_party/libpg_query/grammar/statements/select.y" + case 1015: +#line 3052 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 994: -#line 3052 "third_party/libpg_query/grammar/statements/select.y" + case 1016: +#line 3054 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 995: -#line 3054 "third_party/libpg_query/grammar/statements/select.y" + case 1017: +#line 3056 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString("~~")); ;} break; - case 996: -#line 3056 "third_party/libpg_query/grammar/statements/select.y" + case 1018: +#line 3058 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString("!~~")); ;} break; - case 997: -#line 3058 "third_party/libpg_query/grammar/statements/select.y" + case 1019: +#line 3060 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString("~~~")); ;} break; - case 998: -#line 3060 "third_party/libpg_query/grammar/statements/select.y" + case 1020: +#line 3062 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString("!~~~")); ;} break; - case 999: -#line 3062 "third_party/libpg_query/grammar/statements/select.y" + case 1021: +#line 3064 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString("~~*")); ;} break; - case 1000: -#line 3064 "third_party/libpg_query/grammar/statements/select.y" + case 1022: +#line 3066 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString("!~~*")); ;} break; - case 1001: -#line 3078 "third_party/libpg_query/grammar/statements/select.y" + case 1023: +#line 3080 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 1002: -#line 3080 "third_party/libpg_query/grammar/statements/select.y" + case 1024: +#line 3082 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lcons(makeString((yyvsp[(1) - (3)].str)), (yyvsp[(3) - (3)].list)); ;} break; - case 1003: -#line 3084 "third_party/libpg_query/grammar/statements/select.y" + case 1025: +#line 3086 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 1004: -#line 3088 "third_party/libpg_query/grammar/statements/select.y" + case 1026: +#line 3090 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 1005: -#line 3095 "third_party/libpg_query/grammar/statements/select.y" + case 1027: +#line 3097 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1006: -#line 3100 "third_party/libpg_query/grammar/statements/select.y" + case 1028: +#line 3102 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; - case 1007: -#line 3107 "third_party/libpg_query/grammar/statements/select.y" + case 1029: +#line 3109 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1008: -#line 3111 "third_party/libpg_query/grammar/statements/select.y" + case 1030: +#line 3113 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NULL; ;} break; - case 1009: -#line 3120 "third_party/libpg_query/grammar/statements/select.y" + case 1031: +#line 3122 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 1010: -#line 3124 "third_party/libpg_query/grammar/statements/select.y" + case 1032: +#line 3126 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 1011: -#line 3130 "third_party/libpg_query/grammar/statements/select.y" + case 1033: +#line 3132 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 1012: -#line 3134 "third_party/libpg_query/grammar/statements/select.y" + case 1034: +#line 3136 "third_party/libpg_query/grammar/statements/select.y" { PGNamedArgExpr *na = makeNode(PGNamedArgExpr); na->name = (yyvsp[(1) - (3)].str); @@ -318221,8 +332667,8 @@ YYLTYPE yylloc; ;} break; - case 1013: -#line 3143 "third_party/libpg_query/grammar/statements/select.y" + case 1035: +#line 3145 "third_party/libpg_query/grammar/statements/select.y" { PGNamedArgExpr *na = makeNode(PGNamedArgExpr); na->name = (yyvsp[(1) - (3)].str); @@ -318233,131 +332679,131 @@ YYLTYPE yylloc; ;} break; - case 1014: -#line 3153 "third_party/libpg_query/grammar/statements/select.y" + case 1036: +#line 3155 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].typnam)); ;} break; - case 1015: -#line 3154 "third_party/libpg_query/grammar/statements/select.y" + case 1037: +#line 3156 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].typnam)); ;} break; - case 1016: -#line 3159 "third_party/libpg_query/grammar/statements/select.y" + case 1038: +#line 3161 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2(makeStringConst((yyvsp[(1) - (3)].str), (yylsp[(1) - (3)])), (yyvsp[(3) - (3)].node)); ;} break; - case 1017: -#line 3162 "third_party/libpg_query/grammar/statements/select.y" + case 1039: +#line 3164 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 1018: -#line 3169 "third_party/libpg_query/grammar/statements/select.y" + case 1040: +#line 3171 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1019: -#line 3170 "third_party/libpg_query/grammar/statements/select.y" + case 1041: +#line 3172 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "year"; ;} break; - case 1020: -#line 3171 "third_party/libpg_query/grammar/statements/select.y" + case 1042: +#line 3173 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "month"; ;} break; - case 1021: -#line 3172 "third_party/libpg_query/grammar/statements/select.y" + case 1043: +#line 3174 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "day"; ;} break; - case 1022: -#line 3173 "third_party/libpg_query/grammar/statements/select.y" + case 1044: +#line 3175 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "hour"; ;} break; - case 1023: -#line 3174 "third_party/libpg_query/grammar/statements/select.y" + case 1045: +#line 3176 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "minute"; ;} break; - case 1024: -#line 3175 "third_party/libpg_query/grammar/statements/select.y" + case 1046: +#line 3177 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "second"; ;} break; - case 1025: -#line 3176 "third_party/libpg_query/grammar/statements/select.y" + case 1047: +#line 3178 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "millisecond"; ;} break; - case 1026: -#line 3177 "third_party/libpg_query/grammar/statements/select.y" + case 1048: +#line 3179 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (char*) "microsecond"; ;} break; - case 1027: -#line 3178 "third_party/libpg_query/grammar/statements/select.y" + case 1049: +#line 3180 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1028: -#line 3189 "third_party/libpg_query/grammar/statements/select.y" + case 1050: +#line 3191 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make4((yyvsp[(1) - (4)].node), (yyvsp[(2) - (4)].node), (yyvsp[(3) - (4)].node), (yyvsp[(4) - (4)].node)); ;} break; - case 1029: -#line 3193 "third_party/libpg_query/grammar/statements/select.y" + case 1051: +#line 3195 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make3((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].node), (yyvsp[(3) - (3)].node)); ;} break; - case 1030: -#line 3200 "third_party/libpg_query/grammar/statements/select.y" + case 1052: +#line 3202 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 1031: -#line 3206 "third_party/libpg_query/grammar/statements/select.y" + case 1053: +#line 3208 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(3) - (3)].node), (yyvsp[(1) - (3)].node)); ;} break; - case 1032: -#line 3207 "third_party/libpg_query/grammar/statements/select.y" + case 1054: +#line 3209 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 1033: -#line 3224 "third_party/libpg_query/grammar/statements/select.y" + case 1055: +#line 3226 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make3((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].node), (yyvsp[(3) - (3)].node)); ;} break; - case 1034: -#line 3228 "third_party/libpg_query/grammar/statements/select.y" + case 1056: +#line 3230 "third_party/libpg_query/grammar/statements/select.y" { /* not legal per SQL99, but might as well allow it */ (yyval.list) = list_make3((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node), (yyvsp[(2) - (3)].node)); ;} break; - case 1035: -#line 3233 "third_party/libpg_query/grammar/statements/select.y" + case 1057: +#line 3235 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].node)); ;} break; - case 1036: -#line 3237 "third_party/libpg_query/grammar/statements/select.y" + case 1058: +#line 3239 "third_party/libpg_query/grammar/statements/select.y" { /* * Since there are no cases where this syntax allows @@ -318374,45 +332820,45 @@ YYLTYPE yylloc; ;} break; - case 1037: -#line 3252 "third_party/libpg_query/grammar/statements/select.y" + case 1059: +#line 3254 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1038: -#line 3256 "third_party/libpg_query/grammar/statements/select.y" + case 1060: +#line 3258 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 1039: -#line 3260 "third_party/libpg_query/grammar/statements/select.y" + case 1061: +#line 3262 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 1040: -#line 3263 "third_party/libpg_query/grammar/statements/select.y" + case 1062: +#line 3265 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 1041: -#line 3266 "third_party/libpg_query/grammar/statements/select.y" + case 1063: +#line 3268 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(3) - (3)].list), (yyvsp[(1) - (3)].node)); ;} break; - case 1042: -#line 3267 "third_party/libpg_query/grammar/statements/select.y" + case 1064: +#line 3269 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(2) - (2)].list); ;} break; - case 1043: -#line 3268 "third_party/libpg_query/grammar/statements/select.y" + case 1065: +#line 3270 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1044: -#line 3272 "third_party/libpg_query/grammar/statements/select.y" + case 1066: +#line 3274 "third_party/libpg_query/grammar/statements/select.y" { PGSubLink *n = makeNode(PGSubLink); n->subselect = (yyvsp[(1) - (1)].node); @@ -318421,13 +332867,13 @@ YYLTYPE yylloc; ;} break; - case 1045: -#line 3278 "third_party/libpg_query/grammar/statements/select.y" + case 1067: +#line 3280 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *)(yyvsp[(2) - (3)].list); ;} break; - case 1046: -#line 3289 "third_party/libpg_query/grammar/statements/select.y" + case 1068: +#line 3291 "third_party/libpg_query/grammar/statements/select.y" { PGCaseExpr *c = makeNode(PGCaseExpr); c->casetype = InvalidOid; /* not analyzed yet */ @@ -318439,18 +332885,18 @@ YYLTYPE yylloc; ;} break; - case 1047: -#line 3302 "third_party/libpg_query/grammar/statements/select.y" + case 1069: +#line 3304 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 1048: -#line 3303 "third_party/libpg_query/grammar/statements/select.y" + case 1070: +#line 3305 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); ;} break; - case 1049: -#line 3308 "third_party/libpg_query/grammar/statements/select.y" + case 1071: +#line 3310 "third_party/libpg_query/grammar/statements/select.y" { PGCaseWhen *w = makeNode(PGCaseWhen); w->expr = (PGExpr *) (yyvsp[(2) - (4)].node); @@ -318460,49 +332906,49 @@ YYLTYPE yylloc; ;} break; - case 1050: -#line 3318 "third_party/libpg_query/grammar/statements/select.y" + case 1072: +#line 3320 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 1051: -#line 3319 "third_party/libpg_query/grammar/statements/select.y" + case 1073: +#line 3321 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 1052: -#line 3322 "third_party/libpg_query/grammar/statements/select.y" + case 1074: +#line 3324 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 1053: -#line 3323 "third_party/libpg_query/grammar/statements/select.y" + case 1075: +#line 3325 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 1054: -#line 3327 "third_party/libpg_query/grammar/statements/select.y" + case 1076: +#line 3329 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeColumnRef((yyvsp[(1) - (1)].str), NIL, (yylsp[(1) - (1)]), yyscanner); ;} break; - case 1055: -#line 3331 "third_party/libpg_query/grammar/statements/select.y" + case 1077: +#line 3333 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeColumnRef((yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].list), (yylsp[(1) - (2)]), yyscanner); ;} break; - case 1056: -#line 3338 "third_party/libpg_query/grammar/statements/select.y" + case 1078: +#line 3340 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (PGNode *) makeString((yyvsp[(2) - (2)].str)); ;} break; - case 1057: -#line 3342 "third_party/libpg_query/grammar/statements/select.y" + case 1079: +#line 3344 "third_party/libpg_query/grammar/statements/select.y" { PGAIndices *ai = makeNode(PGAIndices); ai->is_slice = false; @@ -318512,8 +332958,8 @@ YYLTYPE yylloc; ;} break; - case 1058: -#line 3350 "third_party/libpg_query/grammar/statements/select.y" + case 1080: +#line 3352 "third_party/libpg_query/grammar/statements/select.y" { PGAIndices *ai = makeNode(PGAIndices); ai->is_slice = true; @@ -318523,68 +332969,68 @@ YYLTYPE yylloc; ;} break; - case 1059: -#line 3360 "third_party/libpg_query/grammar/statements/select.y" + case 1081: +#line 3362 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = (yyvsp[(1) - (1)].node); ;} break; - case 1060: -#line 3361 "third_party/libpg_query/grammar/statements/select.y" + case 1082: +#line 3363 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = NULL; ;} break; - case 1061: -#line 3365 "third_party/libpg_query/grammar/statements/select.y" + case 1083: +#line 3367 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 1062: -#line 3366 "third_party/libpg_query/grammar/statements/select.y" + case 1084: +#line 3368 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); ;} break; - case 1063: -#line 3370 "third_party/libpg_query/grammar/statements/select.y" + case 1085: +#line 3372 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 1064: -#line 3371 "third_party/libpg_query/grammar/statements/select.y" + case 1086: +#line 3373 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (2)].list), (yyvsp[(2) - (2)].node)); ;} break; - case 1067: -#line 3385 "third_party/libpg_query/grammar/statements/select.y" + case 1089: +#line 3387 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1068: -#line 3386 "third_party/libpg_query/grammar/statements/select.y" + case 1090: +#line 3388 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 1069: -#line 3390 "third_party/libpg_query/grammar/statements/select.y" + case 1091: +#line 3392 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].target)); ;} break; - case 1070: -#line 3391 "third_party/libpg_query/grammar/statements/select.y" + case 1092: +#line 3393 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].target)); ;} break; - case 1071: -#line 3395 "third_party/libpg_query/grammar/statements/select.y" + case 1093: +#line 3397 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1072: -#line 3396 "third_party/libpg_query/grammar/statements/select.y" + case 1094: +#line 3398 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; - case 1073: -#line 3400 "third_party/libpg_query/grammar/statements/select.y" + case 1095: +#line 3402 "third_party/libpg_query/grammar/statements/select.y" { (yyval.target) = makeNode(PGResTarget); (yyval.target)->name = (yyvsp[(3) - (3)].str); @@ -318594,8 +333040,8 @@ YYLTYPE yylloc; ;} break; - case 1074: -#line 3416 "third_party/libpg_query/grammar/statements/select.y" + case 1096: +#line 3418 "third_party/libpg_query/grammar/statements/select.y" { (yyval.target) = makeNode(PGResTarget); (yyval.target)->name = (yyvsp[(2) - (2)].str); @@ -318605,8 +333051,8 @@ YYLTYPE yylloc; ;} break; - case 1075: -#line 3424 "third_party/libpg_query/grammar/statements/select.y" + case 1097: +#line 3426 "third_party/libpg_query/grammar/statements/select.y" { (yyval.target) = makeNode(PGResTarget); (yyval.target)->name = NULL; @@ -318616,8 +333062,8 @@ YYLTYPE yylloc; ;} break; - case 1076: -#line 3432 "third_party/libpg_query/grammar/statements/select.y" + case 1098: +#line 3434 "third_party/libpg_query/grammar/statements/select.y" { PGColumnRef *n = makeNode(PGColumnRef); PGAStar *star = makeNode(PGAStar); @@ -318634,8 +333080,8 @@ YYLTYPE yylloc; ;} break; - case 1077: -#line 3447 "third_party/libpg_query/grammar/statements/select.y" + case 1099: +#line 3449 "third_party/libpg_query/grammar/statements/select.y" { PGColumnRef *n = makeNode(PGColumnRef); PGAStar *star = makeNode(PGAStar); @@ -318653,85 +333099,85 @@ YYLTYPE yylloc; ;} break; - case 1078: -#line 3464 "third_party/libpg_query/grammar/statements/select.y" + case 1100: +#line 3466 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 1079: -#line 3465 "third_party/libpg_query/grammar/statements/select.y" + case 1101: +#line 3467 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(2) - (2)].str))); ;} break; - case 1080: -#line 3468 "third_party/libpg_query/grammar/statements/select.y" + case 1102: +#line 3470 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1081: -#line 3469 "third_party/libpg_query/grammar/statements/select.y" + case 1103: +#line 3471 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NULL; ;} break; - case 1082: -#line 3472 "third_party/libpg_query/grammar/statements/select.y" + case 1104: +#line 3474 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make2((yyvsp[(1) - (3)].node), makeString((yyvsp[(3) - (3)].str))); ;} break; - case 1083: -#line 3476 "third_party/libpg_query/grammar/statements/select.y" + case 1105: +#line 3478 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].list)); ;} break; - case 1084: -#line 3477 "third_party/libpg_query/grammar/statements/select.y" + case 1106: +#line 3479 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); ;} break; - case 1085: -#line 3481 "third_party/libpg_query/grammar/statements/select.y" + case 1107: +#line 3483 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1086: -#line 3482 "third_party/libpg_query/grammar/statements/select.y" + case 1108: +#line 3484 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; - case 1087: -#line 3485 "third_party/libpg_query/grammar/statements/select.y" + case 1109: +#line 3487 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(3) - (4)].list); ;} break; - case 1088: -#line 3486 "third_party/libpg_query/grammar/statements/select.y" + case 1110: +#line 3488 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(2) - (2)].list)); ;} break; - case 1089: -#line 3487 "third_party/libpg_query/grammar/statements/select.y" + case 1111: +#line 3489 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NULL; ;} break; - case 1090: -#line 3497 "third_party/libpg_query/grammar/statements/select.y" + case 1112: +#line 3499 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].range)); ;} break; - case 1091: -#line 3498 "third_party/libpg_query/grammar/statements/select.y" + case 1113: +#line 3500 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].range)); ;} break; - case 1092: -#line 3510 "third_party/libpg_query/grammar/statements/select.y" + case 1114: +#line 3512 "third_party/libpg_query/grammar/statements/select.y" { (yyval.range) = makeRangeVar(NULL, (yyvsp[(1) - (1)].str), (yylsp[(1) - (1)])); ;} break; - case 1093: -#line 3514 "third_party/libpg_query/grammar/statements/select.y" + case 1115: +#line 3516 "third_party/libpg_query/grammar/statements/select.y" { check_qualified_name((yyvsp[(2) - (2)].list), yyscanner); (yyval.range) = makeRangeVar(NULL, NULL, (yylsp[(1) - (2)])); @@ -318747,6 +333193,7 @@ YYLTYPE yylloc; (yyval.range)->schemaname = strVal(linitial((yyvsp[(2) - (2)].list))); (yyval.range)->relname = strVal(lsecond((yyvsp[(2) - (2)].list))); break; + case 3: default: ereport(ERROR, (errcode(PG_ERRCODE_SYNTAX_ERROR), @@ -318758,65 +333205,65 @@ YYLTYPE yylloc; ;} break; - case 1094: -#line 3541 "third_party/libpg_query/grammar/statements/select.y" + case 1116: +#line 3544 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 1095: -#line 3543 "third_party/libpg_query/grammar/statements/select.y" + case 1117: +#line 3546 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), makeString((yyvsp[(3) - (3)].str))); ;} break; - case 1096: -#line 3548 "third_party/libpg_query/grammar/statements/select.y" + case 1118: +#line 3551 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (1)].list); ;} break; - case 1097: -#line 3549 "third_party/libpg_query/grammar/statements/select.y" + case 1119: +#line 3552 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(1) - (2)].list); ;} break; - case 1098: -#line 3552 "third_party/libpg_query/grammar/statements/select.y" + case 1120: +#line 3555 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1099: -#line 3554 "third_party/libpg_query/grammar/statements/select.y" + case 1121: +#line 3557 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1100: -#line 3565 "third_party/libpg_query/grammar/statements/select.y" + case 1122: +#line 3568 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 1101: -#line 3568 "third_party/libpg_query/grammar/statements/select.y" + case 1123: +#line 3571 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = check_func_name(lcons(makeString((yyvsp[(1) - (2)].str)), (yyvsp[(2) - (2)].list)), yyscanner); ;} break; - case 1102: -#line 3579 "third_party/libpg_query/grammar/statements/select.y" + case 1124: +#line 3582 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeIntConst((yyvsp[(1) - (1)].ival), (yylsp[(1) - (1)])); ;} break; - case 1103: -#line 3583 "third_party/libpg_query/grammar/statements/select.y" + case 1125: +#line 3586 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeFloatConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)])); ;} break; - case 1104: -#line 3587 "third_party/libpg_query/grammar/statements/select.y" + case 1126: +#line 3590 "third_party/libpg_query/grammar/statements/select.y" { if ((yyvsp[(2) - (2)].list)) { @@ -318830,15 +333277,15 @@ YYLTYPE yylloc; ;} break; - case 1105: -#line 3599 "third_party/libpg_query/grammar/statements/select.y" + case 1127: +#line 3602 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeBitStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)])); ;} break; - case 1106: -#line 3603 "third_party/libpg_query/grammar/statements/select.y" + case 1128: +#line 3606 "third_party/libpg_query/grammar/statements/select.y" { /* This is a bit constant per SQL99: * Without Feature F511, "BIT data type", @@ -318849,8 +333296,8 @@ YYLTYPE yylloc; ;} break; - case 1107: -#line 3612 "third_party/libpg_query/grammar/statements/select.y" + case 1129: +#line 3615 "third_party/libpg_query/grammar/statements/select.y" { /* generic type 'literal' syntax */ PGTypeName *t = makeTypeNameFromNameList((yyvsp[(1) - (2)].list)); @@ -318859,8 +333306,8 @@ YYLTYPE yylloc; ;} break; - case 1108: -#line 3619 "third_party/libpg_query/grammar/statements/select.y" + case 1130: +#line 3622 "third_party/libpg_query/grammar/statements/select.y" { /* generic syntax with a type modifier */ PGTypeName *t = makeTypeNameFromNameList((yyvsp[(1) - (7)].list)); @@ -318900,196 +333347,201 @@ YYLTYPE yylloc; ;} break; - case 1109: -#line 3657 "third_party/libpg_query/grammar/statements/select.y" + case 1131: +#line 3660 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeStringConstCast((yyvsp[(2) - (2)].str), (yylsp[(2) - (2)]), (yyvsp[(1) - (2)].typnam)); ;} break; - case 1110: -#line 3661 "third_party/libpg_query/grammar/statements/select.y" + case 1132: +#line 3664 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeIntervalNode((yyvsp[(3) - (5)].node), (yylsp[(3) - (5)]), (yyvsp[(5) - (5)].list)); ;} break; - case 1111: -#line 3665 "third_party/libpg_query/grammar/statements/select.y" + case 1133: +#line 3668 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeIntervalNode((yyvsp[(2) - (3)].ival), (yylsp[(2) - (3)]), (yyvsp[(3) - (3)].list)); ;} break; - case 1112: -#line 3669 "third_party/libpg_query/grammar/statements/select.y" + case 1134: +#line 3672 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeIntervalNode((yyvsp[(2) - (3)].str), (yylsp[(2) - (3)]), (yyvsp[(3) - (3)].list)); ;} break; - case 1113: -#line 3673 "third_party/libpg_query/grammar/statements/select.y" + case 1135: +#line 3676 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeBoolAConst(true, (yylsp[(1) - (1)])); ;} break; - case 1114: -#line 3677 "third_party/libpg_query/grammar/statements/select.y" + case 1136: +#line 3680 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeBoolAConst(false, (yylsp[(1) - (1)])); ;} break; - case 1115: -#line 3681 "third_party/libpg_query/grammar/statements/select.y" + case 1137: +#line 3684 "third_party/libpg_query/grammar/statements/select.y" { (yyval.node) = makeNullAConst((yylsp[(1) - (1)])); ;} break; - case 1116: -#line 3686 "third_party/libpg_query/grammar/statements/select.y" + case 1138: +#line 3689 "third_party/libpg_query/grammar/statements/select.y" { (yyval.ival) = (yyvsp[(1) - (1)].ival); ;} break; - case 1117: -#line 3687 "third_party/libpg_query/grammar/statements/select.y" + case 1139: +#line 3690 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1118: -#line 3703 "third_party/libpg_query/grammar/statements/select.y" + case 1140: +#line 3706 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1119: -#line 3704 "third_party/libpg_query/grammar/statements/select.y" + case 1141: +#line 3707 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1120: -#line 3705 "third_party/libpg_query/grammar/statements/select.y" + case 1142: +#line 3708 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1121: -#line 3708 "third_party/libpg_query/grammar/statements/select.y" + case 1143: +#line 3711 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1122: -#line 3709 "third_party/libpg_query/grammar/statements/select.y" + case 1144: +#line 3712 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1123: -#line 3715 "third_party/libpg_query/grammar/statements/select.y" + case 1145: +#line 3718 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1124: -#line 3716 "third_party/libpg_query/grammar/statements/select.y" + case 1146: +#line 3719 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1125: -#line 3717 "third_party/libpg_query/grammar/statements/select.y" + case 1147: +#line 3720 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1126: -#line 3720 "third_party/libpg_query/grammar/statements/select.y" + case 1148: +#line 3723 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1127: -#line 3721 "third_party/libpg_query/grammar/statements/select.y" + case 1149: +#line 3724 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1128: -#line 3722 "third_party/libpg_query/grammar/statements/select.y" + case 1150: +#line 3725 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1129: -#line 3725 "third_party/libpg_query/grammar/statements/select.y" + case 1151: +#line 3728 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1130: -#line 3726 "third_party/libpg_query/grammar/statements/select.y" + case 1152: +#line 3729 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1131: -#line 3727 "third_party/libpg_query/grammar/statements/select.y" + case 1153: +#line 3730 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1132: -#line 3730 "third_party/libpg_query/grammar/statements/select.y" + case 1154: +#line 3733 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} break; - case 1133: -#line 3731 "third_party/libpg_query/grammar/statements/select.y" + case 1155: +#line 3734 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lcons(makeString((yyvsp[(1) - (2)].str)), (yyvsp[(2) - (2)].list)); ;} break; - case 1134: -#line 3735 "third_party/libpg_query/grammar/statements/select.y" + case 1156: +#line 3738 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = list_make1(makeString((yyvsp[(2) - (2)].str))); ;} break; - case 1135: -#line 3737 "third_party/libpg_query/grammar/statements/select.y" + case 1157: +#line 3740 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), makeString((yyvsp[(3) - (3)].str))); ;} break; - case 1136: -#line 3741 "third_party/libpg_query/grammar/statements/select.y" + case 1158: +#line 3744 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = (yyvsp[(2) - (3)].list); ;} break; - case 1137: -#line 3742 "third_party/libpg_query/grammar/statements/select.y" + case 1159: +#line 3745 "third_party/libpg_query/grammar/statements/select.y" { (yyval.list) = NIL; ;} break; - case 1139: -#line 3753 "third_party/libpg_query/grammar/statements/select.y" + case 1161: +#line 3756 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1140: -#line 3754 "third_party/libpg_query/grammar/statements/select.y" + case 1162: +#line 3757 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1141: -#line 3755 "third_party/libpg_query/grammar/statements/select.y" + case 1163: +#line 3758 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1142: -#line 3756 "third_party/libpg_query/grammar/statements/select.y" + case 1164: +#line 3759 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1143: -#line 3759 "third_party/libpg_query/grammar/statements/select.y" + case 1165: +#line 3762 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1144: -#line 3760 "third_party/libpg_query/grammar/statements/select.y" + case 1166: +#line 3763 "third_party/libpg_query/grammar/statements/select.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1145: + case 1167: +#line 3766 "third_party/libpg_query/grammar/statements/select.y" + { (yyval.str) = (yyvsp[(1) - (1)].str); ;} + break; + + case 1168: #line 8 "third_party/libpg_query/grammar/statements/prepare.y" { PGPrepareStmt *n = makeNode(PGPrepareStmt); @@ -319100,34 +333552,54 @@ YYLTYPE yylloc; ;} break; - case 1146: + case 1169: #line 18 "third_party/libpg_query/grammar/statements/prepare.y" { (yyval.list) = (yyvsp[(2) - (3)].list); ;} break; - case 1147: + case 1170: #line 19 "third_party/libpg_query/grammar/statements/prepare.y" { (yyval.list) = NIL; ;} break; - case 1152: + case 1175: #line 8 "third_party/libpg_query/grammar/statements/create_schema.y" { PGCreateSchemaStmt *n = makeNode(PGCreateSchemaStmt); - /* ...but not both */ - n->schemaname = (yyvsp[(3) - (4)].str); + if ((yyvsp[(3) - (4)].range)->catalogname) { + ereport(ERROR, + (errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("CREATE SCHEMA too many dots: expected \"catalog.schema\" or \"schema\""), + parser_errposition((yylsp[(3) - (4)])))); + } + if ((yyvsp[(3) - (4)].range)->schemaname) { + n->catalogname = (yyvsp[(3) - (4)].range)->schemaname; + n->schemaname = (yyvsp[(3) - (4)].range)->relname; + } else { + n->schemaname = (yyvsp[(3) - (4)].range)->relname; + } n->schemaElts = (yyvsp[(4) - (4)].list); n->onconflict = PG_ERROR_ON_CONFLICT; (yyval.node) = (PGNode *)n; ;} break; - case 1153: -#line 17 "third_party/libpg_query/grammar/statements/create_schema.y" + case 1176: +#line 27 "third_party/libpg_query/grammar/statements/create_schema.y" { PGCreateSchemaStmt *n = makeNode(PGCreateSchemaStmt); - /* ...but not here */ - n->schemaname = (yyvsp[(6) - (7)].str); + if ((yyvsp[(6) - (7)].range)->catalogname) { + ereport(ERROR, + (errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("CREATE SCHEMA too many dots: expected \"catalog.schema\" or \"schema\""), + parser_errposition((yylsp[(6) - (7)])))); + } + if ((yyvsp[(6) - (7)].range)->schemaname) { + n->catalogname = (yyvsp[(6) - (7)].range)->schemaname; + n->schemaname = (yyvsp[(6) - (7)].range)->relname; + } else { + n->schemaname = (yyvsp[(6) - (7)].range)->relname; + } if ((yyvsp[(7) - (7)].list) != NIL) ereport(ERROR, (errcode(PG_ERRCODE_FEATURE_NOT_SUPPORTED), @@ -319139,8 +333611,8 @@ YYLTYPE yylloc; ;} break; - case 1154: -#line 35 "third_party/libpg_query/grammar/statements/create_schema.y" + case 1177: +#line 55 "third_party/libpg_query/grammar/statements/create_schema.y" { if ((yyloc) < 0) /* see comments for YYLLOC_DEFAULT */ (yyloc) = (yylsp[(2) - (2)]); @@ -319148,12 +333620,12 @@ YYLTYPE yylloc; ;} break; - case 1155: -#line 41 "third_party/libpg_query/grammar/statements/create_schema.y" + case 1178: +#line 61 "third_party/libpg_query/grammar/statements/create_schema.y" { (yyval.list) = NIL; ;} break; - case 1160: + case 1183: #line 11 "third_party/libpg_query/grammar/statements/index.y" { PGIndexStmt *n = makeNode(PGIndexStmt); @@ -319179,7 +333651,7 @@ YYLTYPE yylloc; ;} break; - case 1161: + case 1184: #line 36 "third_party/libpg_query/grammar/statements/index.y" { PGIndexStmt *n = makeNode(PGIndexStmt); @@ -319205,62 +333677,62 @@ YYLTYPE yylloc; ;} break; - case 1162: + case 1185: #line 62 "third_party/libpg_query/grammar/statements/index.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1163: + case 1186: #line 66 "third_party/libpg_query/grammar/statements/index.y" { (yyval.str) = (yyvsp[(2) - (2)].str); ;} break; - case 1164: + case 1187: #line 67 "third_party/libpg_query/grammar/statements/index.y" { (yyval.str) = (char*) DEFAULT_INDEX_TYPE; ;} break; - case 1165: + case 1188: #line 72 "third_party/libpg_query/grammar/statements/index.y" { (yyval.boolean) = true; ;} break; - case 1166: + case 1189: #line 73 "third_party/libpg_query/grammar/statements/index.y" { (yyval.boolean) = false; ;} break; - case 1167: + case 1190: #line 78 "third_party/libpg_query/grammar/statements/index.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1168: + case 1191: #line 79 "third_party/libpg_query/grammar/statements/index.y" { (yyval.str) = NULL; ;} break; - case 1169: + case 1192: #line 83 "third_party/libpg_query/grammar/statements/index.y" { (yyval.list) = (yyvsp[(2) - (2)].list); ;} break; - case 1170: + case 1193: #line 84 "third_party/libpg_query/grammar/statements/index.y" { (yyval.list) = NIL; ;} break; - case 1171: + case 1194: #line 89 "third_party/libpg_query/grammar/statements/index.y" { (yyval.boolean) = true; ;} break; - case 1172: + case 1195: #line 90 "third_party/libpg_query/grammar/statements/index.y" { (yyval.boolean) = false; ;} break; - case 1173: + case 1196: #line 8 "third_party/libpg_query/grammar/statements/alter_schema.y" { PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt); @@ -319272,7 +333744,7 @@ YYLTYPE yylloc; ;} break; - case 1174: + case 1197: #line 17 "third_party/libpg_query/grammar/statements/alter_schema.y" { PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt); @@ -319284,7 +333756,7 @@ YYLTYPE yylloc; ;} break; - case 1175: + case 1198: #line 26 "third_party/libpg_query/grammar/statements/alter_schema.y" { PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt); @@ -319296,7 +333768,7 @@ YYLTYPE yylloc; ;} break; - case 1176: + case 1199: #line 35 "third_party/libpg_query/grammar/statements/alter_schema.y" { PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt); @@ -319308,7 +333780,7 @@ YYLTYPE yylloc; ;} break; - case 1177: + case 1200: #line 44 "third_party/libpg_query/grammar/statements/alter_schema.y" { PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt); @@ -319320,7 +333792,7 @@ YYLTYPE yylloc; ;} break; - case 1178: + case 1201: #line 53 "third_party/libpg_query/grammar/statements/alter_schema.y" { PGAlterObjectSchemaStmt *n = makeNode(PGAlterObjectSchemaStmt); @@ -319332,28 +333804,41 @@ YYLTYPE yylloc; ;} break; - case 1179: + case 1202: #line 6 "third_party/libpg_query/grammar/statements/checkpoint.y" { PGCheckPointStmt *n = makeNode(PGCheckPointStmt); n->force = true; + n->name = (yyvsp[(3) - (3)].str); (yyval.node) = (PGNode *)n; ;} break; - case 1180: -#line 12 "third_party/libpg_query/grammar/statements/checkpoint.y" + case 1203: +#line 13 "third_party/libpg_query/grammar/statements/checkpoint.y" { PGCheckPointStmt *n = makeNode(PGCheckPointStmt); n->force = false; + n->name = (yyvsp[(2) - (2)].str); (yyval.node) = (PGNode *)n; ;} break; - case 1181: + case 1204: +#line 22 "third_party/libpg_query/grammar/statements/checkpoint.y" + { (yyval.str) = (yyvsp[(1) - (1)].str); ;} + break; + + case 1205: +#line 23 "third_party/libpg_query/grammar/statements/checkpoint.y" + { (yyval.str) = NULL; ;} + break; + + case 1206: #line 8 "third_party/libpg_query/grammar/statements/export.y" { PGExportStmt *n = makeNode(PGExportStmt); + n->database = NULL; n->filename = (yyvsp[(3) - (4)].str); n->options = NIL; if ((yyvsp[(4) - (4)].list)) { @@ -319363,8 +333848,22 @@ YYLTYPE yylloc; ;} break; - case 1182: -#line 21 "third_party/libpg_query/grammar/statements/export.y" + case 1207: +#line 20 "third_party/libpg_query/grammar/statements/export.y" + { + PGExportStmt *n = makeNode(PGExportStmt); + n->database = (yyvsp[(3) - (6)].str); + n->filename = (yyvsp[(5) - (6)].str); + n->options = NIL; + if ((yyvsp[(6) - (6)].list)) { + n->options = list_concat(n->options, (yyvsp[(6) - (6)].list)); + } + (yyval.node) = (PGNode *)n; + ;} + break; + + case 1208: +#line 34 "third_party/libpg_query/grammar/statements/export.y" { PGImportStmt *n = makeNode(PGImportStmt); n->filename = (yyvsp[(3) - (3)].str); @@ -319372,7 +333871,7 @@ YYLTYPE yylloc; ;} break; - case 1183: + case 1209: #line 10 "third_party/libpg_query/grammar/statements/explain.y" { PGExplainStmt *n = makeNode(PGExplainStmt); @@ -319382,7 +333881,7 @@ YYLTYPE yylloc; ;} break; - case 1184: + case 1210: #line 17 "third_party/libpg_query/grammar/statements/explain.y" { PGExplainStmt *n = makeNode(PGExplainStmt); @@ -319395,7 +333894,7 @@ YYLTYPE yylloc; ;} break; - case 1185: + case 1211: #line 27 "third_party/libpg_query/grammar/statements/explain.y" { PGExplainStmt *n = makeNode(PGExplainStmt); @@ -319405,7 +333904,7 @@ YYLTYPE yylloc; ;} break; - case 1186: + case 1212: #line 34 "third_party/libpg_query/grammar/statements/explain.y" { PGExplainStmt *n = makeNode(PGExplainStmt); @@ -319415,118 +333914,118 @@ YYLTYPE yylloc; ;} break; - case 1187: + case 1213: #line 44 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.boolean) = true; ;} break; - case 1188: + case 1214: #line 45 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.boolean) = false; ;} break; - case 1189: + case 1215: #line 50 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.node) = (PGNode *) makeString((yyvsp[(1) - (1)].str)); ;} break; - case 1190: + case 1216: #line 51 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.node) = (PGNode *) (yyvsp[(1) - (1)].value); ;} break; - case 1191: + case 1217: #line 52 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.node) = NULL; ;} break; - case 1222: + case 1248: #line 90 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1223: + case 1249: #line 91 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1224: + case 1250: #line 92 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = pstrdup((yyvsp[(1) - (1)].keyword)); ;} break; - case 1225: + case 1251: #line 97 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1226: + case 1252: #line 98 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1227: + case 1253: #line 104 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].defelt)); ;} break; - case 1228: + case 1254: #line 108 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].defelt)); ;} break; - case 1229: + case 1255: #line 115 "third_party/libpg_query/grammar/statements/explain.y" {;} break; - case 1230: + case 1256: #line 116 "third_party/libpg_query/grammar/statements/explain.y" {;} break; - case 1231: + case 1257: #line 121 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (char*) "true"; ;} break; - case 1232: + case 1258: #line 122 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (char*) "false"; ;} break; - case 1233: + case 1259: #line 123 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (char*) "on"; ;} break; - case 1234: + case 1260: #line 129 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1235: + case 1261: #line 135 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.defelt) = makeDefElem((yyvsp[(1) - (2)].str), (yyvsp[(2) - (2)].node), (yylsp[(1) - (2)])); ;} break; - case 1236: + case 1262: #line 142 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1237: + case 1263: #line 143 "third_party/libpg_query/grammar/statements/explain.y" { (yyval.str) = (char*) "analyze"; ;} break; - case 1238: + case 1264: #line 11 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = (yyvsp[(2) - (2)].vsetstmt); @@ -319535,7 +334034,7 @@ YYLTYPE yylloc; ;} break; - case 1239: + case 1265: #line 17 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = (yyvsp[(3) - (3)].vsetstmt); @@ -319544,7 +334043,7 @@ YYLTYPE yylloc; ;} break; - case 1240: + case 1266: #line 23 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = (yyvsp[(3) - (3)].vsetstmt); @@ -319553,7 +334052,7 @@ YYLTYPE yylloc; ;} break; - case 1241: + case 1267: #line 29 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = (yyvsp[(3) - (3)].vsetstmt); @@ -319562,12 +334061,12 @@ YYLTYPE yylloc; ;} break; - case 1242: + case 1268: #line 38 "third_party/libpg_query/grammar/statements/variable_set.y" {(yyval.vsetstmt) = (yyvsp[(1) - (1)].vsetstmt);;} break; - case 1243: + case 1269: #line 40 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -319577,7 +334076,7 @@ YYLTYPE yylloc; ;} break; - case 1244: + case 1270: #line 48 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -319591,7 +334090,7 @@ YYLTYPE yylloc; ;} break; - case 1245: + case 1271: #line 59 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -319602,7 +334101,7 @@ YYLTYPE yylloc; ;} break; - case 1246: + case 1272: #line 71 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -319613,7 +334112,7 @@ YYLTYPE yylloc; ;} break; - case 1247: + case 1273: #line 79 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -319624,7 +334123,7 @@ YYLTYPE yylloc; ;} break; - case 1248: + case 1274: #line 87 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -319634,7 +334133,7 @@ YYLTYPE yylloc; ;} break; - case 1249: + case 1275: #line 94 "third_party/libpg_query/grammar/statements/variable_set.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); @@ -319644,31 +334143,31 @@ YYLTYPE yylloc; ;} break; - case 1250: + case 1276: #line 104 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.node) = makeStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)])); ;} break; - case 1251: + case 1277: #line 106 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.node) = makeAConst((yyvsp[(1) - (1)].value), (yylsp[(1) - (1)])); ;} break; - case 1252: + case 1278: #line 112 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.node) = makeStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)])); ;} break; - case 1253: + case 1279: #line 116 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.node) = makeStringConst((yyvsp[(1) - (1)].str), (yylsp[(1) - (1)])); ;} break; - case 1254: + case 1280: #line 120 "third_party/libpg_query/grammar/statements/variable_set.y" { PGTypeName *t = (yyvsp[(1) - (3)].typnam); @@ -319686,7 +334185,7 @@ YYLTYPE yylloc; ;} break; - case 1255: + case 1281: #line 135 "third_party/libpg_query/grammar/statements/variable_set.y" { PGTypeName *t = (yyvsp[(1) - (5)].typnam); @@ -319696,32 +334195,32 @@ YYLTYPE yylloc; ;} break; - case 1256: + case 1282: #line 141 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.node) = makeAConst((yyvsp[(1) - (1)].value), (yylsp[(1) - (1)])); ;} break; - case 1257: + case 1283: #line 142 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.node) = NULL; ;} break; - case 1258: + case 1284: #line 143 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.node) = NULL; ;} break; - case 1259: + case 1285: #line 147 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.list) = list_make1((yyvsp[(1) - (1)].node)); ;} break; - case 1260: + case 1286: #line 148 "third_party/libpg_query/grammar/statements/variable_set.y" { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].node)); ;} break; - case 1261: + case 1287: #line 8 "third_party/libpg_query/grammar/statements/load.y" { PGLoadStmt *n = makeNode(PGLoadStmt); @@ -319731,7 +334230,7 @@ YYLTYPE yylloc; ;} break; - case 1262: + case 1288: #line 14 "third_party/libpg_query/grammar/statements/load.y" { PGLoadStmt *n = makeNode(PGLoadStmt); @@ -319741,7 +334240,7 @@ YYLTYPE yylloc; ;} break; - case 1263: + case 1289: #line 20 "third_party/libpg_query/grammar/statements/load.y" { PGLoadStmt *n = makeNode(PGLoadStmt); @@ -319751,17 +334250,17 @@ YYLTYPE yylloc; ;} break; - case 1264: + case 1290: #line 28 "third_party/libpg_query/grammar/statements/load.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1265: + case 1291: #line 29 "third_party/libpg_query/grammar/statements/load.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1266: + case 1292: #line 9 "third_party/libpg_query/grammar/statements/vacuum.y" { PGVacuumStmt *n = makeNode(PGVacuumStmt); @@ -319778,7 +334277,7 @@ YYLTYPE yylloc; ;} break; - case 1267: + case 1293: #line 23 "third_party/libpg_query/grammar/statements/vacuum.y" { PGVacuumStmt *n = makeNode(PGVacuumStmt); @@ -319795,7 +334294,7 @@ YYLTYPE yylloc; ;} break; - case 1268: + case 1294: #line 37 "third_party/libpg_query/grammar/statements/vacuum.y" { PGVacuumStmt *n = (PGVacuumStmt *) (yyvsp[(5) - (5)].node); @@ -319810,7 +334309,7 @@ YYLTYPE yylloc; ;} break; - case 1269: + case 1295: #line 49 "third_party/libpg_query/grammar/statements/vacuum.y" { PGVacuumStmt *n = makeNode(PGVacuumStmt); @@ -319821,7 +334320,7 @@ YYLTYPE yylloc; ;} break; - case 1270: + case 1296: #line 57 "third_party/libpg_query/grammar/statements/vacuum.y" { PGVacuumStmt *n = makeNode(PGVacuumStmt); @@ -319834,27 +334333,27 @@ YYLTYPE yylloc; ;} break; - case 1271: + case 1297: #line 70 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.ival) = PG_VACOPT_ANALYZE; ;} break; - case 1272: + case 1298: #line 71 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.ival) = PG_VACOPT_VERBOSE; ;} break; - case 1273: + case 1299: #line 72 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.ival) = PG_VACOPT_FREEZE; ;} break; - case 1274: + case 1300: #line 73 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.ival) = PG_VACOPT_FULL; ;} break; - case 1275: + case 1301: #line 75 "third_party/libpg_query/grammar/statements/vacuum.y" { if (strcmp((yyvsp[(1) - (1)].str), "disable_page_skipping") == 0) @@ -319867,37 +334366,37 @@ YYLTYPE yylloc; ;} break; - case 1276: + case 1302: #line 87 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.boolean) = true; ;} break; - case 1277: + case 1303: #line 88 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.boolean) = false; ;} break; - case 1278: + case 1304: #line 93 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.ival) = (yyvsp[(1) - (1)].ival); ;} break; - case 1279: + case 1305: #line 94 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.ival) = (yyvsp[(1) - (3)].ival) | (yyvsp[(3) - (3)].ival); ;} break; - case 1280: + case 1306: #line 98 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.boolean) = true; ;} break; - case 1281: + case 1307: #line 99 "third_party/libpg_query/grammar/statements/vacuum.y" { (yyval.boolean) = false; ;} break; - case 1282: + case 1308: #line 9 "third_party/libpg_query/grammar/statements/delete.y" { PGDeleteStmt *n = makeNode(PGDeleteStmt); @@ -319910,7 +334409,7 @@ YYLTYPE yylloc; ;} break; - case 1283: + case 1309: #line 19 "third_party/libpg_query/grammar/statements/delete.y" { PGDeleteStmt *n = makeNode(PGDeleteStmt); @@ -319923,14 +334422,14 @@ YYLTYPE yylloc; ;} break; - case 1284: + case 1310: #line 32 "third_party/libpg_query/grammar/statements/delete.y" { (yyval.range) = (yyvsp[(1) - (1)].range); ;} break; - case 1285: + case 1311: #line 36 "third_party/libpg_query/grammar/statements/delete.y" { PGAlias *alias = makeNode(PGAlias); @@ -319940,7 +334439,7 @@ YYLTYPE yylloc; ;} break; - case 1286: + case 1312: #line 43 "third_party/libpg_query/grammar/statements/delete.y" { PGAlias *alias = makeNode(PGAlias); @@ -319950,27 +334449,27 @@ YYLTYPE yylloc; ;} break; - case 1287: + case 1313: #line 53 "third_party/libpg_query/grammar/statements/delete.y" { (yyval.node) = (yyvsp[(2) - (2)].node); ;} break; - case 1288: + case 1314: #line 54 "third_party/libpg_query/grammar/statements/delete.y" { (yyval.node) = NULL; ;} break; - case 1289: + case 1315: #line 60 "third_party/libpg_query/grammar/statements/delete.y" { (yyval.list) = (yyvsp[(2) - (2)].list); ;} break; - case 1290: + case 1316: #line 61 "third_party/libpg_query/grammar/statements/delete.y" { (yyval.list) = NIL; ;} break; - case 1291: + case 1317: #line 10 "third_party/libpg_query/grammar/statements/analyze.y" { PGVacuumStmt *n = makeNode(PGVacuumStmt); @@ -319983,7 +334482,7 @@ YYLTYPE yylloc; ;} break; - case 1292: + case 1318: #line 20 "third_party/libpg_query/grammar/statements/analyze.y" { PGVacuumStmt *n = makeNode(PGVacuumStmt); @@ -319996,37 +334495,124 @@ YYLTYPE yylloc; ;} break; - case 1293: + case 1319: +#line 8 "third_party/libpg_query/grammar/statements/attach.y" + { + PGAttachStmt *n = makeNode(PGAttachStmt); + n->path = (yyvsp[(3) - (5)].str); + n->name = (yyvsp[(4) - (5)].str); + n->options = (yyvsp[(5) - (5)].list); + (yyval.node) = (PGNode *)n; + ;} + break; + + case 1320: +#line 19 "third_party/libpg_query/grammar/statements/attach.y" + { + PGDropStmt *n = makeNode(PGDropStmt); + n->removeType = PG_OBJECT_DATABASE; + n->missing_ok = false; + n->objects = (yyvsp[(3) - (3)].list); + n->behavior = PG_DROP_RESTRICT; + n->concurrent = false; + (yyval.node) = (PGNode *)n; + ;} + break; + + case 1321: +#line 29 "third_party/libpg_query/grammar/statements/attach.y" + { + PGDropStmt *n = makeNode(PGDropStmt); + n->removeType = PG_OBJECT_DATABASE; + n->missing_ok = false; + n->objects = (yyvsp[(2) - (2)].list); + n->behavior = PG_DROP_RESTRICT; + n->concurrent = false; + (yyval.node) = (PGNode *)n; + ;} + break; + + case 1322: +#line 39 "third_party/libpg_query/grammar/statements/attach.y" + { + PGDropStmt *n = makeNode(PGDropStmt); + n->removeType = PG_OBJECT_DATABASE; + n->missing_ok = true; + n->objects = (yyvsp[(5) - (5)].list); + n->behavior = PG_DROP_RESTRICT; + n->concurrent = false; + (yyval.node) = (PGNode *)n; + ;} + break; + + case 1323: +#line 50 "third_party/libpg_query/grammar/statements/attach.y" + {;} + break; + + case 1324: +#line 51 "third_party/libpg_query/grammar/statements/attach.y" + {;} + break; + + case 1325: +#line 55 "third_party/libpg_query/grammar/statements/attach.y" + { (yyval.str) = (yyvsp[(2) - (2)].str); ;} + break; + + case 1326: +#line 56 "third_party/libpg_query/grammar/statements/attach.y" + { (yyval.str) = NULL; ;} + break; + + case 1327: +#line 59 "third_party/libpg_query/grammar/statements/attach.y" + { (yyval.list) = list_make1(makeString((yyvsp[(1) - (1)].str))); ;} + break; + + case 1328: +#line 62 "third_party/libpg_query/grammar/statements/attach.y" + { (yyval.list) = list_make1((yyvsp[(1) - (1)].list)); ;} + break; + + case 1329: +#line 63 "third_party/libpg_query/grammar/statements/attach.y" + { (yyval.list) = lappend((yyvsp[(1) - (3)].list), (yyvsp[(3) - (3)].list)); ;} + break; + + case 1330: #line 2 "third_party/libpg_query/grammar/statements/variable_reset.y" { (yyval.node) = (PGNode *) (yyvsp[(2) - (2)].vsetstmt); ;} break; - case 1294: + case 1331: #line 8 "third_party/libpg_query/grammar/statements/variable_reset.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); n->kind = VAR_RESET; + n->scope = VAR_SET_SCOPE_GLOBAL; n->name = (yyvsp[(1) - (1)].str); (yyval.vsetstmt) = n; ;} break; - case 1295: -#line 15 "third_party/libpg_query/grammar/statements/variable_reset.y" + case 1332: +#line 16 "third_party/libpg_query/grammar/statements/variable_reset.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); n->kind = VAR_RESET_ALL; + n->scope = VAR_SET_SCOPE_GLOBAL; (yyval.vsetstmt) = n; ;} break; - case 1296: -#line 24 "third_party/libpg_query/grammar/statements/variable_reset.y" + case 1333: +#line 26 "third_party/libpg_query/grammar/statements/variable_reset.y" { (yyval.vsetstmt) = (yyvsp[(1) - (1)].vsetstmt); ;} break; - case 1297: -#line 26 "third_party/libpg_query/grammar/statements/variable_reset.y" + case 1334: +#line 28 "third_party/libpg_query/grammar/statements/variable_reset.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); n->kind = VAR_RESET; @@ -320035,8 +334621,8 @@ YYLTYPE yylloc; ;} break; - case 1298: -#line 33 "third_party/libpg_query/grammar/statements/variable_reset.y" + case 1335: +#line 35 "third_party/libpg_query/grammar/statements/variable_reset.y" { PGVariableSetStmt *n = makeNode(PGVariableSetStmt); n->kind = VAR_RESET; @@ -320045,7 +334631,7 @@ YYLTYPE yylloc; ;} break; - case 1299: + case 1336: #line 3 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowSelectStmt *n = makeNode(PGVariableShowSelectStmt); @@ -320056,7 +334642,7 @@ YYLTYPE yylloc; ;} break; - case 1300: + case 1337: #line 10 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowSelectStmt *n = makeNode(PGVariableShowSelectStmt); @@ -320067,7 +334653,7 @@ YYLTYPE yylloc; ;} break; - case 1301: + case 1338: #line 18 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowStmt *n = makeNode(PGVariableShowStmt); @@ -320077,7 +334663,7 @@ YYLTYPE yylloc; ;} break; - case 1302: + case 1339: #line 25 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowStmt *n = makeNode(PGVariableShowStmt); @@ -320087,7 +334673,7 @@ YYLTYPE yylloc; ;} break; - case 1303: + case 1340: #line 32 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowStmt *n = makeNode(PGVariableShowStmt); @@ -320097,7 +334683,7 @@ YYLTYPE yylloc; ;} break; - case 1304: + case 1341: #line 39 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowStmt *n = makeNode(PGVariableShowStmt); @@ -320107,7 +334693,7 @@ YYLTYPE yylloc; ;} break; - case 1305: + case 1342: #line 46 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowStmt *n = makeNode(PGVariableShowStmt); @@ -320117,7 +334703,7 @@ YYLTYPE yylloc; ;} break; - case 1306: + case 1343: #line 53 "third_party/libpg_query/grammar/statements/variable_show.y" { PGVariableShowStmt *n = makeNode(PGVariableShowStmt); @@ -320127,27 +334713,27 @@ YYLTYPE yylloc; ;} break; - case 1309: + case 1346: #line 63 "third_party/libpg_query/grammar/statements/variable_show.y" { (yyval.str) = (yyvsp[(1) - (1)].str); ;} break; - case 1310: + case 1347: #line 65 "third_party/libpg_query/grammar/statements/variable_show.y" { (yyval.str) = psprintf("%s.%s", (yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].str)); ;} break; - case 1311: + case 1348: #line 68 "third_party/libpg_query/grammar/statements/variable_show.y" { (yyval.str) = psprintf("\"%s\"", (yyvsp[(1) - (1)].str)); ;} break; - case 1312: + case 1349: #line 70 "third_party/libpg_query/grammar/statements/variable_show.y" { (yyval.str) = psprintf("%s.\"%s\"", (yyvsp[(1) - (3)].str), (yyvsp[(3) - (3)].str)); ;} break; - case 1313: + case 1350: #line 7 "third_party/libpg_query/grammar/statements/call.y" { PGCallStmt *n = makeNode(PGCallStmt); @@ -320156,7 +334742,7 @@ YYLTYPE yylloc; ;} break; - case 1314: + case 1351: #line 10 "third_party/libpg_query/grammar/statements/view.y" { PGViewStmt *n = makeNode(PGViewStmt); @@ -320171,8 +334757,23 @@ YYLTYPE yylloc; ;} break; - case 1315: + case 1352: #line 23 "third_party/libpg_query/grammar/statements/view.y" + { + PGViewStmt *n = makeNode(PGViewStmt); + n->view = (yyvsp[(7) - (12)].range); + n->view->relpersistence = (yyvsp[(2) - (12)].ival); + n->aliases = (yyvsp[(8) - (12)].list); + n->query = (yyvsp[(11) - (12)].node); + n->onconflict = PG_IGNORE_ON_CONFLICT; + n->options = (yyvsp[(9) - (12)].list); + n->withCheckOption = (yyvsp[(12) - (12)].viewcheckoption); + (yyval.node) = (PGNode *) n; + ;} + break; + + case 1353: +#line 36 "third_party/libpg_query/grammar/statements/view.y" { PGViewStmt *n = makeNode(PGViewStmt); n->view = (yyvsp[(6) - (11)].range); @@ -320186,8 +334787,8 @@ YYLTYPE yylloc; ;} break; - case 1316: -#line 36 "third_party/libpg_query/grammar/statements/view.y" + case 1354: +#line 49 "third_party/libpg_query/grammar/statements/view.y" { PGViewStmt *n = makeNode(PGViewStmt); n->view = (yyvsp[(5) - (12)].range); @@ -320206,8 +334807,8 @@ YYLTYPE yylloc; ;} break; - case 1317: -#line 54 "third_party/libpg_query/grammar/statements/view.y" + case 1355: +#line 67 "third_party/libpg_query/grammar/statements/view.y" { PGViewStmt *n = makeNode(PGViewStmt); n->view = (yyvsp[(7) - (14)].range); @@ -320226,27 +334827,27 @@ YYLTYPE yylloc; ;} break; - case 1318: -#line 74 "third_party/libpg_query/grammar/statements/view.y" + case 1356: +#line 87 "third_party/libpg_query/grammar/statements/view.y" { (yyval.viewcheckoption) = CASCADED_CHECK_OPTION; ;} break; - case 1319: -#line 75 "third_party/libpg_query/grammar/statements/view.y" + case 1357: +#line 88 "third_party/libpg_query/grammar/statements/view.y" { (yyval.viewcheckoption) = CASCADED_CHECK_OPTION; ;} break; - case 1320: -#line 76 "third_party/libpg_query/grammar/statements/view.y" + case 1358: +#line 89 "third_party/libpg_query/grammar/statements/view.y" { (yyval.viewcheckoption) = PG_LOCAL_CHECK_OPTION; ;} break; - case 1321: -#line 77 "third_party/libpg_query/grammar/statements/view.y" + case 1359: +#line 90 "third_party/libpg_query/grammar/statements/view.y" { (yyval.viewcheckoption) = PG_NO_CHECK_OPTION; ;} break; - case 1322: + case 1360: #line 12 "third_party/libpg_query/grammar/statements/create_as.y" { PGCreateTableAsStmt *ctas = makeNode(PGCreateTableAsStmt); @@ -320262,7 +334863,7 @@ YYLTYPE yylloc; ;} break; - case 1323: + case 1361: #line 25 "third_party/libpg_query/grammar/statements/create_as.y" { PGCreateTableAsStmt *ctas = makeNode(PGCreateTableAsStmt); @@ -320278,7 +334879,7 @@ YYLTYPE yylloc; ;} break; - case 1324: + case 1362: #line 38 "third_party/libpg_query/grammar/statements/create_as.y" { PGCreateTableAsStmt *ctas = makeNode(PGCreateTableAsStmt); @@ -320294,22 +334895,22 @@ YYLTYPE yylloc; ;} break; - case 1325: + case 1363: #line 54 "third_party/libpg_query/grammar/statements/create_as.y" { (yyval.boolean) = true; ;} break; - case 1326: + case 1364: #line 55 "third_party/libpg_query/grammar/statements/create_as.y" { (yyval.boolean) = false; ;} break; - case 1327: + case 1365: #line 56 "third_party/libpg_query/grammar/statements/create_as.y" { (yyval.boolean) = true; ;} break; - case 1328: + case 1366: #line 62 "third_party/libpg_query/grammar/statements/create_as.y" { (yyval.into) = makeNode(PGIntoClause); @@ -320324,7 +334925,7 @@ YYLTYPE yylloc; /* Line 1267 of yacc.c. */ -#line 26643 "third_party/libpg_query/grammar/grammar_out.cpp" +#line 27480 "third_party/libpg_query/grammar/grammar_out.cpp" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -320893,6 +335494,17 @@ static PGNode* makeParamRef(int number, int location) PGParamRef *p = makeNode(PGParamRef); p->number = number; p->location = location; + p->name = NULL; + return (PGNode *) p; +} + +/* makeNamedParamRef + * Creates a new PGParamRef node + */ +static PGNode* makeNamedParamRef(char *name, int location) +{ + PGParamRef *p = (PGParamRef *)makeParamRef(0, location); + p->name = name; return (PGNode *) p; } @@ -321644,6 +336256,7 @@ PG_KEYWORD("placing", PLACING, RESERVED_KEYWORD) PG_KEYWORD("plans", PLANS, UNRESERVED_KEYWORD) PG_KEYWORD("policy", POLICY, UNRESERVED_KEYWORD) PG_KEYWORD("position", POSITION, COL_NAME_KEYWORD) +PG_KEYWORD("positional", POSITIONAL, TYPE_FUNC_NAME_KEYWORD) PG_KEYWORD("pragma", PRAGMA_P, UNRESERVED_KEYWORD) PG_KEYWORD("preceding", PRECEDING, UNRESERVED_KEYWORD) PG_KEYWORD("precision", PRECISION, COL_NAME_KEYWORD) @@ -321770,6 +336383,7 @@ PG_KEYWORD("unlisten", UNLISTEN, UNRESERVED_KEYWORD) PG_KEYWORD("unlogged", UNLOGGED, UNRESERVED_KEYWORD) PG_KEYWORD("until", UNTIL, UNRESERVED_KEYWORD) PG_KEYWORD("update", UPDATE, UNRESERVED_KEYWORD) +PG_KEYWORD("use", USE_P, UNRESERVED_KEYWORD) PG_KEYWORD("user", USER, TYPE_FUNC_NAME_KEYWORD) PG_KEYWORD("using", USING, RESERVED_KEYWORD) PG_KEYWORD("vacuum", VACUUM, UNRESERVED_KEYWORD) @@ -322601,7 +337215,7 @@ struct yy_buffer_state /* Size of input buffer in bytes, not including room for EOB * characters. */ - int yy_buf_size; + yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. @@ -324344,7 +338958,6 @@ YY_RULE_SETUP { /* no UESCAPE after the quote, throw back everything */ char *ident; - int identlen; yyless(0); @@ -324352,7 +338965,6 @@ YY_RULE_SETUP if (yyextra->literallen == 0) yyerror("zero-length delimited identifier"); ident = litbuf_udeescape('\\', yyscanner); - identlen = strlen(ident); yylval->str = ident; return IDENT; } @@ -324360,11 +338972,10 @@ YY_RULE_SETUP case 56: /* rule 56 can match eol */ YY_RULE_SETUP -#line 773 "third_party/libpg_query/scan.l" +#line 771 "third_party/libpg_query/scan.l" { /* found UESCAPE after the end quote */ char *ident; - int identlen; BEGIN(INITIAL); if (yyextra->literallen == 0) @@ -324376,14 +338987,13 @@ YY_RULE_SETUP yyerror("invalid Unicode escape character"); } ident = litbuf_udeescape(yytext[yyleng - 2], yyscanner); - identlen = strlen(ident); yylval->str = ident; return IDENT; } YY_BREAK case 57: YY_RULE_SETUP -#line 792 "third_party/libpg_query/scan.l" +#line 788 "third_party/libpg_query/scan.l" { addlitchar('"', yyscanner); } @@ -324391,19 +339001,19 @@ YY_RULE_SETUP case 58: /* rule 58 can match eol */ YY_RULE_SETUP -#line 795 "third_party/libpg_query/scan.l" +#line 791 "third_party/libpg_query/scan.l" { addlit(yytext, yyleng, yyscanner); } YY_BREAK case YY_STATE_EOF(xd): case YY_STATE_EOF(xui): -#line 798 "third_party/libpg_query/scan.l" +#line 794 "third_party/libpg_query/scan.l" { yyerror("unterminated quoted identifier"); } YY_BREAK case 59: YY_RULE_SETUP -#line 800 "third_party/libpg_query/scan.l" +#line 796 "third_party/libpg_query/scan.l" { char *ident; @@ -324418,7 +339028,7 @@ YY_RULE_SETUP YY_BREAK case 60: YY_RULE_SETUP -#line 812 "third_party/libpg_query/scan.l" +#line 808 "third_party/libpg_query/scan.l" { SET_YYLLOC(); return TYPECAST; @@ -324426,7 +339036,7 @@ YY_RULE_SETUP YY_BREAK case 61: YY_RULE_SETUP -#line 817 "third_party/libpg_query/scan.l" +#line 813 "third_party/libpg_query/scan.l" { SET_YYLLOC(); return DOT_DOT; @@ -324434,7 +339044,7 @@ YY_RULE_SETUP YY_BREAK case 62: YY_RULE_SETUP -#line 822 "third_party/libpg_query/scan.l" +#line 818 "third_party/libpg_query/scan.l" { SET_YYLLOC(); return COLON_EQUALS; @@ -324442,7 +339052,7 @@ YY_RULE_SETUP YY_BREAK case 63: YY_RULE_SETUP -#line 827 "third_party/libpg_query/scan.l" +#line 823 "third_party/libpg_query/scan.l" { SET_YYLLOC(); return LAMBDA_ARROW; @@ -324450,7 +339060,7 @@ YY_RULE_SETUP YY_BREAK case 64: YY_RULE_SETUP -#line 832 "third_party/libpg_query/scan.l" +#line 828 "third_party/libpg_query/scan.l" { SET_YYLLOC(); return DOUBLE_ARROW; @@ -324458,7 +339068,7 @@ YY_RULE_SETUP YY_BREAK case 65: YY_RULE_SETUP -#line 837 "third_party/libpg_query/scan.l" +#line 833 "third_party/libpg_query/scan.l" { SET_YYLLOC(); return POWER_OF; @@ -324466,7 +339076,7 @@ YY_RULE_SETUP YY_BREAK case 66: YY_RULE_SETUP -#line 842 "third_party/libpg_query/scan.l" +#line 838 "third_party/libpg_query/scan.l" { SET_YYLLOC(); return EQUALS_GREATER; @@ -324474,7 +339084,7 @@ YY_RULE_SETUP YY_BREAK case 67: YY_RULE_SETUP -#line 847 "third_party/libpg_query/scan.l" +#line 843 "third_party/libpg_query/scan.l" { SET_YYLLOC(); return LESS_EQUALS; @@ -324482,7 +339092,7 @@ YY_RULE_SETUP YY_BREAK case 68: YY_RULE_SETUP -#line 852 "third_party/libpg_query/scan.l" +#line 848 "third_party/libpg_query/scan.l" { SET_YYLLOC(); return GREATER_EQUALS; @@ -324490,7 +339100,7 @@ YY_RULE_SETUP YY_BREAK case 69: YY_RULE_SETUP -#line 857 "third_party/libpg_query/scan.l" +#line 853 "third_party/libpg_query/scan.l" { /* We accept both "<>" and "!=" as meaning NOT_EQUALS */ SET_YYLLOC(); @@ -324499,7 +339109,7 @@ YY_RULE_SETUP YY_BREAK case 70: YY_RULE_SETUP -#line 863 "third_party/libpg_query/scan.l" +#line 859 "third_party/libpg_query/scan.l" { /* We accept both "<>" and "!=" as meaning NOT_EQUALS */ SET_YYLLOC(); @@ -324508,7 +339118,7 @@ YY_RULE_SETUP YY_BREAK case 71: YY_RULE_SETUP -#line 869 "third_party/libpg_query/scan.l" +#line 865 "third_party/libpg_query/scan.l" { SET_YYLLOC(); return yytext[0]; @@ -324516,7 +339126,7 @@ YY_RULE_SETUP YY_BREAK case 72: YY_RULE_SETUP -#line 874 "third_party/libpg_query/scan.l" +#line 870 "third_party/libpg_query/scan.l" { /* * Check for embedded slash-star or dash-dash; those @@ -324636,7 +339246,7 @@ YY_RULE_SETUP YY_BREAK case 73: YY_RULE_SETUP -#line 991 "third_party/libpg_query/scan.l" +#line 987 "third_party/libpg_query/scan.l" { SET_YYLLOC(); yylval->ival = atol(yytext + 1); @@ -324645,7 +339255,7 @@ YY_RULE_SETUP YY_BREAK case 74: YY_RULE_SETUP -#line 997 "third_party/libpg_query/scan.l" +#line 993 "third_party/libpg_query/scan.l" { SET_YYLLOC(); yylval->ival = atol(yytext + 1); @@ -324654,7 +339264,7 @@ YY_RULE_SETUP YY_BREAK case 75: YY_RULE_SETUP -#line 1003 "third_party/libpg_query/scan.l" +#line 999 "third_party/libpg_query/scan.l" { SET_YYLLOC(); return process_integer_literal(yytext, yylval); @@ -324662,7 +339272,7 @@ YY_RULE_SETUP YY_BREAK case 76: YY_RULE_SETUP -#line 1007 "third_party/libpg_query/scan.l" +#line 1003 "third_party/libpg_query/scan.l" { SET_YYLLOC(); yylval->str = pstrdup(yytext); @@ -324671,7 +339281,7 @@ YY_RULE_SETUP YY_BREAK case 77: YY_RULE_SETUP -#line 1012 "third_party/libpg_query/scan.l" +#line 1008 "third_party/libpg_query/scan.l" { /* throw back the .., and treat as integer */ yyless(yyleng - 2); @@ -324681,7 +339291,7 @@ YY_RULE_SETUP YY_BREAK case 78: YY_RULE_SETUP -#line 1018 "third_party/libpg_query/scan.l" +#line 1014 "third_party/libpg_query/scan.l" { SET_YYLLOC(); yylval->str = pstrdup(yytext); @@ -324690,7 +339300,7 @@ YY_RULE_SETUP YY_BREAK case 79: YY_RULE_SETUP -#line 1023 "third_party/libpg_query/scan.l" +#line 1019 "third_party/libpg_query/scan.l" { /* * throw back the [Ee], and treat as {decimal}. Note @@ -324706,7 +339316,7 @@ YY_RULE_SETUP YY_BREAK case 80: YY_RULE_SETUP -#line 1035 "third_party/libpg_query/scan.l" +#line 1031 "third_party/libpg_query/scan.l" { /* throw back the [Ee][+-], and proceed as above */ yyless(yyleng - 2); @@ -324717,7 +339327,7 @@ YY_RULE_SETUP YY_BREAK case 81: YY_RULE_SETUP -#line 1044 "third_party/libpg_query/scan.l" +#line 1040 "third_party/libpg_query/scan.l" { const PGScanKeyword *keyword; char *ident; @@ -324738,7 +339348,7 @@ YY_RULE_SETUP if (keyword_text[yyleng - 1] == '\0') { yyless(yyleng - 1); } - yylval->keyword = keyword->name; + yylval->keyword = keyword_text; return keyword->value; } @@ -324753,14 +339363,14 @@ YY_RULE_SETUP YY_BREAK case 82: YY_RULE_SETUP -#line 1077 "third_party/libpg_query/scan.l" +#line 1073 "third_party/libpg_query/scan.l" { SET_YYLLOC(); return yytext[0]; } YY_BREAK case YY_STATE_EOF(INITIAL): -#line 1082 "third_party/libpg_query/scan.l" +#line 1078 "third_party/libpg_query/scan.l" { SET_YYLLOC(); yyterminate(); @@ -324768,10 +339378,10 @@ case YY_STATE_EOF(INITIAL): YY_BREAK case 83: YY_RULE_SETUP -#line 1087 "third_party/libpg_query/scan.l" +#line 1083 "third_party/libpg_query/scan.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 2661 "third_party/libpg_query/src_backend_parser_scan.cpp" +#line 2657 "third_party/libpg_query/src_backend_parser_scan.cpp" case YY_END_OF_BUFFER: { @@ -325896,7 +340506,7 @@ static int yy_flex_strlen (const char * s , yyscan_t yyscanner) #define YYTABLES_NAME "yytables" -#line 1087 "third_party/libpg_query/scan.l" +#line 1083 "third_party/libpg_query/scan.l" /* LCOV_EXCL_STOP */ @@ -334358,7 +348968,7 @@ void mpi_mul_hlp( size_t i, mbedtls_mpi_uint *d, mbedtls_mpi_uint b ) { - mbedtls_mpi_uint c = 0, t = 0; + mbedtls_mpi_uint c = 0; #if defined(MULADDC_HUIT) for( ; i >= 8; i -= 8 ) @@ -334409,8 +349019,6 @@ void mpi_mul_hlp( size_t i, } #endif /* MULADDC_HUIT */ - t++; - while( c != 0 ) { *d += c; c = ( *d < c ); d++; diff --git a/libduckdb-sys/duckdb/duckdb.h b/libduckdb-sys/duckdb/duckdb.h index 7a564706..878dd804 100644 --- a/libduckdb-sys/duckdb/duckdb.h +++ b/libduckdb-sys/duckdb/duckdb.h @@ -119,10 +119,10 @@ typedef enum DUCKDB_TYPE { DUCKDB_TYPE_MAP, // duckdb_hugeint DUCKDB_TYPE_UUID, - // const char* - DUCKDB_TYPE_JSON, // union type, only useful as logical type DUCKDB_TYPE_UNION, + // duckdb_bit + DUCKDB_TYPE_BIT, } duckdb_type; //! Days are stored as days since 1970-01-01 @@ -192,6 +192,11 @@ typedef struct { idx_t size; } duckdb_blob; +typedef struct { + uint64_t offset; + uint64_t length; +} duckdb_list_entry; + typedef struct { #if DUCKDB_API_VERSION < DUCKDB_API_0_3_2 void *data; @@ -233,19 +238,48 @@ typedef struct { void *internal_data; } duckdb_result; -typedef void *duckdb_database; -typedef void *duckdb_connection; -typedef void *duckdb_prepared_statement; -typedef void *duckdb_pending_result; -typedef void *duckdb_appender; -typedef void *duckdb_arrow; -typedef void *duckdb_config; -typedef void *duckdb_arrow_schema; -typedef void *duckdb_arrow_array; -typedef void *duckdb_logical_type; -typedef void *duckdb_data_chunk; -typedef void *duckdb_vector; -typedef void *duckdb_value; +typedef struct _duckdb_database { + void *__db; +} * duckdb_database; +typedef struct _duckdb_connection { + void *__conn; +} * duckdb_connection; +typedef struct _duckdb_prepared_statement { + void *__prep; +} * duckdb_prepared_statement; +typedef struct _duckdb_extracted_statements { + void *__extrac; +} * duckdb_extracted_statements; +typedef struct _duckdb_pending_result { + void *__pend; +} * duckdb_pending_result; +typedef struct _duckdb_appender { + void *__appn; +} * duckdb_appender; +typedef struct _duckdb_arrow { + void *__arrw; +} * duckdb_arrow; +typedef struct _duckdb_config { + void *__cnfg; +} * duckdb_config; +typedef struct _duckdb_arrow_schema { + void *__arrs; +} * duckdb_arrow_schema; +typedef struct _duckdb_arrow_array { + void *__arra; +} * duckdb_arrow_array; +typedef struct _duckdb_logical_type { + void *__lglt; +} * duckdb_logical_type; +typedef struct _duckdb_data_chunk { + void *__dtck; +} * duckdb_data_chunk; +typedef struct _duckdb_vector { + void *__vctr; +} * duckdb_vector; +typedef struct _duckdb_value { + void *__val; +} * duckdb_value; typedef enum { DuckDBSuccess = 0, DuckDBError = 1 } duckdb_state; typedef enum { @@ -1007,6 +1041,53 @@ Executes the prepared statement with the given bound parameters, and returns an DUCKDB_API duckdb_state duckdb_execute_prepared_arrow(duckdb_prepared_statement prepared_statement, duckdb_arrow *out_result); +//===--------------------------------------------------------------------===// +// Extract Statements +//===--------------------------------------------------------------------===// +// A query string can be extracted into multiple SQL statements. Each statement can be prepared and executed separately. + +/*! +Extract all statements from a query. +Note that after calling `duckdb_extract_statements`, the extracted statements should always be destroyed using +`duckdb_destroy_extracted`, even if no statements were extracted. +If the extract fails, `duckdb_extract_statements_error` can be called to obtain the reason why the extract failed. +* connection: The connection object +* query: The SQL query to extract +* out_extracted_statements: The resulting extracted statements object +* returns: The number of extracted statements or 0 on failure. +*/ +DUCKDB_API idx_t duckdb_extract_statements(duckdb_connection connection, const char *query, + duckdb_extracted_statements *out_extracted_statements); + +/*! +Prepare an extracted statement. +Note that after calling `duckdb_prepare_extracted_statement`, the prepared statement should always be destroyed using +`duckdb_destroy_prepare`, even if the prepare fails. +If the prepare fails, `duckdb_prepare_error` can be called to obtain the reason why the prepare failed. +* connection: The connection object +* extracted_statements: The extracted statements object +* index: The index of the extracted statement to prepare +* out_prepared_statement: The resulting prepared statement object +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_prepare_extracted_statement(duckdb_connection connection, + duckdb_extracted_statements extracted_statements, + idx_t index, + duckdb_prepared_statement *out_prepared_statement); +/*! +Returns the error message contained within the extracted statements. +The result of this function must not be freed. It will be cleaned up when `duckdb_destroy_extracted` is called. +* result: The extracted statements to fetch the error from. +* returns: The error of the extracted statements. +*/ +DUCKDB_API const char *duckdb_extract_statements_error(duckdb_extracted_statements extracted_statements); + +/*! +De-allocates all memory allocated for the extracted statements. +* extracted_statements: The extracted statements to destroy. +*/ +DUCKDB_API void duckdb_destroy_extracted(duckdb_extracted_statements *extracted_statements); + //===--------------------------------------------------------------------===// // Pending Result Interface //===--------------------------------------------------------------------===// @@ -1153,6 +1234,17 @@ The resulting type should be destroyed with `duckdb_destroy_logical_type`. */ DUCKDB_API duckdb_logical_type duckdb_create_map_type(duckdb_logical_type key_type, duckdb_logical_type value_type); +/*! +Creates a UNION type from the passed types array +The resulting type should be destroyed with `duckdb_destroy_logical_type`. + +* types: The array of types that the union should consist of. +* type_amount: The size of the types array. +* returns: The logical type. +*/ +DUCKDB_API duckdb_logical_type duckdb_create_union_type(duckdb_logical_type member_types, const char **member_names, + idx_t member_count); + /*! Creates a `duckdb_logical_type` of type decimal with the specified width and scale The resulting type should be destroyed with `duckdb_destroy_logical_type`. @@ -1282,6 +1374,36 @@ The result must be freed with `duckdb_destroy_logical_type` */ DUCKDB_API duckdb_logical_type duckdb_struct_type_child_type(duckdb_logical_type type, idx_t index); +/*! +Returns the number of members that the union type has. + +* type: The logical type (union) object +* returns: The number of members of a union type. +*/ +DUCKDB_API idx_t duckdb_union_type_member_count(duckdb_logical_type type); + +/*! +Retrieves the name of the union member. + +The result must be freed with `duckdb_free` + +* type: The logical type object +* index: The child index +* returns: The name of the union member. Must be freed with `duckdb_free`. +*/ +DUCKDB_API char *duckdb_union_type_member_name(duckdb_logical_type type, idx_t index); + +/*! +Retrieves the child type of the given union member at the specified index. + +The result must be freed with `duckdb_destroy_logical_type` + +* type: The logical type object +* index: The child index +* returns: The child type of the union member. Must be destroyed with `duckdb_destroy_logical_type`. +*/ +DUCKDB_API duckdb_logical_type duckdb_union_type_member_type(duckdb_logical_type type, idx_t index); + /*! Destroys the logical type and de-allocates all memory allocated for that type. @@ -1444,6 +1566,24 @@ Returns the size of the child vector of the list */ DUCKDB_API idx_t duckdb_list_vector_get_size(duckdb_vector vector); +/*! +Sets the total size of the underlying child-vector of a list vector. + +* vector: The list vector. +* size: The size of the child list. +* returns: The duckdb state. Returns DuckDBError if the vector is nullptr. +*/ +DUCKDB_API duckdb_state duckdb_list_vector_set_size(duckdb_vector vector, idx_t size); + +/*! +Sets the total capacity of the underlying child-vector of a list. + +* vector: The list vector. +* required_capacity: the total capacity to reserve. +* return: The duckdb state. Returns DuckDBError if the vector is nullptr. +*/ +DUCKDB_API duckdb_state duckdb_list_vector_reserve(duckdb_vector vector, idx_t required_capacity); + /*! Retrieves the child vector of a struct vector. @@ -2172,6 +2312,13 @@ on the task state. */ DUCKDB_API void duckdb_destroy_task_state(duckdb_task_state state); +/*! +Returns true if execution of the current query is finished. + +* con: The connection on which to check +*/ +DUCKDB_API bool duckdb_execution_is_finished(duckdb_connection con); + #ifdef __cplusplus } #endif diff --git a/libduckdb-sys/duckdb/duckdb.hpp b/libduckdb-sys/duckdb/duckdb.hpp index 2cf38ab2..70921a1e 100644 --- a/libduckdb-sys/duckdb/duckdb.hpp +++ b/libduckdb-sys/duckdb/duckdb.hpp @@ -1,5 +1,5 @@ /* -Copyright 2018-2022 Stichting DuckDB Foundation +Copyright 2018-2023 Stichting DuckDB Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: @@ -10,8 +10,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI #pragma once #define DUCKDB_AMALGAMATION 1 -#define DUCKDB_SOURCE_ID "919cad22e8" -#define DUCKDB_VERSION "v0.6.1" +#define DUCKDB_SOURCE_ID "f7827396d7" +#define DUCKDB_VERSION "v0.7.0" //===----------------------------------------------------------------------===// // DuckDB // @@ -128,7 +128,9 @@ namespace duckdb { #endif //! inline std directives that we use frequently +#ifndef DUCKDB_DEBUG_MOVE using std::move; +#endif using std::shared_ptr; using std::unique_ptr; using std::weak_ptr; @@ -136,9 +138,14 @@ using data_ptr = unique_ptr; using std::make_shared; // NOTE: there is a copy of this in the Postgres' parser grammar (gram.y) -#define DEFAULT_SCHEMA "main" -#define TEMP_SCHEMA "temp" -#define INVALID_SCHEMA "" +#define DEFAULT_SCHEMA "main" +#define INVALID_SCHEMA "" +#define INVALID_CATALOG "" +#define SYSTEM_CATALOG "system" +#define TEMP_CATALOG "temp" + +DUCKDB_API bool IsInvalidSchema(const string &str); +DUCKDB_API bool IsInvalidCatalog(const string &str); //! a saner size_t for loop indices etc typedef uint64_t idx_t; @@ -237,7 +244,7 @@ struct PhysicalIndex { } }; -uint64_t NextPowerOfTwo(uint64_t v); +DUCKDB_API uint64_t NextPowerOfTwo(uint64_t v); } // namespace duckdb @@ -348,6 +355,14 @@ struct UniqueConstructor { } }; +#ifdef DUCKDB_DEBUG_MOVE +template +typename std::remove_reference::type&& move(T&& t) noexcept { + // the nonsensical sizeof check ensures this is never instantiated + static_assert(sizeof(T) == 0, "Use std::move instead of unqualified move or duckdb::move"); +} +#endif + template T MaxValue(T a, T b) { return a > b ? a : b; @@ -433,6 +448,10 @@ void AssignSharedPointer(shared_ptr &target, const shared_ptr &source) { #include #define D_ASSERT assert +namespace duckdb { +DUCKDB_API void DuckDBAssertInternal(bool condition, const char *condition_name, const char *file, int linenr); +} + #else namespace duckdb { DUCKDB_API void DuckDBAssertInternal(bool condition, const char *condition_name, const char *file, int linenr); @@ -685,8 +704,9 @@ struct hugeint_t { public: DUCKDB_API hugeint_t() = default; DUCKDB_API hugeint_t(int64_t value); // NOLINT: Allow implicit conversion from `int64_t` - DUCKDB_API hugeint_t(const hugeint_t &rhs) = default; - DUCKDB_API hugeint_t(hugeint_t &&rhs) = default; + DUCKDB_API constexpr hugeint_t(int64_t upper, uint64_t lower): lower(lower), upper(upper) {}; + DUCKDB_API constexpr hugeint_t(const hugeint_t &rhs) = default; + DUCKDB_API constexpr hugeint_t(hugeint_t &&rhs) = default; DUCKDB_API hugeint_t &operator=(const hugeint_t &rhs) = default; DUCKDB_API hugeint_t &operator=(hugeint_t &&rhs) = default; @@ -847,9 +867,6 @@ enum class PhysicalType : uint8_t { ///// ArrayData struct //DICTIONARY = 26, - /// Map, a repeated struct logical type - MAP = 27, - ///// Custom data type, implemented by user //EXTENSION = 28, @@ -912,7 +929,7 @@ enum class LogicalTypeId : uint8_t { UBIGINT = 31, TIMESTAMP_TZ = 32, TIME_TZ = 34, - JSON = 35, + BIT = 36, HUGEINT = 50, POINTER = 51, @@ -969,7 +986,7 @@ struct LogicalType { inline LogicalType& operator=(LogicalType&& other) noexcept { id_ = other.id_; physical_type_ = other.physical_type_; - type_info_ = move(other.type_info_); + type_info_ = std::move(other.type_info_); return *this; } @@ -1045,7 +1062,8 @@ struct LogicalType { static constexpr const LogicalTypeId VARCHAR = LogicalTypeId::VARCHAR; static constexpr const LogicalTypeId ANY = LogicalTypeId::ANY; static constexpr const LogicalTypeId BLOB = LogicalTypeId::BLOB; - static constexpr const LogicalTypeId INTERVAL = LogicalTypeId::INTERVAL; + static constexpr const LogicalTypeId BIT = LogicalTypeId::BIT; + static constexpr const LogicalTypeId INTERVAL = LogicalTypeId::INTERVAL; static constexpr const LogicalTypeId HUGEINT = LogicalTypeId::HUGEINT; static constexpr const LogicalTypeId UUID = LogicalTypeId::UUID; static constexpr const LogicalTypeId HASH = LogicalTypeId::UBIGINT; @@ -1053,7 +1071,6 @@ struct LogicalType { static constexpr const LogicalTypeId TABLE = LogicalTypeId::TABLE; static constexpr const LogicalTypeId LAMBDA = LogicalTypeId::LAMBDA; static constexpr const LogicalTypeId INVALID = LogicalTypeId::INVALID; - static constexpr const LogicalTypeId JSON = LogicalTypeId::JSON; static constexpr const LogicalTypeId ROW_TYPE = LogicalTypeId::BIGINT; // explicitly allowing these functions to be capitalized to be in-line with the remaining functions @@ -1062,11 +1079,11 @@ struct LogicalType { DUCKDB_API static LogicalType LIST( LogicalType child); // NOLINT DUCKDB_API static LogicalType STRUCT( child_list_t children); // NOLINT DUCKDB_API static LogicalType AGGREGATE_STATE(aggregate_state_t state_type); // NOLINT + DUCKDB_API static LogicalType MAP(LogicalType child); // NOLINT DUCKDB_API static LogicalType MAP( child_list_t children); // NOLINT DUCKDB_API static LogicalType MAP(LogicalType key, LogicalType value); // NOLINT DUCKDB_API static LogicalType UNION( child_list_t members); // NOLINT DUCKDB_API static LogicalType ENUM(const string &enum_name, Vector &ordered_data, idx_t size); // NOLINT - DUCKDB_API static LogicalType DEDUP_POINTER_ENUM(); // NOLINT DUCKDB_API static LogicalType USER(const string &user_type_name); // NOLINT //! A list of all NUMERIC types (integral and floating point types) DUCKDB_API static const vector Numeric(); @@ -1136,21 +1153,23 @@ DUCKDB_API LogicalTypeId TransformStringToLogicalTypeId(const string &str); DUCKDB_API LogicalType TransformStringToLogicalType(const string &str); +DUCKDB_API LogicalType TransformStringToLogicalType(const string &str, ClientContext &context); + //! The PhysicalType used by the row identifiers column extern const PhysicalType ROW_TYPE; DUCKDB_API string TypeIdToString(PhysicalType type); -idx_t GetTypeIdSize(PhysicalType type); -bool TypeIsConstantSize(PhysicalType type); -bool TypeIsIntegral(PhysicalType type); -bool TypeIsNumeric(PhysicalType type); -bool TypeIsInteger(PhysicalType type); +DUCKDB_API idx_t GetTypeIdSize(PhysicalType type); +DUCKDB_API bool TypeIsConstantSize(PhysicalType type); +DUCKDB_API bool TypeIsIntegral(PhysicalType type); +DUCKDB_API bool TypeIsNumeric(PhysicalType type); +DUCKDB_API bool TypeIsInteger(PhysicalType type); bool ApproxEqual(float l, float r); bool ApproxEqual(double l, double r); struct aggregate_state_t { - aggregate_state_t(string function_name_p, LogicalType return_type_p, vector bound_argument_types_p) : function_name(move(function_name_p)), return_type(move(return_type_p)), bound_argument_types(move(bound_argument_types_p)) { + aggregate_state_t(string function_name_p, LogicalType return_type_p, vector bound_argument_types_p) : function_name(std::move(function_name_p)), return_type(std::move(return_type_p)), bound_argument_types(std::move(bound_argument_types_p)) { } string function_name; @@ -1683,16 +1702,16 @@ class Deserializer { } template - void ReadList(vector> &list, ARGS &&...args) { + void ReadList(vector> &list, ARGS &&... args) { auto select_count = Read(); for (uint32_t i = 0; i < select_count; i++) { auto child = T::Deserialize(*this, std::forward(args)...); - list.push_back(move(child)); + list.push_back(std::move(child)); } } template - unique_ptr ReadOptional(ARGS &&...args) { + unique_ptr ReadOptional(ARGS &&... args) { auto has_entry = Read(); if (has_entry) { return T::Deserialize(*this, std::forward(args)...); @@ -1719,6 +1738,27 @@ DUCKDB_API string Deserializer::Read(); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/file_compression_type.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +enum class FileCompressionType : uint8_t { AUTO_DETECT = 0, UNCOMPRESSED = 1, GZIP = 2, ZSTD = 3 }; + +FileCompressionType FileCompressionTypeFromString(const string &input); + +} // namespace duckdb + + //===----------------------------------------------------------------------===// // DuckDB // @@ -1760,14 +1800,8 @@ class FileBuffer { public: //! Read into the FileBuffer from the specified location. void Read(FileHandle &handle, uint64_t location); - //! Read into the FileBuffer from the specified location. Automatically verifies the checksum, and throws an - //! exception if the checksum does not match correctly. - virtual void ReadAndChecksum(FileHandle &handle, uint64_t location); //! Write the contents of the FileBuffer to the specified location. void Write(FileHandle &handle, uint64_t location); - //! Write the contents of the FileBuffer to the specified location. Automatically adds a checksum of the contents of - //! the filebuffer in front of the written data. - virtual void ChecksumAndWrite(FileHandle &handle, uint64_t location); void Clear(); @@ -1778,6 +1812,9 @@ class FileBuffer { uint64_t AllocSize() const { return internal_size; } + data_ptr_t InternalBuffer() { + return internal_buffer; + } struct MemoryRequirement { idx_t alloc_size; @@ -1793,22 +1830,11 @@ class FileBuffer { uint64_t internal_size; void ReallocBuffer(size_t malloc_size); - -private: - //! The buffer that was actually malloc'd, i.e. the pointer that must be freed when the FileBuffer is destroyed - data_ptr_t malloced_buffer; - uint64_t malloced_size; - -protected: - uint64_t GetMallocedSize() { - return malloced_size; - } void Init(); }; } // namespace duckdb - //===----------------------------------------------------------------------===// // DuckDB // @@ -1826,26 +1852,6 @@ using std::unordered_map; } -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/enums/file_compression_type.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { - -enum class FileCompressionType : uint8_t { AUTO_DETECT = 0, UNCOMPRESSED = 1, GZIP = 2, ZSTD = 3 }; - -FileCompressionType FileCompressionTypeFromString(const string &input); - -} // namespace duckdb - #include @@ -1854,6 +1860,7 @@ FileCompressionType FileCompressionTypeFromString(const string &input); #undef RemoveDirectory namespace duckdb { +class AttachedDatabase; class ClientContext; class DatabaseInstance; class FileOpener; @@ -1939,6 +1946,7 @@ class FileSystem { DUCKDB_API static constexpr FileCompressionType DEFAULT_COMPRESSION = FileCompressionType::UNCOMPRESSED; DUCKDB_API static FileSystem &GetFileSystem(ClientContext &context); DUCKDB_API static FileSystem &GetFileSystem(DatabaseInstance &db); + DUCKDB_API static FileSystem &Get(AttachedDatabase &db); DUCKDB_API static FileOpener *GetFileOpener(ClientContext &context); DUCKDB_API virtual unique_ptr OpenFile(const string &path, uint8_t flags, @@ -1958,6 +1966,8 @@ class FileSystem { //! Write nr_bytes from the buffer into the file, moving the file pointer forward by nr_bytes. DUCKDB_API virtual int64_t Write(FileHandle &handle, void *buffer, int64_t nr_bytes); + //! Returns the extension of the file, or empty string if no extension was found. + DUCKDB_API string GetFileExtension(FileHandle &handle); //! Returns the file size of a file handle, returns -1 on error DUCKDB_API virtual int64_t GetFileSize(FileHandle &handle); //! Returns the file last modified time of a file handle, returns timespec with zero on all attributes on error @@ -1976,7 +1986,9 @@ class FileSystem { DUCKDB_API virtual void RemoveDirectory(const string &directory); //! List files in a directory, invoking the callback method for each one with (filename, is_dir) DUCKDB_API virtual bool ListFiles(const string &directory, - const std::function &callback); + const std::function &callback, + FileOpener *opener = nullptr); + //! Move a file from source path to the target, StorageManager relies on this being an atomic action for ACID //! properties DUCKDB_API virtual void MoveFile(const string &source, const string &target); @@ -2006,8 +2018,10 @@ class FileSystem { DUCKDB_API static string JoinPath(const string &a, const string &path); //! Convert separators in a path to the local separators (e.g. convert "/" into \\ on windows) DUCKDB_API static string ConvertSeparators(const string &path); - //! Extract the base name of a file (e.g. if the input is lib/example.dll the base name is example) + //! Extract the base name of a file (e.g. if the input is lib/example.dll the base name is 'example') DUCKDB_API static string ExtractBaseName(const string &path); + //! Extract the name of a file (e.g if the input is lib/example.dll the name is 'example.dll') + DUCKDB_API static string ExtractName(const string &path); //! Runs a glob on the file system, returning a list of matching files DUCKDB_API virtual vector Glob(const string &path, FileOpener *opener = nullptr); @@ -2017,6 +2031,12 @@ class FileSystem { DUCKDB_API virtual void RegisterSubSystem(unique_ptr sub_fs); DUCKDB_API virtual void RegisterSubSystem(FileCompressionType compression_type, unique_ptr fs); + //! Unregister a sub-filesystem by name + DUCKDB_API virtual void UnregisterSubSystem(const string &name); + + //! List registered sub-filesystems, including builtin ones + DUCKDB_API virtual vector ListSubSystems(); + //! Whether or not a sub-system can handle a specific file path DUCKDB_API virtual bool CanHandleFile(const string &fpath); @@ -2037,7 +2057,6 @@ class FileSystem { //! Create a LocalFileSystem. DUCKDB_API static unique_ptr CreateLocal(); -protected: //! Return the name of the filesytem. Used for forming diagnosis messages. DUCKDB_API virtual std::string GetName() const = 0; }; @@ -2235,10 +2254,31 @@ struct SelectionVector { Initialize(sel_vector); } explicit SelectionVector(buffer_ptr data) { - Initialize(move(data)); + Initialize(std::move(data)); + } + SelectionVector &operator=(SelectionVector &&other) { + sel_vector = other.sel_vector; + other.sel_vector = nullptr; + selection_data = std::move(other.selection_data); + return *this; } public: + static idx_t Inverted(const SelectionVector &src, SelectionVector &dst, idx_t source_size, idx_t count) { + idx_t src_idx = 0; + idx_t dst_idx = 0; + for (idx_t i = 0; i < count; i++) { + if (src_idx < source_size && src.get_index(src_idx) == i) { + src_idx++; + // This index is selected by 'src', skip it in 'dst' + continue; + } + // This index does not exist in 'src', add it to the selection of 'dst' + dst.set_index(dst_idx++, i); + } + return dst_idx; + } + void Initialize(sel_t *sel) { selection_data.reset(); sel_vector = sel; @@ -2248,7 +2288,7 @@ struct SelectionVector { sel_vector = selection_data->owned_data.get(); } void Initialize(buffer_ptr data) { - selection_data = move(data); + selection_data = std::move(data); sel_vector = selection_data->owned_data.get(); } void Initialize(const SelectionVector &other) { @@ -2292,8 +2332,11 @@ struct SelectionVector { class OptionalSelection { public: - explicit inline OptionalSelection(SelectionVector *sel_p) : sel(sel_p) { - + explicit inline OptionalSelection(SelectionVector *sel_p) { + Initialize(sel_p); + } + void Initialize(SelectionVector *sel_p) { + sel = sel_p; if (sel) { vec.Initialize(sel->data()); sel = &vec; @@ -2322,6 +2365,62 @@ class OptionalSelection { SelectionVector vec; }; +// Contains a selection vector, combined with a count +class ManagedSelection { +public: + explicit inline ManagedSelection(idx_t size, bool initialize = true) + : initialized(initialize), size(size), internal_opt_selvec(nullptr) { + count = 0; + if (!initialized) { + return; + } + sel_vec.Initialize(size); + internal_opt_selvec.Initialize(&sel_vec); + } + +public: + bool Initialized() const { + return initialized; + } + void Initialize(idx_t size) { + D_ASSERT(!initialized); + this->size = size; + sel_vec.Initialize(size); + internal_opt_selvec.Initialize(&sel_vec); + initialized = true; + } + + inline idx_t operator[](idx_t index) const { + D_ASSERT(index < size); + return sel_vec.get_index(index); + } + inline bool IndexMapsToLocation(idx_t idx, idx_t location) const { + return idx < count && sel_vec.get_index(idx) == location; + } + inline void Append(const idx_t idx) { + internal_opt_selvec.Append(count, idx); + } + inline idx_t Count() const { + return count; + } + inline idx_t Size() const { + return size; + } + inline const SelectionVector &Selection() const { + return sel_vec; + } + inline SelectionVector &Selection() { + return sel_vec; + } + +private: + bool initialized = false; + idx_t count; + idx_t size; + SelectionVector sel_vec; + OptionalSelection internal_opt_selvec; +}; + } // namespace duckdb //===----------------------------------------------------------------------===// @@ -2422,15 +2521,7 @@ struct TemplatedValidityMask { return !validity_mask; } inline bool CheckAllValid(idx_t count) const { - if (AllValid()) { - return true; - } - idx_t entry_count = ValidityBuffer::EntryCount(count); - idx_t valid_count = 0; - for (idx_t i = 0; i < entry_count; i++) { - valid_count += validity_mask[i] == ValidityBuffer::MAX_ENTRY; - } - return valid_count == entry_count; + return CountValid(count) == count; } inline bool CheckAllValid(idx_t to, idx_t from) const { @@ -2714,20 +2805,33 @@ struct ValidityMask : public TemplatedValidityMask { +// Undef annoying windows macro +#undef max + +#include + namespace duckdb { template struct NumericLimits { - DUCKDB_API static T Minimum(); - DUCKDB_API static T Maximum(); + DUCKDB_API static constexpr T Minimum() { + return std::numeric_limits::lowest(); + }; + DUCKDB_API static constexpr T Maximum() { + return std::numeric_limits::max(); + }; DUCKDB_API static bool IsSigned(); DUCKDB_API static idx_t Digits(); }; template <> struct NumericLimits { - DUCKDB_API static int8_t Minimum(); - DUCKDB_API static int8_t Maximum(); + DUCKDB_API static constexpr int8_t Minimum() { + return std::numeric_limits::lowest(); + }; + DUCKDB_API static constexpr int8_t Maximum() { + return std::numeric_limits::max(); + }; DUCKDB_API static bool IsSigned() { return true; } @@ -2737,8 +2841,12 @@ struct NumericLimits { }; template <> struct NumericLimits { - DUCKDB_API static int16_t Minimum(); - DUCKDB_API static int16_t Maximum(); + DUCKDB_API static constexpr int16_t Minimum() { + return std::numeric_limits::lowest(); + }; + DUCKDB_API static constexpr int16_t Maximum() { + return std::numeric_limits::max(); + }; DUCKDB_API static bool IsSigned() { return true; } @@ -2748,8 +2856,12 @@ struct NumericLimits { }; template <> struct NumericLimits { - DUCKDB_API static int32_t Minimum(); - DUCKDB_API static int32_t Maximum(); + DUCKDB_API static constexpr int32_t Minimum() { + return std::numeric_limits::lowest(); + }; + DUCKDB_API static constexpr int32_t Maximum() { + return std::numeric_limits::max(); + }; DUCKDB_API static bool IsSigned() { return true; } @@ -2757,10 +2869,15 @@ struct NumericLimits { return 10; } }; + template <> struct NumericLimits { - DUCKDB_API static int64_t Minimum(); - DUCKDB_API static int64_t Maximum(); + DUCKDB_API static constexpr int64_t Minimum() { + return std::numeric_limits::lowest(); + }; + DUCKDB_API static constexpr int64_t Maximum() { + return std::numeric_limits::max(); + }; DUCKDB_API static bool IsSigned() { return true; } @@ -2770,8 +2887,12 @@ struct NumericLimits { }; template <> struct NumericLimits { - DUCKDB_API static hugeint_t Minimum(); - DUCKDB_API static hugeint_t Maximum(); + DUCKDB_API static constexpr hugeint_t Minimum() { + return {std::numeric_limits::lowest(), 1}; + }; + DUCKDB_API static constexpr hugeint_t Maximum() { + return {std::numeric_limits::max(), std::numeric_limits::max()}; + }; DUCKDB_API static bool IsSigned() { return true; } @@ -2779,10 +2900,15 @@ struct NumericLimits { return 39; } }; + template <> struct NumericLimits { - DUCKDB_API static uint8_t Minimum(); - DUCKDB_API static uint8_t Maximum(); + DUCKDB_API static constexpr uint8_t Minimum() { + return std::numeric_limits::lowest(); + }; + DUCKDB_API static constexpr uint8_t Maximum() { + return std::numeric_limits::max(); + }; DUCKDB_API static bool IsSigned() { return false; } @@ -2790,10 +2916,15 @@ struct NumericLimits { return 3; } }; + template <> struct NumericLimits { - DUCKDB_API static uint16_t Minimum(); - DUCKDB_API static uint16_t Maximum(); + DUCKDB_API static constexpr uint16_t Minimum() { + return std::numeric_limits::lowest(); + }; + DUCKDB_API static constexpr uint16_t Maximum() { + return std::numeric_limits::max(); + }; DUCKDB_API static bool IsSigned() { return false; } @@ -2803,8 +2934,12 @@ struct NumericLimits { }; template <> struct NumericLimits { - DUCKDB_API static uint32_t Minimum(); - DUCKDB_API static uint32_t Maximum(); + DUCKDB_API static constexpr uint32_t Minimum() { + return std::numeric_limits::lowest(); + }; + DUCKDB_API static constexpr uint32_t Maximum() { + return std::numeric_limits::max(); + }; DUCKDB_API static bool IsSigned() { return false; } @@ -2814,8 +2949,12 @@ struct NumericLimits { }; template <> struct NumericLimits { - DUCKDB_API static uint64_t Minimum(); - DUCKDB_API static uint64_t Maximum(); + DUCKDB_API static constexpr uint64_t Minimum() { + return std::numeric_limits::lowest(); + }; + DUCKDB_API static constexpr uint64_t Maximum() { + return std::numeric_limits::max(); + }; DUCKDB_API static bool IsSigned() { return false; } @@ -2825,8 +2964,12 @@ struct NumericLimits { }; template <> struct NumericLimits { - DUCKDB_API static float Minimum(); - DUCKDB_API static float Maximum(); + DUCKDB_API static constexpr float Minimum() { + return std::numeric_limits::lowest(); + }; + DUCKDB_API static constexpr float Maximum() { + return std::numeric_limits::max(); + }; DUCKDB_API static bool IsSigned() { return true; } @@ -2836,8 +2979,12 @@ struct NumericLimits { }; template <> struct NumericLimits { - DUCKDB_API static double Minimum(); - DUCKDB_API static double Maximum(); + DUCKDB_API static constexpr double Minimum() { + return std::numeric_limits::lowest(); + }; + DUCKDB_API static constexpr double Maximum() { + return std::numeric_limits::max(); + }; DUCKDB_API static bool IsSigned() { return true; } @@ -2848,90 +2995,259 @@ struct NumericLimits { } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/string_util.hpp +// +// +//===----------------------------------------------------------------------===// -#include -namespace duckdb { -struct date_t; -struct dtime_t; -//! Type used to represent timestamps (seconds,microseconds,milliseconds or nanoseconds since 1970-01-01) -struct timestamp_t { // NOLINT - int64_t value; - timestamp_t() = default; - explicit inline timestamp_t(int64_t value_p) : value(value_p) { +namespace duckdb { +/** + * String Utility Functions + * Note that these are not the most efficient implementations (i.e., they copy + * memory) and therefore they should only be used for debug messages and other + * such things. + */ +class StringUtil { +public: + DUCKDB_API static bool CharacterIsSpace(char c) { + return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; } - inline timestamp_t &operator=(int64_t value_p) { - value = value_p; - return *this; + DUCKDB_API static bool CharacterIsNewline(char c) { + return c == '\n' || c == '\r'; } - - // explicit conversion - explicit inline operator int64_t() const { - return value; + DUCKDB_API static bool CharacterIsDigit(char c) { + return c >= '0' && c <= '9'; + } + DUCKDB_API static bool CharacterIsHex(char c) { + return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); + } + DUCKDB_API static char CharacterToLower(char c) { + if (c >= 'A' && c <= 'Z') { + return c - ('A' - 'a'); + } + return c; + } + DUCKDB_API static char CharacterIsAlpha(char c) { + return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); + } + static bool CharacterIsOperator(char c) { + if (c == '_') { + return false; + } + if (c >= '!' && c <= '/') { + return true; + } + if (c >= ':' && c <= '@') { + return true; + } + if (c >= '[' && c <= '`') { + return true; + } + if (c >= '{' && c <= '~') { + return true; + } + return false; } - // comparison operators - inline bool operator==(const timestamp_t &rhs) const { - return value == rhs.value; - }; - inline bool operator!=(const timestamp_t &rhs) const { - return value != rhs.value; - }; - inline bool operator<=(const timestamp_t &rhs) const { - return value <= rhs.value; - }; - inline bool operator<(const timestamp_t &rhs) const { - return value < rhs.value; - }; - inline bool operator>(const timestamp_t &rhs) const { - return value > rhs.value; - }; - inline bool operator>=(const timestamp_t &rhs) const { - return value >= rhs.value; - }; + //! Returns true if the needle string exists in the haystack + DUCKDB_API static bool Contains(const string &haystack, const string &needle); - // arithmetic operators - inline timestamp_t operator+(const double &value) const { - return timestamp_t(this->value + int64_t(value)); - }; - inline int64_t operator-(const timestamp_t &other) const { - return this->value - other.value; - }; + //! Returns true if the target string starts with the given prefix + DUCKDB_API static bool StartsWith(string str, string prefix); - // in-place operators - inline timestamp_t &operator+=(const int64_t &value) { - this->value += value; - return *this; - }; - inline timestamp_t &operator-=(const int64_t &value) { - this->value -= value; - return *this; - }; + //! Returns true if the target string ends with the given suffix. + DUCKDB_API static bool EndsWith(const string &str, const string &suffix); - // special values - static timestamp_t infinity() { - return timestamp_t(NumericLimits::Maximum()); - } // NOLINT - static timestamp_t ninfinity() { - return timestamp_t(-NumericLimits::Maximum()); - } // NOLINT - static inline timestamp_t epoch() { - return timestamp_t(0); - } // NOLINT -}; + //! Repeat a string multiple times + DUCKDB_API static string Repeat(const string &str, const idx_t n); -struct timestamp_tz_t : public timestamp_t {}; -struct timestamp_ns_t : public timestamp_t {}; -struct timestamp_ms_t : public timestamp_t {}; -struct timestamp_sec_t : public timestamp_t {}; + //! Split the input string based on newline char + DUCKDB_API static vector Split(const string &str, char delimiter); -//! The Timestamp class is a static class that holds helper functions for the Timestamp -//! type. + //! Split the input string allong a quote. Note that any escaping is NOT supported. + DUCKDB_API static vector SplitWithQuote(const string &str, char delimiter = ',', char quote = '"'); + + //! Join multiple strings into one string. Components are concatenated by the given separator + DUCKDB_API static string Join(const vector &input, const string &separator); + + template + static string ToString(const vector &input, const string &separator) { + vector input_list; + for (auto &i : input) { + input_list.push_back(i.ToString()); + } + return StringUtil::Join(input_list, separator); + } + + //! Join multiple items of container with given size, transformed to string + //! using function, into one string using the given separator + template + static string Join(const C &input, S count, const string &separator, Func f) { + // The result + std::string result; + + // If the input isn't empty, append the first element. We do this so we + // don't need to introduce an if into the loop. + if (count > 0) { + result += f(input[0]); + } + + // Append the remaining input components, after the first + for (size_t i = 1; i < count; i++) { + result += separator + f(input[i]); + } + + return result; + } + + //! Return a string that formats the give number of bytes + DUCKDB_API static string BytesToHumanReadableString(idx_t bytes); + + //! Convert a string to uppercase + DUCKDB_API static string Upper(const string &str); + + //! Convert a string to lowercase + DUCKDB_API static string Lower(const string &str); + + //! Case insensitive equals + DUCKDB_API static bool CIEquals(const string &l1, const string &l2); + + //! Format a string using printf semantics + template + static string Format(const string fmt_str, Args... params) { + return Exception::ConstructMessage(fmt_str, params...); + } + + //! Split the input string into a vector of strings based on the split string + DUCKDB_API static vector Split(const string &input, const string &split); + + //! Remove the whitespace char in the left end of the string + DUCKDB_API static void LTrim(string &str); + //! Remove the whitespace char in the right end of the string + DUCKDB_API static void RTrim(string &str); + //! Remove the all chars from chars_to_trim char in the right end of the string + DUCKDB_API static void RTrim(string &str, const string &chars_to_trim); + //! Remove the whitespace char in the left and right end of the string + DUCKDB_API static void Trim(string &str); + + DUCKDB_API static string Replace(string source, const string &from, const string &to); + + //! Get the levenshtein distance from two strings + DUCKDB_API static idx_t LevenshteinDistance(const string &s1, const string &s2); + + //! Get the top-n strings (sorted by the given score distance) from a set of scores. + //! At least one entry is returned (if there is one). + //! Strings are only returned if they have a score less than the threshold. + DUCKDB_API static vector TopNStrings(vector> scores, idx_t n = 5, + idx_t threshold = 5); + //! Computes the levenshtein distance of each string in strings, and compares it to target, then returns TopNStrings + //! with the given params. + DUCKDB_API static vector TopNLevenshtein(const vector &strings, const string &target, idx_t n = 5, + idx_t threshold = 5); + DUCKDB_API static string CandidatesMessage(const vector &candidates, + const string &candidate = "Candidate bindings"); + + //! Generate an error message in the form of "{message_prefix}: nearest_string, nearest_string2, ... + //! Equivalent to calling TopNLevenshtein followed by CandidatesMessage + DUCKDB_API static string CandidatesErrorMessage(const vector &strings, const string &target, + const string &message_prefix, idx_t n = 5); +}; + +} // namespace duckdb + + + + +#include + +namespace duckdb { + +struct date_t; +struct dtime_t; + +//! Type used to represent timestamps (seconds,microseconds,milliseconds or nanoseconds since 1970-01-01) +struct timestamp_t { // NOLINT + int64_t value; + + timestamp_t() = default; + explicit inline timestamp_t(int64_t value_p) : value(value_p) { + } + inline timestamp_t &operator=(int64_t value_p) { + value = value_p; + return *this; + } + + // explicit conversion + explicit inline operator int64_t() const { + return value; + } + + // comparison operators + inline bool operator==(const timestamp_t &rhs) const { + return value == rhs.value; + }; + inline bool operator!=(const timestamp_t &rhs) const { + return value != rhs.value; + }; + inline bool operator<=(const timestamp_t &rhs) const { + return value <= rhs.value; + }; + inline bool operator<(const timestamp_t &rhs) const { + return value < rhs.value; + }; + inline bool operator>(const timestamp_t &rhs) const { + return value > rhs.value; + }; + inline bool operator>=(const timestamp_t &rhs) const { + return value >= rhs.value; + }; + + // arithmetic operators + inline timestamp_t operator+(const double &value) const { + return timestamp_t(this->value + int64_t(value)); + }; + inline int64_t operator-(const timestamp_t &other) const { + return this->value - other.value; + }; + + // in-place operators + inline timestamp_t &operator+=(const int64_t &value) { + this->value += value; + return *this; + }; + inline timestamp_t &operator-=(const int64_t &value) { + this->value -= value; + return *this; + }; + + // special values + static timestamp_t infinity() { // NOLINT + return timestamp_t(NumericLimits::Maximum()); + } // NOLINT + static timestamp_t ninfinity() { // NOLINT + return timestamp_t(-NumericLimits::Maximum()); + } // NOLINT + static inline timestamp_t epoch() { // NOLINT + return timestamp_t(0); + } // NOLINT +}; + +struct timestamp_tz_t : public timestamp_t {}; // NOLINT +struct timestamp_ns_t : public timestamp_t {}; // NOLINT +struct timestamp_ms_t : public timestamp_t {}; // NOLINT +struct timestamp_sec_t : public timestamp_t {}; // NOLINT + +//! The Timestamp class is a static class that holds helper functions for the Timestamp +//! type. class Timestamp { public: // min timestamp is 290308-12-22 (BC) @@ -2959,6 +3275,12 @@ class Timestamp { DUCKDB_API static timestamp_t FromDatetime(date_t date, dtime_t time); DUCKDB_API static bool TryFromDatetime(date_t date, dtime_t time, timestamp_t &result); + //! Is the character a valid part of a time zone name? + static inline bool CharacterIsTimeZone(char c) { + return StringUtil::CharacterIsAlpha(c) || StringUtil::CharacterIsDigit(c) || c == '_' || c == '/' || c == '+' || + c == '-'; + } + //! Is the timestamp finite or infinite? static inline bool IsFinite(timestamp_t timestamp) { return timestamp != timestamp_t::infinity() && timestamp != timestamp_t::ninfinity(); @@ -3143,6 +3465,11 @@ struct string_t { return GetString(); } + void SetPointer(char *new_ptr) { + D_ASSERT(!IsInlined()); + value.pointer.ptr = new_ptr; + } + void Finalize() { // set trailing NULL byte if (GetSize() <= INLINE_LENGTH) { @@ -3659,7 +3986,7 @@ class Value { // move assignment DUCKDB_API Value &operator=(Value &&other) noexcept; - inline LogicalType &type() { + inline LogicalType &GetTypeMutable() { return type_; } inline const LogicalType &type() const { @@ -3727,10 +4054,6 @@ class Value { int32_t micros); DUCKDB_API static Value INTERVAL(int32_t months, int32_t days, int64_t micros); DUCKDB_API static Value INTERVAL(interval_t interval); - //! Creates a JSON Value - DUCKDB_API static Value JSON(const char *val); - DUCKDB_API static Value JSON(string_t val); - DUCKDB_API static Value JSON(string val); // Create a enum Value from a specified uint value DUCKDB_API static Value ENUM(uint64_t value, const LogicalType &original_type); @@ -3753,8 +4076,8 @@ class Value { DUCKDB_API static Value LIST(LogicalType child_type, vector values); //! Create an empty list with the specified child-type DUCKDB_API static Value EMPTYLIST(LogicalType child_type); - //! Create a map value from a (key, value) pair - DUCKDB_API static Value MAP(Value key, Value value); + //! Create a map value with the given entries + DUCKDB_API static Value MAP(LogicalType child_type, vector values); //! Create a union value from a selected value and a tag from a set of alternatives. DUCKDB_API static Value UNION(child_list_t members, uint8_t tag, Value value); @@ -3765,6 +4088,9 @@ class Value { } //! Creates a blob by casting a specified string to a blob (i.e. interpreting \x characters) DUCKDB_API static Value BLOB(const string &data); + //! Creates a bitstring by casting a specified string to a bitstring + DUCKDB_API static Value BIT(const_data_ptr_t data, idx_t len); + DUCKDB_API static Value BIT(const string &data); template T GetValue() const { @@ -3818,6 +4144,8 @@ class Value { DUCKDB_API bool TryCastAs(ClientContext &context, const LogicalType &target_type, bool strict = false); DUCKDB_API bool DefaultTryCastAs(const LogicalType &target_type, bool strict = false); + DUCKDB_API void Reinterpret(LogicalType new_type); + //! Serializes a Value to a stand-alone binary blob DUCKDB_API void Serialize(Serializer &serializer) const; //! Deserializes a Value from a blob @@ -4211,7 +4539,6 @@ DUCKDB_API bool Value::IsFinite(timestamp_t input); - //===----------------------------------------------------------------------===// // DuckDB // @@ -4226,6 +4553,7 @@ DUCKDB_API bool Value::IsFinite(timestamp_t input); namespace duckdb { class Allocator; +class AttachedDatabase; class ClientContext; class DatabaseInstance; class ExecutionContext; @@ -4305,13 +4633,14 @@ class Allocator { } static Allocator &Get(ClientContext &context); static Allocator &Get(DatabaseInstance &db); + static Allocator &Get(AttachedDatabase &db); PrivateAllocatorData *GetPrivateData() { return private_data.get(); } - static Allocator &DefaultAllocator(); - static shared_ptr &DefaultAllocatorReference(); + DUCKDB_API static Allocator &DefaultAllocator(); + DUCKDB_API static shared_ptr &DefaultAllocatorReference(); private: allocate_function_ptr_t allocate_function; @@ -4332,7 +4661,7 @@ void DeleteArray(T *ptr, idx_t size) { } template -T *AllocateObject(ARGS &&...args) { +T *AllocateObject(ARGS &&... args) { auto data = Allocator::DefaultAllocator().AllocateData(sizeof(T)); return new (data) T(std::forward(args)...); } @@ -4351,11 +4680,13 @@ void DestroyObject(T *ptr) { struct BufferAllocator { DUCKDB_API static Allocator &Get(ClientContext &context); DUCKDB_API static Allocator &Get(DatabaseInstance &db); + DUCKDB_API static Allocator &Get(AttachedDatabase &db); }; } // namespace duckdb + namespace duckdb { struct ArenaChunk { @@ -4373,19 +4704,24 @@ class ArenaAllocator { static constexpr const idx_t ARENA_ALLOCATOR_INITIAL_CAPACITY = 2048; public: - ArenaAllocator(Allocator &allocator, idx_t initial_capacity = ARENA_ALLOCATOR_INITIAL_CAPACITY); - ~ArenaAllocator(); + DUCKDB_API ArenaAllocator(Allocator &allocator, idx_t initial_capacity = ARENA_ALLOCATOR_INITIAL_CAPACITY); + DUCKDB_API ~ArenaAllocator(); + + DUCKDB_API data_ptr_t Allocate(idx_t size); + DUCKDB_API data_ptr_t Reallocate(data_ptr_t pointer, idx_t old_size, idx_t size); + + DUCKDB_API data_ptr_t AllocateAligned(idx_t size); + DUCKDB_API data_ptr_t ReallocateAligned(data_ptr_t pointer, idx_t old_size, idx_t size); - data_ptr_t Allocate(idx_t size); //! Resets the current head and destroys all previous arena chunks - void Reset(); - void Destroy(); - void Move(ArenaAllocator &allocator); + DUCKDB_API void Reset(); + DUCKDB_API void Destroy(); + DUCKDB_API void Move(ArenaAllocator &allocator); - ArenaChunk *GetHead(); - ArenaChunk *GetTail(); + DUCKDB_API ArenaChunk *GetHead(); + DUCKDB_API ArenaChunk *GetTail(); - bool IsEmpty(); + DUCKDB_API bool IsEmpty(); private: //! Internal allocator that is used by the arena allocator @@ -4404,25 +4740,25 @@ namespace duckdb { //! returned pointer will remain valid until the StringHeap is destroyed class StringHeap { public: - StringHeap(Allocator &allocator = Allocator::DefaultAllocator()); + DUCKDB_API StringHeap(Allocator &allocator = Allocator::DefaultAllocator()); - void Destroy(); - void Move(StringHeap &other); + DUCKDB_API void Destroy(); + DUCKDB_API void Move(StringHeap &other); //! Add a string to the string heap, returns a pointer to the string - string_t AddString(const char *data, idx_t len); + DUCKDB_API string_t AddString(const char *data, idx_t len); //! Add a string to the string heap, returns a pointer to the string - string_t AddString(const char *data); + DUCKDB_API string_t AddString(const char *data); //! Add a string to the string heap, returns a pointer to the string - string_t AddString(const string &data); + DUCKDB_API string_t AddString(const string &data); //! Add a string to the string heap, returns a pointer to the string - string_t AddString(const string_t &data); + DUCKDB_API string_t AddString(const string_t &data); //! Add a blob to the string heap; blobs can be non-valid UTF8 - string_t AddBlob(const string_t &data); + DUCKDB_API string_t AddBlob(const string_t &data); //! Add a blob to the string heap; blobs can be non-valid UTF8 - string_t AddBlob(const char *data, idx_t len); + DUCKDB_API string_t AddBlob(const char *data, idx_t len); //! Allocates space for an empty string of size "len" on the heap - string_t EmptyString(idx_t len); + DUCKDB_API string_t EmptyString(idx_t len); private: ArenaAllocator allocator; @@ -4471,6 +4807,8 @@ struct FileHandle; //! The version number of the database storage format extern const uint64_t VERSION_NUMBER; +const char *GetDuckDBVersion(idx_t version_number); + using block_id_t = int64_t; #define INVALID_BLOCK (-1) @@ -4606,7 +4944,7 @@ class VectorBuffer { } } explicit VectorBuffer(unique_ptr data_p) - : buffer_type(VectorBufferType::STANDARD_BUFFER), data(move(data_p)) { + : buffer_type(VectorBufferType::STANDARD_BUFFER), data(std::move(data_p)) { } virtual ~VectorBuffer() { } @@ -4619,7 +4957,7 @@ class VectorBuffer { } void SetData(unique_ptr new_data) { - data = move(new_data); + data = std::move(new_data); } VectorAuxiliaryData *GetAuxiliaryData() { @@ -4627,7 +4965,7 @@ class VectorBuffer { } void SetAuxiliaryData(unique_ptr aux_data_p) { - aux_data = move(aux_data_p); + aux_data = std::move(aux_data_p); } static buffer_ptr CreateStandardVector(PhysicalType type, idx_t capacity = STANDARD_VECTOR_SIZE); @@ -4657,7 +4995,7 @@ class DictionaryBuffer : public VectorBuffer { : VectorBuffer(VectorBufferType::DICTIONARY_BUFFER), sel_vector(sel) { } explicit DictionaryBuffer(buffer_ptr data) - : VectorBuffer(VectorBufferType::DICTIONARY_BUFFER), sel_vector(move(data)) { + : VectorBuffer(VectorBufferType::DICTIONARY_BUFFER), sel_vector(std::move(data)) { } explicit DictionaryBuffer(idx_t count = STANDARD_VECTOR_SIZE) : VectorBuffer(VectorBufferType::DICTIONARY_BUFFER), sel_vector(count) { @@ -4698,7 +5036,7 @@ class VectorStringBuffer : public VectorBuffer { } void AddHeapReference(buffer_ptr heap) { - references.push_back(move(heap)); + references.push_back(std::move(heap)); } private: @@ -4805,6 +5143,14 @@ class VectorListBuffer; struct SelCache; +struct ConsecutiveChildListInfo { + ConsecutiveChildListInfo() : is_constant(true), needs_slicing(false), child_list_info(list_entry_t(0, 0)) { + } + bool is_constant; + bool needs_slicing; + list_entry_t child_list_info; +}; + //! Vector of values of a specified PhysicalType. class Vector { friend struct ConstantVector; @@ -4881,10 +5227,10 @@ class Vector { //! Converts this Vector to a printable string representation DUCKDB_API string ToString(idx_t count) const; - DUCKDB_API void Print(idx_t count); + DUCKDB_API void Print(idx_t count) const; DUCKDB_API string ToString() const; - DUCKDB_API void Print(); + DUCKDB_API void Print() const; //! Flatten the vector, removing any compression and turning it into a FLAT_VECTOR DUCKDB_API void Flatten(idx_t count); @@ -4976,7 +5322,7 @@ class Vector { class VectorChildBuffer : public VectorBuffer { public: explicit VectorChildBuffer(Vector vector) - : VectorBuffer(VectorBufferType::VECTOR_CHILD_BUFFER), data(move(vector)) { + : VectorBuffer(VectorBufferType::VECTOR_CHILD_BUFFER), data(std::move(vector)) { } public: @@ -5077,6 +5423,7 @@ struct FlatVector { return !vector.validity.RowIsValid(idx); } DUCKDB_API static const SelectionVector *IncrementalSelectionVector(); + static Value GetValuesFromOffsets(Vector &values, vector &offsets); }; struct ListVector { @@ -5103,8 +5450,12 @@ struct ListVector { DUCKDB_API static void Append(Vector &target, const Vector &source, const SelectionVector &sel, idx_t source_size, idx_t source_offset = 0); DUCKDB_API static void PushBack(Vector &target, const Value &insert); - DUCKDB_API static vector Search(Vector &list, const Value &key, idx_t row); - DUCKDB_API static Value GetValuesFromOffsets(Vector &list, vector &offsets); + //! Returns the child_vector of list starting at offset until offset + count, and its length + DUCKDB_API static idx_t GetConsecutiveChildList(Vector &list, Vector &result, idx_t offset, idx_t count); + //! Returns information to only copy a section of a list child vector + DUCKDB_API static ConsecutiveChildListInfo GetConsecutiveChildListInfo(Vector &list, idx_t offset, idx_t count); + //! Slice and flatten a child vector to only contain a consecutive subsection of the child entries + DUCKDB_API static void GetConsecutiveChildSelVector(Vector &list, SelectionVector &sel, idx_t offset, idx_t count); //! Share the entry of the other list vector DUCKDB_API static void ReferenceEntry(Vector &vector, Vector &other); }; @@ -5182,6 +5533,7 @@ struct MapVector { DUCKDB_API static const Vector &GetValues(const Vector &vector); DUCKDB_API static Vector &GetKeys(Vector &vector); DUCKDB_API static Vector &GetValues(Vector &vector); + static vector Search(Vector &keys, idx_t count, const Value &key, list_entry_t &entry); }; struct StructVector { @@ -5382,7 +5734,9 @@ class PreservedError { //! Not initialized, default constructor DUCKDB_API PreservedError(); //! From std::exception - DUCKDB_API explicit PreservedError(const std::exception &exception); + PreservedError(const std::exception &ex) + : initialized(true), type(ExceptionType::INVALID), raw_message(SanitizeErrorMessage(ex.what())) { + } //! From a raw string DUCKDB_API explicit PreservedError(const string &raw_message); //! From an Exception @@ -5398,8 +5752,8 @@ class PreservedError { //! Used in clients like C-API, creates the final message and returns a reference to it DUCKDB_API const string &Message(); //! Let's us do things like 'if (error)' - operator bool() const; - bool operator==(const PreservedError &other) const; + DUCKDB_API operator bool() const; + DUCKDB_API bool operator==(const PreservedError &other) const; private: //! Whether this PreservedError contains an exception or not @@ -5412,7 +5766,7 @@ class PreservedError { string final_message; private: - static string SanitizeErrorMessage(string error); + DUCKDB_API static string SanitizeErrorMessage(string error); }; } // namespace duckdb @@ -5606,6 +5960,8 @@ class DataChunk { //! Hashes the DataChunk to the target vector DUCKDB_API void Hash(Vector &result); + //! Hashes specific vectors of the DataChunk to the target vector + DUCKDB_API void Hash(vector &column_ids, Vector &result); //! Returns a list of types of the vectors of this data chunk DUCKDB_API vector GetTypes(); @@ -6329,6 +6685,14 @@ struct BinaryExecutor { namespace duckdb { +template +struct TernaryStandardOperatorWrapper { + template + static inline RESULT_TYPE Operation(FUN fun, A_TYPE a, B_TYPE b, C_TYPE c, ValidityMask &mask, idx_t idx) { + return OP::template Operation(a, b, c); + } +}; + struct TernaryLambdaWrapper { template static inline RESULT_TYPE Operation(FUN fun, A_TYPE a, B_TYPE b, C_TYPE c, ValidityMask &mask, idx_t idx) { @@ -6412,6 +6776,12 @@ struct TernaryExecutor { ExecuteGeneric(a, b, c, result, count, fun); } + template + static void ExecuteStandard(Vector &a, Vector &b, Vector &c, Vector &result, idx_t count) { + ExecuteGeneric, bool>(a, b, c, result, + count, false); + } + template > static void ExecuteWithNulls(Vector &a, Vector &b, Vector &c, Vector &result, idx_t count, FUN fun) { @@ -6870,233 +7240,70 @@ using std::unordered_set; } + + +namespace duckdb { + +struct CaseInsensitiveStringHashFunction { + uint64_t operator()(const string &str) const { + std::hash hasher; + return hasher(StringUtil::Lower(str)); + } +}; + +struct CaseInsensitiveStringEquality { + bool operator()(const string &a, const string &b) const { + return StringUtil::Lower(a) == StringUtil::Lower(b); + } +}; + +template +using case_insensitive_map_t = + unordered_map; + +using case_insensitive_set_t = unordered_set; + +} // namespace duckdb + + +namespace duckdb { + +using named_parameter_type_map_t = case_insensitive_map_t; +using named_parameter_map_t = case_insensitive_map_t; + +} // namespace duckdb + + + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/string_util.hpp +// duckdb/main/external_dependencies.hpp // // //===----------------------------------------------------------------------===// +namespace duckdb { +enum ExternalDependenciesType { PYTHON_DEPENDENCY }; +class ExternalDependency { +public: + explicit ExternalDependency(ExternalDependenciesType type_p) : type(type_p) {}; + virtual ~ExternalDependency() {}; + ExternalDependenciesType type; +}; +} // namespace duckdb - -namespace duckdb { -/** - * String Utility Functions - * Note that these are not the most efficient implementations (i.e., they copy - * memory) and therefore they should only be used for debug messages and other - * such things. - */ -class StringUtil { -public: - DUCKDB_API static bool CharacterIsSpace(char c) { - return c == ' ' || c == '\t' || c == '\n' || c == '\v' || c == '\f' || c == '\r'; - } - DUCKDB_API static bool CharacterIsNewline(char c) { - return c == '\n' || c == '\r'; - } - DUCKDB_API static bool CharacterIsDigit(char c) { - return c >= '0' && c <= '9'; - } - DUCKDB_API static bool CharacterIsHex(char c) { - return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); - } - DUCKDB_API static char CharacterToLower(char c) { - if (c >= 'A' && c <= 'Z') { - return c - ('A' - 'a'); - } - return c; - } - DUCKDB_API static char CharacterIsAlpha(char c) { - return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); - } - static bool CharacterIsOperator(char c) { - if (c == '_') { - return false; - } - if (c >= '!' && c <= '/') { - return true; - } - if (c >= ':' && c <= '@') { - return true; - } - if (c >= '[' && c <= '`') { - return true; - } - if (c >= '{' && c <= '~') { - return true; - } - return false; - } - - //! Returns true if the needle string exists in the haystack - DUCKDB_API static bool Contains(const string &haystack, const string &needle); - - //! Returns true if the target string starts with the given prefix - DUCKDB_API static bool StartsWith(string str, string prefix); - - //! Returns true if the target string ends with the given suffix. - DUCKDB_API static bool EndsWith(const string &str, const string &suffix); - - //! Repeat a string multiple times - DUCKDB_API static string Repeat(const string &str, const idx_t n); - - //! Split the input string based on newline char - DUCKDB_API static vector Split(const string &str, char delimiter); - - //! Split the input string allong a quote. Note that any escaping is NOT supported. - DUCKDB_API static vector SplitWithQuote(const string &str, char delimiter = ',', char quote = '"'); - - //! Join multiple strings into one string. Components are concatenated by the given separator - DUCKDB_API static string Join(const vector &input, const string &separator); - - template - static string ToString(const vector &input, const string &separator) { - vector input_list; - for (auto &i : input) { - input_list.push_back(i.ToString()); - } - return StringUtil::Join(input_list, separator); - } - - //! Join multiple items of container with given size, transformed to string - //! using function, into one string using the given separator - template - static string Join(const C &input, S count, const string &separator, Func f) { - // The result - std::string result; - - // If the input isn't empty, append the first element. We do this so we - // don't need to introduce an if into the loop. - if (count > 0) { - result += f(input[0]); - } - - // Append the remaining input components, after the first - for (size_t i = 1; i < count; i++) { - result += separator + f(input[i]); - } - - return result; - } - - //! Return a string that formats the give number of bytes - DUCKDB_API static string BytesToHumanReadableString(idx_t bytes); - - //! Convert a string to uppercase - DUCKDB_API static string Upper(const string &str); - - //! Convert a string to lowercase - DUCKDB_API static string Lower(const string &str); - - //! Format a string using printf semantics - template - static string Format(const string fmt_str, Args... params) { - return Exception::ConstructMessage(fmt_str, params...); - } - - //! Split the input string into a vector of strings based on the split string - DUCKDB_API static vector Split(const string &input, const string &split); - - //! Remove the whitespace char in the left end of the string - DUCKDB_API static void LTrim(string &str); - //! Remove the whitespace char in the right end of the string - DUCKDB_API static void RTrim(string &str); - //! Remove the whitespace char in the left and right end of the string - DUCKDB_API static void Trim(string &str); - - DUCKDB_API static string Replace(string source, const string &from, const string &to); - - //! Get the levenshtein distance from two strings - DUCKDB_API static idx_t LevenshteinDistance(const string &s1, const string &s2); - - //! Get the top-n strings (sorted by the given score distance) from a set of scores. - //! At least one entry is returned (if there is one). - //! Strings are only returned if they have a score less than the threshold. - DUCKDB_API static vector TopNStrings(vector> scores, idx_t n = 5, - idx_t threshold = 5); - //! Computes the levenshtein distance of each string in strings, and compares it to target, then returns TopNStrings - //! with the given params. - DUCKDB_API static vector TopNLevenshtein(const vector &strings, const string &target, idx_t n = 5, - idx_t threshold = 5); - DUCKDB_API static string CandidatesMessage(const vector &candidates, - const string &candidate = "Candidate bindings"); - - //! Generate an error message in the form of "{message_prefix}: nearest_string, nearest_string2, ... - //! Equivalent to calling TopNLevenshtein followed by CandidatesMessage - DUCKDB_API static string CandidatesErrorMessage(const vector &strings, const string &target, - const string &message_prefix, idx_t n = 5); -}; - -} // namespace duckdb - - -namespace duckdb { - -struct CaseInsensitiveStringHashFunction { - uint64_t operator()(const string &str) const { - std::hash hasher; - return hasher(StringUtil::Lower(str)); - } -}; - -struct CaseInsensitiveStringEquality { - bool operator()(const string &a, const string &b) const { - return StringUtil::Lower(a) == StringUtil::Lower(b); - } -}; - -template -using case_insensitive_map_t = - unordered_map; - -using case_insensitive_set_t = unordered_set; - -} // namespace duckdb - - -namespace duckdb { - -using named_parameter_type_map_t = case_insensitive_map_t; -using named_parameter_map_t = case_insensitive_map_t; - -} // namespace duckdb - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/external_dependencies.hpp -// -// -//===----------------------------------------------------------------------===// - - - -namespace duckdb { - -enum ExternalDependenciesType { PYTHON_DEPENDENCY }; -class ExternalDependency { -public: - explicit ExternalDependency(ExternalDependenciesType type_p) : type(type_p) {}; - virtual ~ExternalDependency() {}; - ExternalDependenciesType type; -}; - -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/column_definition.hpp -// -// -//===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/column_definition.hpp +// +// +//===----------------------------------------------------------------------===// @@ -7268,7 +7475,8 @@ enum class ExpressionType : uint8_t { BOUND_UNNEST = 229, COLLATE = 230, LAMBDA = 231, - POSITIONAL_REFERENCE = 232 + POSITIONAL_REFERENCE = 232, + BOUND_LAMBDA_REF = 233 }; //===--------------------------------------------------------------------===// @@ -7317,6 +7525,7 @@ enum class ExpressionClass : uint8_t { BOUND_BETWEEN = 39, BOUND_UNNEST = 40, BOUND_LAMBDA = 41, + BOUND_LAMBDA_REF = 42, //===--------------------------------------------------------------------===// // Miscellaneous //===--------------------------------------------------------------------===// @@ -7465,12 +7674,14 @@ class KeywordHelper { namespace duckdb { struct QualifiedName { + string catalog; string schema; string name; //! Parse the (optional) schema and a name from a string in the format of e.g. "schema"."table"; if there is no dot //! the schema will be set to INVALID_SCHEMA static QualifiedName Parse(const string &input) { + string catalog; string schema; string name; idx_t idx = 0; @@ -7506,22 +7717,28 @@ struct QualifiedName { throw ParserException("Unterminated quote in qualified name!"); end: if (entries.empty()) { + catalog = INVALID_CATALOG; schema = INVALID_SCHEMA; name = entry; } else if (entries.size() == 1) { + catalog = INVALID_CATALOG; schema = entries[0]; name = entry; + } else if (entries.size() == 2) { + catalog = entries[0]; + schema = entries[1]; + name = entry; } else { - throw ParserException("Expected schema.entry or entry: too many entries found"); + throw ParserException("Expected catalog.entry, schema.entry or entry: too many entries found"); } - return QualifiedName {schema, name}; + return QualifiedName {catalog, schema, name}; } }; struct QualifiedColumnName { QualifiedColumnName() { } - QualifiedColumnName(string table_p, string column_p) : table(move(table_p)), column(move(column_p)) { + QualifiedColumnName(string table_p, string column_p) : table(std::move(table_p)), column(std::move(column_p)) { } string schema; @@ -7638,6 +7855,7 @@ class ParsedExpression : public BaseExpression { + namespace duckdb { enum class CompressionType : uint8_t { @@ -7650,9 +7868,11 @@ enum class CompressionType : uint8_t { COMPRESSION_BITPACKING = 6, COMPRESSION_FSST = 7, COMPRESSION_CHIMP = 8, - COMPRESSION_PATAS = 9 + COMPRESSION_PATAS = 9, + COMPRESSION_COUNT // This has to stay the last entry of the type! }; +vector ListCompressionTypes(void); CompressionType CompressionTypeFromString(const string &str); string CompressionTypeToString(CompressionType type); @@ -7901,67 +8121,6 @@ class BaseScalarFunction : public SimpleFunction { DUCKDB_API string ToString() override; }; -class BuiltinFunctions { -public: - BuiltinFunctions(ClientContext &transaction, Catalog &catalog); - - //! Initialize a catalog with all built-in functions - void Initialize(); - -public: - void AddFunction(AggregateFunctionSet set); - void AddFunction(AggregateFunction function); - void AddFunction(ScalarFunctionSet set); - void AddFunction(PragmaFunction function); - void AddFunction(const string &name, PragmaFunctionSet functions); - void AddFunction(ScalarFunction function); - void AddFunction(const vector &names, ScalarFunction function); - void AddFunction(TableFunctionSet set); - void AddFunction(TableFunction function); - void AddFunction(CopyFunction function); - - void AddCollation(string name, ScalarFunction function, bool combinable = false, - bool not_required_for_equality = false); - -private: - ClientContext &context; - Catalog &catalog; - -private: - template - void Register() { - T::RegisterFunction(*this); - } - - // table-producing functions - void RegisterTableScanFunctions(); - void RegisterSQLiteFunctions(); - void RegisterReadFunctions(); - void RegisterTableFunctions(); - void RegisterArrowFunctions(); - - // aggregates - void RegisterAlgebraicAggregates(); - void RegisterDistributiveAggregates(); - void RegisterNestedAggregates(); - void RegisterHolisticAggregates(); - void RegisterRegressiveAggregates(); - - // scalar functions - void RegisterDateFunctions(); - void RegisterEnumFunctions(); - void RegisterGenericFunctions(); - void RegisterMathFunctions(); - void RegisterOperators(); - void RegisterStringFunctions(); - void RegisterNestedFunctions(); - void RegisterSequenceFunctions(); - void RegisterTrigonometricsFunctions(); - - // pragmas - void RegisterPragmaFunctions(); -}; - } // namespace duckdb @@ -7989,7 +8148,7 @@ struct ExpressionState { void Finalize(); Allocator &GetAllocator(); bool HasContext(); - ClientContext &GetContext(); + DUCKDB_API ClientContext &GetContext(); void Verify(ExpressionExecutorState &root); }; @@ -8001,7 +8160,7 @@ struct ExecuteFunctionState : public ExpressionState { unique_ptr local_state; public: - static FunctionLocalState *GetFunctionState(ExpressionState &state) { + DUCKDB_API static FunctionLocalState *GetFunctionState(ExpressionState &state) { return ((ExecuteFunctionState &)state).local_state.get(); } }; @@ -8140,9 +8299,9 @@ class Hugeint { template static T Cast(hugeint_t input) { - T value; - TryCast(input, value); - return value; + T result = 0; + TryCast(input, result); + return result; } template @@ -8596,8 +8755,8 @@ class BaseStatistics { public: static unique_ptr CreateEmpty(LogicalType type, StatisticsType stats_type); - bool CanHaveNull() const; - bool CanHaveNoNull() const; + DUCKDB_API bool CanHaveNull() const; + DUCKDB_API bool CanHaveNoNull() const; void UpdateDistinctStatistics(Vector &v, idx_t count); @@ -8613,7 +8772,7 @@ class BaseStatistics { virtual void Serialize(Serializer &serializer) const; virtual void Serialize(FieldWriter &writer) const; - idx_t GetDistinctCount(); + virtual idx_t GetDistinctCount(); static unique_ptr Deserialize(Deserializer &source, LogicalType type); @@ -8638,6 +8797,7 @@ struct FunctionLocalState { class Binder; class BoundFunctionExpression; +class DependencyList; class ScalarFunctionCatalogEntry; struct FunctionStatisticsInput { @@ -8662,7 +8822,7 @@ typedef unique_ptr (*init_local_state_t)(ExpressionState &st FunctionData *bind_data); typedef unique_ptr (*function_statistics_t)(ClientContext &context, FunctionStatisticsInput &input); //! Adds the dependencies of this BoundFunctionExpression to the set of dependencies -typedef void (*dependency_function_t)(BoundFunctionExpression &expr, unordered_set &dependencies); +typedef void (*dependency_function_t)(BoundFunctionExpression &expr, DependencyList &dependencies); typedef void (*function_serialize_t)(FieldWriter &writer, const FunctionData *bind_data, const ScalarFunction &function); @@ -8723,6 +8883,13 @@ class ScalarFunction : public BaseScalarFunction { BinaryExecutor::ExecuteStandard(input.data[0], input.data[1], result, input.size()); } + template + static void TernaryFunction(DataChunk &input, ExpressionState &state, Vector &result) { + D_ASSERT(input.ColumnCount() == 3); + TernaryExecutor::ExecuteStandard(input.data[0], input.data[1], input.data[2], result, + input.size()); + } + public: template static scalar_function_t GetScalarUnaryFunction(LogicalType type) { @@ -8945,7 +9112,7 @@ class ResultModifier { //! Single node in ORDER BY statement struct OrderByNode { OrderByNode(OrderType type, OrderByNullType null_order, unique_ptr expression) - : type(type), null_order(null_order), expression(move(expression)) { + : type(type), null_order(null_order), expression(std::move(expression)) { } //! Sort order, ASC or DESC @@ -9037,41 +9204,48 @@ class LimitPercentModifier : public ResultModifier { -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/logical_operator.hpp -// -// -//===----------------------------------------------------------------------===// +namespace duckdb { + +class LogicalOperator; +struct LogicalType; + +struct BoundStatement { + unique_ptr plan; + vector types; + vector names; +}; + +} // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/catalog/catalog.hpp +// duckdb/planner/expression.hpp // // //===----------------------------------------------------------------------===// + + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/catalog/catalog_entry.hpp +// duckdb/planner/plan_serialization.hpp // // //===----------------------------------------------------------------------===// - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/enums/catalog_type.hpp +// duckdb/common/enums/logical_operator_type.hpp // // //===----------------------------------------------------------------------===// @@ -9083,34 +9257,98 @@ class LimitPercentModifier : public ResultModifier { namespace duckdb { //===--------------------------------------------------------------------===// -// Catalog Types +// Logical Operator Types //===--------------------------------------------------------------------===// -enum class CatalogType : uint8_t { - INVALID = 0, - TABLE_ENTRY = 1, - SCHEMA_ENTRY = 2, - VIEW_ENTRY = 3, - INDEX_ENTRY = 4, - PREPARED_STATEMENT = 5, - SEQUENCE_ENTRY = 6, - COLLATION_ENTRY = 7, - TYPE_ENTRY = 8, +enum class LogicalOperatorType : uint8_t { + LOGICAL_INVALID = 0, + LOGICAL_PROJECTION = 1, + LOGICAL_FILTER = 2, + LOGICAL_AGGREGATE_AND_GROUP_BY = 3, + LOGICAL_WINDOW = 4, + LOGICAL_UNNEST = 5, + LOGICAL_LIMIT = 6, + LOGICAL_ORDER_BY = 7, + LOGICAL_TOP_N = 8, + LOGICAL_COPY_TO_FILE = 10, + LOGICAL_DISTINCT = 11, + LOGICAL_SAMPLE = 12, + LOGICAL_LIMIT_PERCENT = 13, - // functions - TABLE_FUNCTION_ENTRY = 25, - SCALAR_FUNCTION_ENTRY = 26, - AGGREGATE_FUNCTION_ENTRY = 27, - PRAGMA_FUNCTION_ENTRY = 28, - COPY_FUNCTION_ENTRY = 29, - MACRO_ENTRY = 30, - TABLE_MACRO_ENTRY = 31, + // ----------------------------- + // Data sources + // ----------------------------- + LOGICAL_GET = 25, + LOGICAL_CHUNK_GET = 26, + LOGICAL_DELIM_GET = 27, + LOGICAL_EXPRESSION_GET = 28, + LOGICAL_DUMMY_SCAN = 29, + LOGICAL_EMPTY_RESULT = 30, + LOGICAL_CTE_REF = 31, + // ----------------------------- + // Joins + // ----------------------------- + LOGICAL_JOIN = 50, + LOGICAL_DELIM_JOIN = 51, + LOGICAL_COMPARISON_JOIN = 52, + LOGICAL_ANY_JOIN = 53, + LOGICAL_CROSS_PRODUCT = 54, + LOGICAL_POSITIONAL_JOIN = 55, + // ----------------------------- + // SetOps + // ----------------------------- + LOGICAL_UNION = 75, + LOGICAL_EXCEPT = 76, + LOGICAL_INTERSECT = 77, + LOGICAL_RECURSIVE_CTE = 78, - // version info - UPDATED_ENTRY = 50, - DELETED_ENTRY = 51, + // ----------------------------- + // Updates + // ----------------------------- + LOGICAL_INSERT = 100, + LOGICAL_DELETE = 101, + LOGICAL_UPDATE = 102, + + // ----------------------------- + // Schema + // ----------------------------- + LOGICAL_ALTER = 125, + LOGICAL_CREATE_TABLE = 126, + LOGICAL_CREATE_INDEX = 127, + LOGICAL_CREATE_SEQUENCE = 128, + LOGICAL_CREATE_VIEW = 129, + LOGICAL_CREATE_SCHEMA = 130, + LOGICAL_CREATE_MACRO = 131, + LOGICAL_DROP = 132, + LOGICAL_PRAGMA = 133, + LOGICAL_TRANSACTION = 134, + LOGICAL_CREATE_TYPE = 135, + LOGICAL_ATTACH = 136, + + // ----------------------------- + // Explain + // ----------------------------- + LOGICAL_EXPLAIN = 150, + + // ----------------------------- + // Show + // ----------------------------- + LOGICAL_SHOW = 160, + + // ----------------------------- + // Helpers + // ----------------------------- + LOGICAL_PREPARE = 175, + LOGICAL_EXECUTE = 176, + LOGICAL_EXPORT = 177, + LOGICAL_VACUUM = 178, + LOGICAL_SET = 179, + LOGICAL_LOAD = 180, + LOGICAL_RESET = 181, + + LOGICAL_EXTENSION_OPERATOR = 255 }; -DUCKDB_API string CatalogTypeToString(CatalogType type); +DUCKDB_API string LogicalOperatorToString(LogicalOperatorType type); } // namespace duckdb @@ -9118,378 +9356,205 @@ DUCKDB_API string CatalogTypeToString(CatalogType type); //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/atomic.hpp +// duckdb/planner/bound_parameter_map.hpp // // //===----------------------------------------------------------------------===// -#include - -namespace duckdb { -using std::atomic; -} -#include namespace duckdb { -struct AlterInfo; -class Catalog; -class CatalogSet; -class ClientContext; - -//! Abstract base class of an entry in the catalog -class CatalogEntry { -public: - CatalogEntry(CatalogType type, Catalog *catalog, string name); - virtual ~CatalogEntry(); - - //! The oid of the entry - idx_t oid; - //! The type of this catalog entry - CatalogType type; - //! Reference to the catalog this entry belongs to - Catalog *catalog; - //! Reference to the catalog set this entry is stored in - CatalogSet *set; - //! The name of the entry - string name; - //! Whether or not the object is deleted - bool deleted; - //! Whether or not the object is temporary and should not be added to the WAL - bool temporary; - //! Whether or not the entry is an internal entry (cannot be deleted, not dumped, etc) - bool internal; - //! Timestamp at which the catalog entry was created - atomic timestamp; - //! Child entry - unique_ptr child; - //! Parent entry (the node that dependents_map this node) - CatalogEntry *parent; -public: - virtual unique_ptr AlterEntry(ClientContext &context, AlterInfo *info); - virtual void UndoAlter(ClientContext &context, AlterInfo *info); - - virtual unique_ptr Copy(ClientContext &context); +struct BoundParameterData; - //! Sets the CatalogEntry as the new root entry (i.e. the newest entry) - // this is called on a rollback to an AlterEntry - virtual void SetAsRoot(); +using bound_parameter_map_t = unordered_map>; - //! Convert the catalog entry to a SQL string that can be used to re-construct the catalog entry - virtual string ToSQL(); -}; } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/mutex.hpp -// -// -//===----------------------------------------------------------------------===// - - - -#include namespace duckdb { -using std::lock_guard; -using std::mutex; -using std::unique_lock; -} // namespace duckdb +class ClientContext; +class LogicalOperator; +struct BoundParameterData; -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/query_error_context.hpp -// -// -//===----------------------------------------------------------------------===// +struct PlanDeserializationState { + PlanDeserializationState(ClientContext &context); + ~PlanDeserializationState(); + + ClientContext &context; + bound_parameter_map_t parameter_data; +}; +struct LogicalDeserializationState { + LogicalDeserializationState(PlanDeserializationState &gstate, LogicalOperatorType type, + vector> &children); + PlanDeserializationState &gstate; + LogicalOperatorType type; + vector> &children; +}; +struct ExpressionDeserializationState { + ExpressionDeserializationState(PlanDeserializationState &gstate, ExpressionType type); + PlanDeserializationState &gstate; + ExpressionType type; +}; +} // namespace duckdb namespace duckdb { -class SQLStatement; +class BaseStatistics; +class FieldWriter; +class FieldReader; +class ClientContext; -class QueryErrorContext { +//! The Expression class represents a bound Expression with a return type +class Expression : public BaseExpression { public: - explicit QueryErrorContext(SQLStatement *statement_ = nullptr, idx_t query_location_ = DConstants::INVALID_INDEX) - : statement(statement_), query_location(query_location_) { - } + Expression(ExpressionType type, ExpressionClass expression_class, LogicalType return_type); + ~Expression() override; - //! The query statement - SQLStatement *statement; - //! The location in which the error should be thrown - idx_t query_location; + //! The return type of the expression + LogicalType return_type; + //! Expression statistics (if any) - ONLY USED FOR VERIFICATION + unique_ptr verification_stats; public: - static string Format(const string &query, const string &error_message, int error_location); + bool IsAggregate() const override; + bool IsWindow() const override; + bool HasSubquery() const override; + bool IsScalar() const override; + bool HasParameter() const override; + virtual bool HasSideEffects() const; + virtual bool PropagatesNullValues() const; + virtual bool IsFoldable() const; - string FormatErrorRecursive(const string &msg, vector &values); - template - string FormatErrorRecursive(const string &msg, vector &values, T param, Args... params) { - values.push_back(ExceptionFormatValue::CreateFormatValue(param)); - return FormatErrorRecursive(msg, values, params...); + hash_t Hash() const override; + + bool Equals(const BaseExpression *other) const override { + if (!BaseExpression::Equals(other)) { + return false; + } + return return_type == ((Expression *)other)->return_type; } - template - string FormatError(const string &msg, Args... params) { - vector values; - return FormatErrorRecursive(msg, values, params...); + static bool Equals(Expression *left, Expression *right) { + return BaseExpression::Equals((BaseExpression *)left, (BaseExpression *)right); } -}; + //! Create a copy of this expression + virtual unique_ptr Copy() = 0; -} // namespace duckdb + //! Serializes an Expression to a stand-alone binary blob + void Serialize(Serializer &serializer) const; + //! Serializes an Expression to a stand-alone binary blob + virtual void Serialize(FieldWriter &writer) const = 0; + //! Deserializes a blob back into an Expression [CAN THROW: + //! SerializationException] + static unique_ptr Deserialize(Deserializer &source, PlanDeserializationState &state); -#include - - -namespace duckdb { -struct CreateSchemaInfo; -struct DropInfo; -struct BoundCreateTableInfo; -struct AlterTableInfo; -struct CreateTableFunctionInfo; -struct CreateCopyFunctionInfo; -struct CreatePragmaFunctionInfo; -struct CreateFunctionInfo; -struct CreateViewInfo; -struct CreateSequenceInfo; -struct CreateCollationInfo; -struct CreateTypeInfo; -struct CreateTableInfo; - -class ClientContext; -class Transaction; - -class AggregateFunctionCatalogEntry; -class CollateCatalogEntry; -class SchemaCatalogEntry; -class TableCatalogEntry; -class ViewCatalogEntry; -class SequenceCatalogEntry; -class TableFunctionCatalogEntry; -class CopyFunctionCatalogEntry; -class PragmaFunctionCatalogEntry; -class CatalogSet; -class DatabaseInstance; -class DependencyManager; - -//! Return value of Catalog::LookupEntry -struct CatalogEntryLookup { - SchemaCatalogEntry *schema; - CatalogEntry *entry; - - DUCKDB_API bool Found() const { - return entry; +protected: + //! Copy base Expression properties from another expression to this one, + //! used in Copy method + void CopyProperties(Expression &other) { + type = other.type; + expression_class = other.expression_class; + alias = other.alias; + return_type = other.return_type; } }; -//! Return value of SimilarEntryInSchemas -struct SimilarCatalogEntry { - //! The entry name. Empty if absent - string name; - //! The distance to the given name. - idx_t distance; - //! The schema of the entry. - SchemaCatalogEntry *schema; - - DUCKDB_API bool Found() const { - return !name.empty(); - } +} // namespace duckdb - DUCKDB_API string GetQualifiedName() const; -}; -//! The Catalog object represents the catalog of the database. -class Catalog { -public: - explicit Catalog(DatabaseInstance &db); - ~Catalog(); - //! Reference to the database - DatabaseInstance &db; - //! The catalog set holding the schemas - unique_ptr schemas; - //! The DependencyManager manages dependencies between different catalog objects - unique_ptr dependency_manager; - //! Write lock for the catalog - mutex write_lock; +namespace duckdb { +//! A ResultModifier +class BoundResultModifier { public: - //! Get the Catalog from the ClientContext - DUCKDB_API static Catalog &GetCatalog(ClientContext &context); - //! Get the Catalog from the DatabaseInstance - DUCKDB_API static Catalog &GetCatalog(DatabaseInstance &db); - - DUCKDB_API DependencyManager &GetDependencyManager() { - return *dependency_manager; - } - - //! Returns the current version of the catalog (incremented whenever anything changes, not stored between restarts) - DUCKDB_API idx_t GetCatalogVersion(); - //! Trigger a modification in the catalog, increasing the catalog version and returning the previous version - DUCKDB_API idx_t ModifyCatalog(); - - //! Creates a schema in the catalog. - DUCKDB_API CatalogEntry *CreateSchema(ClientContext &context, CreateSchemaInfo *info); - //! Creates a table in the catalog. - DUCKDB_API CatalogEntry *CreateTable(ClientContext &context, BoundCreateTableInfo *info); - //! Creates a table in the catalog. - DUCKDB_API CatalogEntry *CreateTable(ClientContext &context, unique_ptr info); - //! Create a table function in the catalog - DUCKDB_API CatalogEntry *CreateTableFunction(ClientContext &context, CreateTableFunctionInfo *info); - //! Create a copy function in the catalog - DUCKDB_API CatalogEntry *CreateCopyFunction(ClientContext &context, CreateCopyFunctionInfo *info); - //! Create a pragma function in the catalog - DUCKDB_API CatalogEntry *CreatePragmaFunction(ClientContext &context, CreatePragmaFunctionInfo *info); - //! Create a scalar or aggregate function in the catalog - DUCKDB_API CatalogEntry *CreateFunction(ClientContext &context, CreateFunctionInfo *info); - //! Creates a table in the catalog. - DUCKDB_API CatalogEntry *CreateView(ClientContext &context, CreateViewInfo *info); - //! Creates a sequence in the catalog. - DUCKDB_API CatalogEntry *CreateSequence(ClientContext &context, CreateSequenceInfo *info); - //! Creates a Enum in the catalog. - DUCKDB_API CatalogEntry *CreateType(ClientContext &context, CreateTypeInfo *info); - //! Creates a collation in the catalog - DUCKDB_API CatalogEntry *CreateCollation(ClientContext &context, CreateCollationInfo *info); + explicit BoundResultModifier(ResultModifierType type); + virtual ~BoundResultModifier(); - //! Creates a table in the catalog. - DUCKDB_API CatalogEntry *CreateTable(ClientContext &context, SchemaCatalogEntry *schema, - BoundCreateTableInfo *info); - //! Create a table function in the catalog - DUCKDB_API CatalogEntry *CreateTableFunction(ClientContext &context, SchemaCatalogEntry *schema, - CreateTableFunctionInfo *info); - //! Create a copy function in the catalog - DUCKDB_API CatalogEntry *CreateCopyFunction(ClientContext &context, SchemaCatalogEntry *schema, - CreateCopyFunctionInfo *info); - //! Create a pragma function in the catalog - DUCKDB_API CatalogEntry *CreatePragmaFunction(ClientContext &context, SchemaCatalogEntry *schema, - CreatePragmaFunctionInfo *info); - //! Create a scalar or aggregate function in the catalog - DUCKDB_API CatalogEntry *CreateFunction(ClientContext &context, SchemaCatalogEntry *schema, - CreateFunctionInfo *info); - //! Creates a table in the catalog. - DUCKDB_API CatalogEntry *CreateView(ClientContext &context, SchemaCatalogEntry *schema, CreateViewInfo *info); - //! Creates a table in the catalog. - DUCKDB_API CatalogEntry *CreateSequence(ClientContext &context, SchemaCatalogEntry *schema, - CreateSequenceInfo *info); - //! Creates a enum in the catalog. - DUCKDB_API CatalogEntry *CreateType(ClientContext &context, SchemaCatalogEntry *schema, CreateTypeInfo *info); - //! Creates a collation in the catalog - DUCKDB_API CatalogEntry *CreateCollation(ClientContext &context, SchemaCatalogEntry *schema, - CreateCollationInfo *info); + ResultModifierType type; +}; - //! Drops an entry from the catalog - DUCKDB_API void DropEntry(ClientContext &context, DropInfo *info); +struct BoundOrderByNode { +public: + BoundOrderByNode(OrderType type, OrderByNullType null_order, unique_ptr expression); + BoundOrderByNode(OrderType type, OrderByNullType null_order, unique_ptr expression, + unique_ptr stats); - //! Returns the schema object with the specified name, or throws an exception if it does not exist - DUCKDB_API SchemaCatalogEntry *GetSchema(ClientContext &context, const string &name = DEFAULT_SCHEMA, - bool if_exists = false, - QueryErrorContext error_context = QueryErrorContext()); - //! Scans all the schemas in the system one-by-one, invoking the callback for each entry - DUCKDB_API void ScanSchemas(ClientContext &context, std::function callback); - //! Gets the "schema.name" entry of the specified type, if if_exists=true returns nullptr if entry does not - //! exist, otherwise an exception is thrown - DUCKDB_API CatalogEntry *GetEntry(ClientContext &context, CatalogType type, const string &schema, - const string &name, bool if_exists = false, - QueryErrorContext error_context = QueryErrorContext()); + OrderType type; + OrderByNullType null_order; + unique_ptr expression; + unique_ptr stats; - //! Gets the "schema.name" entry without a specified type, if entry does not exist an exception is thrown - DUCKDB_API CatalogEntry *GetEntry(ClientContext &context, const string &schema, const string &name); +public: + BoundOrderByNode Copy() const; + bool Equals(const BoundOrderByNode &other) const; + string ToString() const; - //! Fetches a logical type from the catalog - DUCKDB_API LogicalType GetType(ClientContext &context, const string &schema, const string &name); + void Serialize(Serializer &serializer) const; + static BoundOrderByNode Deserialize(Deserializer &source, PlanDeserializationState &state); +}; - template - T *GetEntry(ClientContext &context, const string &schema_name, const string &name, bool if_exists = false, - QueryErrorContext error_context = QueryErrorContext()); +class BoundLimitModifier : public BoundResultModifier { +public: + BoundLimitModifier(); - //! Append a scalar or aggregate function to the catalog - DUCKDB_API CatalogEntry *AddFunction(ClientContext &context, CreateFunctionInfo *info); - //! Append a scalar or aggregate function to the catalog - DUCKDB_API CatalogEntry *AddFunction(ClientContext &context, SchemaCatalogEntry *schema, CreateFunctionInfo *info); + //! LIMIT + int64_t limit_val = NumericLimits::Maximum(); + //! OFFSET + int64_t offset_val = 0; + //! Expression in case limit is not constant + unique_ptr limit; + //! Expression in case limit is not constant + unique_ptr offset; +}; - //! Alter an existing entry in the catalog. - DUCKDB_API void Alter(ClientContext &context, AlterInfo *info); +class BoundOrderModifier : public BoundResultModifier { +public: + BoundOrderModifier(); -private: - //! The catalog version, incremented whenever anything changes in the catalog - atomic catalog_version; + //! List of order nodes + vector orders; +}; -private: - //! A variation of GetEntry that returns an associated schema as well. - CatalogEntryLookup LookupEntry(ClientContext &context, CatalogType type, const string &schema, const string &name, - bool if_exists = false, QueryErrorContext error_context = QueryErrorContext()); +class BoundDistinctModifier : public BoundResultModifier { +public: + BoundDistinctModifier(); - //! Return an exception with did-you-mean suggestion. - CatalogException CreateMissingEntryException(ClientContext &context, const string &entry_name, CatalogType type, - const vector &schemas, - QueryErrorContext error_context); + //! list of distinct on targets (if any) + vector> target_distincts; +}; - //! Return the close entry name, the distance and the belonging schema. - SimilarCatalogEntry SimilarEntryInSchemas(ClientContext &context, const string &entry_name, CatalogType type, - const vector &schemas); +class BoundLimitPercentModifier : public BoundResultModifier { +public: + BoundLimitPercentModifier(); - void DropSchema(ClientContext &context, DropInfo *info); + //! LIMIT % + double limit_percent = 100.0; + //! OFFSET + int64_t offset_val = 0; + //! Expression in case limit is not constant + unique_ptr limit; + //! Expression in case limit is not constant + unique_ptr offset; }; -template <> -DUCKDB_API TableCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name, - bool if_exists, QueryErrorContext error_context); -template <> -DUCKDB_API SequenceCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, - const string &name, bool if_exists, QueryErrorContext error_context); -template <> -DUCKDB_API TableFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, - const string &name, bool if_exists, - QueryErrorContext error_context); -template <> -DUCKDB_API CopyFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, - const string &name, bool if_exists, - QueryErrorContext error_context); -template <> -DUCKDB_API PragmaFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, - const string &name, bool if_exists, - QueryErrorContext error_context); -template <> -DUCKDB_API AggregateFunctionCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, - const string &name, bool if_exists, - QueryErrorContext error_context); -template <> -DUCKDB_API CollateCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name, - bool if_exists, QueryErrorContext error_context); -template <> -DUCKDB_API TypeCatalogEntry *Catalog::GetEntry(ClientContext &context, const string &schema_name, const string &name, - bool if_exists, QueryErrorContext error_context); - } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/optimizer/estimated_properties.hpp -// -// -//===----------------------------------------------------------------------===// - - - - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/join_order/join_relation.hpp +// duckdb/common/vector_operations/aggregate_executor.hpp // // //===----------------------------------------------------------------------===// @@ -9501,568 +9566,987 @@ DUCKDB_API TypeCatalogEntry *Catalog::GetEntry(ClientContext &context, const str namespace duckdb { -class LogicalOperator; -//! Represents a single relation and any metadata accompanying that relation -struct SingleJoinRelation { - LogicalOperator *op; - LogicalOperator *parent; +struct AggregateInputData; - SingleJoinRelation() { - } - SingleJoinRelation(LogicalOperator *op, LogicalOperator *parent) : op(op), parent(parent) { - } -}; +typedef std::pair FrameBounds; -//! Set of relations, used in the join graph. -struct JoinRelationSet { - JoinRelationSet(unique_ptr relations, idx_t count) : relations(move(relations)), count(count) { +class AggregateExecutor { +private: + template + static inline void NullaryFlatLoop(STATE_TYPE **__restrict states, AggregateInputData &aggr_input_data, + idx_t count) { + for (idx_t i = 0; i < count; i++) { + OP::template Operation(states[i], aggr_input_data, i); + } } - string ToString() const; - - unique_ptr relations; - idx_t count; - - static bool IsSubset(JoinRelationSet *super, JoinRelationSet *sub); -}; - -//! The JoinRelationTree is a structure holding all the created JoinRelationSet objects and allowing fast lookup on to -//! them -class JoinRelationSetManager { -public: - //! Contains a node with a JoinRelationSet and child relations - // FIXME: this structure is inefficient, could use a bitmap for lookup instead (todo: profile) - struct JoinRelationTreeNode { - unique_ptr relation; - unordered_map> children; - }; - -public: - //! Create or get a JoinRelationSet from a single node with the given index - JoinRelationSet *GetJoinRelation(idx_t index); - //! Create or get a JoinRelationSet from a set of relation bindings - JoinRelationSet *GetJoinRelation(unordered_set &bindings); - //! Create or get a JoinRelationSet from a (sorted, duplicate-free!) list of relations - JoinRelationSet *GetJoinRelation(unique_ptr relations, idx_t count); - //! Union two sets of relations together and create a new relation set - JoinRelationSet *Union(JoinRelationSet *left, JoinRelationSet *right); - // //! Create the set difference of left \ right (i.e. all elements in left that are not in right) - // JoinRelationSet *Difference(JoinRelationSet *left, JoinRelationSet *right); - -private: - JoinRelationTreeNode root; -}; - -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/expression_map.hpp -// -// -//===----------------------------------------------------------------------===// - + template + static inline void NullaryScatterLoop(STATE_TYPE **__restrict states, AggregateInputData &aggr_input_data, + const SelectionVector &ssel, idx_t count) { + for (idx_t i = 0; i < count; i++) { + auto sidx = ssel.get_index(i); + OP::template Operation(states[sidx], aggr_input_data, sidx); + } + } + template + static inline void UnaryFlatLoop(INPUT_TYPE *__restrict idata, AggregateInputData &aggr_input_data, + STATE_TYPE **__restrict states, ValidityMask &mask, idx_t count) { + if (!mask.AllValid()) { + idx_t base_idx = 0; + auto entry_count = ValidityMask::EntryCount(count); + for (idx_t entry_idx = 0; entry_idx < entry_count; entry_idx++) { + auto validity_entry = mask.GetValidityEntry(entry_idx); + idx_t next = MinValue(base_idx + ValidityMask::BITS_PER_VALUE, count); + if (!OP::IgnoreNull() || ValidityMask::AllValid(validity_entry)) { + // all valid: perform operation + for (; base_idx < next; base_idx++) { + OP::template Operation(states[base_idx], aggr_input_data, idata, + mask, base_idx); + } + } else if (ValidityMask::NoneValid(validity_entry)) { + // nothing valid: skip all + base_idx = next; + continue; + } else { + // partially valid: need to check individual elements for validity + idx_t start = base_idx; + for (; base_idx < next; base_idx++) { + if (ValidityMask::RowIsValid(validity_entry, base_idx - start)) { + OP::template Operation(states[base_idx], aggr_input_data, idata, + mask, base_idx); + } + } + } + } + } else { + for (idx_t i = 0; i < count; i++) { + OP::template Operation(states[i], aggr_input_data, idata, mask, i); + } + } + } + template + static inline void UnaryScatterLoop(INPUT_TYPE *__restrict idata, AggregateInputData &aggr_input_data, + STATE_TYPE **__restrict states, const SelectionVector &isel, + const SelectionVector &ssel, ValidityMask &mask, idx_t count) { + if (OP::IgnoreNull() && !mask.AllValid()) { + // potential NULL values and NULL values are ignored + for (idx_t i = 0; i < count; i++) { + auto idx = isel.get_index(i); + auto sidx = ssel.get_index(i); + if (mask.RowIsValid(idx)) { + OP::template Operation(states[sidx], aggr_input_data, idata, mask, idx); + } + } + } else { + // quick path: no NULL values or NULL values are not ignored + for (idx_t i = 0; i < count; i++) { + auto idx = isel.get_index(i); + auto sidx = ssel.get_index(i); + OP::template Operation(states[sidx], aggr_input_data, idata, mask, idx); + } + } + } + template + static inline void UnaryFlatUpdateLoop(INPUT_TYPE *__restrict idata, AggregateInputData &aggr_input_data, + STATE_TYPE *__restrict state, idx_t count, ValidityMask &mask) { + idx_t base_idx = 0; + auto entry_count = ValidityMask::EntryCount(count); + for (idx_t entry_idx = 0; entry_idx < entry_count; entry_idx++) { + auto validity_entry = mask.GetValidityEntry(entry_idx); + idx_t next = MinValue(base_idx + ValidityMask::BITS_PER_VALUE, count); + if (!OP::IgnoreNull() || ValidityMask::AllValid(validity_entry)) { + // all valid: perform operation + for (; base_idx < next; base_idx++) { + OP::template Operation(state, aggr_input_data, idata, mask, base_idx); + } + } else if (ValidityMask::NoneValid(validity_entry)) { + // nothing valid: skip all + base_idx = next; + continue; + } else { + // partially valid: need to check individual elements for validity + idx_t start = base_idx; + for (; base_idx < next; base_idx++) { + if (ValidityMask::RowIsValid(validity_entry, base_idx - start)) { + OP::template Operation(state, aggr_input_data, idata, mask, + base_idx); + } + } + } + } + } + template + static inline void UnaryUpdateLoop(INPUT_TYPE *__restrict idata, AggregateInputData &aggr_input_data, + STATE_TYPE *__restrict state, idx_t count, ValidityMask &mask, + const SelectionVector &__restrict sel_vector) { + if (OP::IgnoreNull() && !mask.AllValid()) { + // potential NULL values and NULL values are ignored + for (idx_t i = 0; i < count; i++) { + auto idx = sel_vector.get_index(i); + if (mask.RowIsValid(idx)) { + OP::template Operation(state, aggr_input_data, idata, mask, idx); + } + } + } else { + // quick path: no NULL values or NULL values are not ignored + for (idx_t i = 0; i < count; i++) { + auto idx = sel_vector.get_index(i); + OP::template Operation(state, aggr_input_data, idata, mask, idx); + } + } + } -namespace duckdb { -class Expression; + template + static inline void BinaryScatterLoop(A_TYPE *__restrict adata, AggregateInputData &aggr_input_data, + B_TYPE *__restrict bdata, STATE_TYPE **__restrict states, idx_t count, + const SelectionVector &asel, const SelectionVector &bsel, + const SelectionVector &ssel, ValidityMask &avalidity, + ValidityMask &bvalidity) { + if (OP::IgnoreNull() && (!avalidity.AllValid() || !bvalidity.AllValid())) { + // potential NULL values and NULL values are ignored + for (idx_t i = 0; i < count; i++) { + auto aidx = asel.get_index(i); + auto bidx = bsel.get_index(i); + auto sidx = ssel.get_index(i); + if (avalidity.RowIsValid(aidx) && bvalidity.RowIsValid(bidx)) { + OP::template Operation(states[sidx], aggr_input_data, adata, bdata, + avalidity, bvalidity, aidx, bidx); + } + } + } else { + // quick path: no NULL values or NULL values are not ignored + for (idx_t i = 0; i < count; i++) { + auto aidx = asel.get_index(i); + auto bidx = bsel.get_index(i); + auto sidx = ssel.get_index(i); + OP::template Operation(states[sidx], aggr_input_data, adata, bdata, + avalidity, bvalidity, aidx, bidx); + } + } + } -struct ExpressionHashFunction { - uint64_t operator()(const BaseExpression *const &expr) const { - return (uint64_t)expr->Hash(); + template + static inline void BinaryUpdateLoop(A_TYPE *__restrict adata, AggregateInputData &aggr_input_data, + B_TYPE *__restrict bdata, STATE_TYPE *__restrict state, idx_t count, + const SelectionVector &asel, const SelectionVector &bsel, + ValidityMask &avalidity, ValidityMask &bvalidity) { + if (OP::IgnoreNull() && (!avalidity.AllValid() || !bvalidity.AllValid())) { + // potential NULL values and NULL values are ignored + for (idx_t i = 0; i < count; i++) { + auto aidx = asel.get_index(i); + auto bidx = bsel.get_index(i); + if (avalidity.RowIsValid(aidx) && bvalidity.RowIsValid(bidx)) { + OP::template Operation(state, aggr_input_data, adata, bdata, + avalidity, bvalidity, aidx, bidx); + } + } + } else { + // quick path: no NULL values or NULL values are not ignored + for (idx_t i = 0; i < count; i++) { + auto aidx = asel.get_index(i); + auto bidx = bsel.get_index(i); + OP::template Operation(state, aggr_input_data, adata, bdata, avalidity, + bvalidity, aidx, bidx); + } + } } -}; -struct ExpressionEquality { - bool operator()(const BaseExpression *const &a, const BaseExpression *const &b) const { - return a->Equals(b); +public: + template + static void NullaryScatter(Vector &states, AggregateInputData &aggr_input_data, idx_t count) { + if (states.GetVectorType() == VectorType::CONSTANT_VECTOR) { + auto sdata = ConstantVector::GetData(states); + OP::template ConstantOperation(*sdata, aggr_input_data, count); + } else if (states.GetVectorType() == VectorType::FLAT_VECTOR) { + auto sdata = FlatVector::GetData(states); + NullaryFlatLoop(sdata, aggr_input_data, count); + } else { + UnifiedVectorFormat sdata; + states.ToUnifiedFormat(count, sdata); + NullaryScatterLoop((STATE_TYPE **)sdata.data, aggr_input_data, *sdata.sel, count); + } } -}; -template -using expression_map_t = unordered_map; + template + static void NullaryUpdate(data_ptr_t state, AggregateInputData &aggr_input_data, idx_t count) { + OP::template ConstantOperation((STATE_TYPE *)state, aggr_input_data, count); + } -using expression_set_t = unordered_set; + template + static void UnaryScatter(Vector &input, Vector &states, AggregateInputData &aggr_input_data, idx_t count) { + if (input.GetVectorType() == VectorType::CONSTANT_VECTOR && + states.GetVectorType() == VectorType::CONSTANT_VECTOR) { + if (OP::IgnoreNull() && ConstantVector::IsNull(input)) { + // constant NULL input in function that ignores NULL values + return; + } + // regular constant: get first state + auto idata = ConstantVector::GetData(input); + auto sdata = ConstantVector::GetData(states); + OP::template ConstantOperation(*sdata, aggr_input_data, idata, + ConstantVector::Validity(input), count); + } else if (input.GetVectorType() == VectorType::FLAT_VECTOR && + states.GetVectorType() == VectorType::FLAT_VECTOR) { + auto idata = FlatVector::GetData(input); + auto sdata = FlatVector::GetData(states); + UnaryFlatLoop(idata, aggr_input_data, sdata, FlatVector::Validity(input), + count); + } else { + UnifiedVectorFormat idata, sdata; + input.ToUnifiedFormat(count, idata); + states.ToUnifiedFormat(count, sdata); + UnaryScatterLoop((INPUT_TYPE *)idata.data, aggr_input_data, + (STATE_TYPE **)sdata.data, *idata.sel, *sdata.sel, + idata.validity, count); + } + } -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/logical_operator_visitor.hpp -// -// -//===----------------------------------------------------------------------===// + template + static void UnaryUpdate(Vector &input, AggregateInputData &aggr_input_data, data_ptr_t state, idx_t count) { + switch (input.GetVectorType()) { + case VectorType::CONSTANT_VECTOR: { + if (OP::IgnoreNull() && ConstantVector::IsNull(input)) { + return; + } + auto idata = ConstantVector::GetData(input); + OP::template ConstantOperation((STATE_TYPE *)state, aggr_input_data, idata, + ConstantVector::Validity(input), count); + break; + } + case VectorType::FLAT_VECTOR: { + auto idata = FlatVector::GetData(input); + UnaryFlatUpdateLoop(idata, aggr_input_data, (STATE_TYPE *)state, count, + FlatVector::Validity(input)); + break; + } + default: { + UnifiedVectorFormat idata; + input.ToUnifiedFormat(count, idata); + UnaryUpdateLoop((INPUT_TYPE *)idata.data, aggr_input_data, (STATE_TYPE *)state, + count, idata.validity, *idata.sel); + break; + } + } + } + template + static void BinaryScatter(AggregateInputData &aggr_input_data, Vector &a, Vector &b, Vector &states, idx_t count) { + UnifiedVectorFormat adata, bdata, sdata; + a.ToUnifiedFormat(count, adata); + b.ToUnifiedFormat(count, bdata); + states.ToUnifiedFormat(count, sdata); + BinaryScatterLoop((A_TYPE *)adata.data, aggr_input_data, (B_TYPE *)bdata.data, + (STATE_TYPE **)sdata.data, count, *adata.sel, *bdata.sel, + *sdata.sel, adata.validity, bdata.validity); + } -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/bound_tokens.hpp -// -// -//===----------------------------------------------------------------------===// + template + static void BinaryUpdate(AggregateInputData &aggr_input_data, Vector &a, Vector &b, data_ptr_t state, idx_t count) { + UnifiedVectorFormat adata, bdata; + a.ToUnifiedFormat(count, adata); + b.ToUnifiedFormat(count, bdata); + BinaryUpdateLoop((A_TYPE *)adata.data, aggr_input_data, (B_TYPE *)bdata.data, + (STATE_TYPE *)state, count, *adata.sel, *bdata.sel, + adata.validity, bdata.validity); + } -namespace duckdb { + template + static void Combine(Vector &source, Vector &target, AggregateInputData &aggr_input_data, idx_t count) { + D_ASSERT(source.GetType().id() == LogicalTypeId::POINTER && target.GetType().id() == LogicalTypeId::POINTER); + auto sdata = FlatVector::GetData(source); + auto tdata = FlatVector::GetData(target); -//===--------------------------------------------------------------------===// -// Query Node -//===--------------------------------------------------------------------===// -class BoundQueryNode; -class BoundSelectNode; -class BoundSetOperationNode; -class BoundRecursiveCTENode; + for (idx_t i = 0; i < count; i++) { + OP::template Combine(*sdata[i], tdata[i], aggr_input_data); + } + } -//===--------------------------------------------------------------------===// -// Expressions -//===--------------------------------------------------------------------===// -class Expression; + template + static void Finalize(Vector &states, AggregateInputData &aggr_input_data, Vector &result, idx_t count, + idx_t offset) { + if (states.GetVectorType() == VectorType::CONSTANT_VECTOR) { + result.SetVectorType(VectorType::CONSTANT_VECTOR); -class BoundAggregateExpression; -class BoundBetweenExpression; -class BoundCaseExpression; -class BoundCastExpression; -class BoundColumnRefExpression; -class BoundComparisonExpression; -class BoundConjunctionExpression; -class BoundConstantExpression; -class BoundDefaultExpression; -class BoundFunctionExpression; -class BoundOperatorExpression; -class BoundParameterExpression; -class BoundReferenceExpression; -class BoundSubqueryExpression; -class BoundUnnestExpression; -class BoundWindowExpression; + auto sdata = ConstantVector::GetData(states); + auto rdata = ConstantVector::GetData(result); + OP::template Finalize(result, aggr_input_data, *sdata, rdata, + ConstantVector::Validity(result), 0); + } else { + D_ASSERT(states.GetVectorType() == VectorType::FLAT_VECTOR); + result.SetVectorType(VectorType::FLAT_VECTOR); -//===--------------------------------------------------------------------===// -// TableRefs -//===--------------------------------------------------------------------===// -class BoundTableRef; + auto sdata = FlatVector::GetData(states); + auto rdata = FlatVector::GetData(result); + for (idx_t i = 0; i < count; i++) { + OP::template Finalize(result, aggr_input_data, sdata[i], rdata, + FlatVector::Validity(result), i + offset); + } + } + } -class BoundBaseTableRef; -class BoundCrossProductRef; -class BoundJoinRef; -class BoundSubqueryRef; -class BoundTableFunction; -class BoundEmptyTableRef; -class BoundExpressionListRef; -class BoundCTERef; + template + static void UnaryWindow(Vector &input, const ValidityMask &ifilter, AggregateInputData &aggr_input_data, + data_ptr_t state, const FrameBounds &frame, const FrameBounds &prev, Vector &result, + idx_t rid, idx_t bias) { -} // namespace duckdb + auto idata = FlatVector::GetData(input) - bias; + const auto &ivalid = FlatVector::Validity(input); + OP::template Window(idata, ifilter, ivalid, aggr_input_data, (STATE *)state, + frame, prev, result, rid, bias); + } -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/logical_tokens.hpp -// -// -//===----------------------------------------------------------------------===// + template + static void Destroy(Vector &states, idx_t count) { + auto sdata = FlatVector::GetData(states); + for (idx_t i = 0; i < count; i++) { + OP::template Destroy(sdata[i]); + } + } +}; +} // namespace duckdb namespace duckdb { -class LogicalOperator; - -class LogicalAggregate; -class LogicalAnyJoin; -class LogicalColumnDataGet; -class LogicalComparisonJoin; -class LogicalCopyToFile; -class LogicalCreate; -class LogicalCreateTable; -class LogicalCreateIndex; -class LogicalCreateTable; -class LogicalCrossProduct; -class LogicalCTERef; -class LogicalDelete; -class LogicalDelimGet; -class LogicalDelimJoin; -class LogicalDistinct; -class LogicalDummyScan; -class LogicalEmptyResult; -class LogicalExecute; -class LogicalExplain; -class LogicalExport; -class LogicalExpressionGet; -class LogicalFilter; -class LogicalGet; -class LogicalInsert; -class LogicalJoin; -class LogicalLimit; -class LogicalOrder; -class LogicalPragma; -class LogicalPrepare; -class LogicalProjection; -class LogicalRecursiveCTE; -class LogicalSetOperation; -class LogicalSample; -class LogicalShow; -class LogicalSimple; -class LogicalSet; -class LogicalTopN; -class LogicalUnnest; -class LogicalUpdate; -class LogicalWindow; +//! This allows us to use the & operator to check if the type is contained in the set +enum class AggregateType : uint8_t { NON_DISTINCT = 1, DISTINCT = 2 }; -} // namespace duckdb +class BoundAggregateExpression; +struct AggregateInputData { + AggregateInputData(FunctionData *bind_data_p, Allocator &allocator_p) + : bind_data(bind_data_p), allocator(allocator_p) {}; + FunctionData *bind_data; + Allocator &allocator; +}; -#include +//! The type used for sizing hashed aggregate function states +typedef idx_t (*aggregate_size_t)(); +//! The type used for initializing hashed aggregate function states +typedef void (*aggregate_initialize_t)(data_ptr_t state); +//! The type used for updating hashed aggregate functions +typedef void (*aggregate_update_t)(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, + Vector &state, idx_t count); +//! The type used for combining hashed aggregate states +typedef void (*aggregate_combine_t)(Vector &state, Vector &combined, AggregateInputData &aggr_input_data, idx_t count); +//! The type used for finalizing hashed aggregate function payloads +typedef void (*aggregate_finalize_t)(Vector &state, AggregateInputData &aggr_input_data, Vector &result, idx_t count, + idx_t offset); +//! The type used for propagating statistics in aggregate functions (optional) +typedef unique_ptr (*aggregate_statistics_t)(ClientContext &context, BoundAggregateExpression &expr, + FunctionData *bind_data, + vector> &child_stats, + NodeStatistics *node_stats); +//! Binds the scalar function and creates the function data +typedef unique_ptr (*bind_aggregate_function_t)(ClientContext &context, AggregateFunction &function, + vector> &arguments); +//! The type used for the aggregate destructor method. NOTE: this method is used in destructors and MAY NOT throw. +typedef void (*aggregate_destructor_t)(Vector &state, idx_t count); -namespace duckdb { -//! The LogicalOperatorVisitor is an abstract base class that implements the -//! Visitor pattern on LogicalOperator. -class LogicalOperatorVisitor { -public: - virtual ~LogicalOperatorVisitor() {}; +//! The type used for updating simple (non-grouped) aggregate functions +typedef void (*aggregate_simple_update_t)(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, + data_ptr_t state, idx_t count); - virtual void VisitOperator(LogicalOperator &op); - virtual void VisitExpression(unique_ptr *expression); +//! The type used for updating complex windowed aggregate functions (optional) +typedef std::pair FrameBounds; +typedef void (*aggregate_window_t)(Vector inputs[], const ValidityMask &filter_mask, + AggregateInputData &aggr_input_data, idx_t input_count, data_ptr_t state, + const FrameBounds &frame, const FrameBounds &prev, Vector &result, idx_t rid, + idx_t bias); - static void EnumerateExpressions(LogicalOperator &op, - const std::function *child)> &callback); +typedef void (*aggregate_serialize_t)(FieldWriter &writer, const FunctionData *bind_data, + const AggregateFunction &function); +typedef unique_ptr (*aggregate_deserialize_t)(ClientContext &context, FieldReader &reader, + AggregateFunction &function); -protected: - //! Automatically calls the Visit method for LogicalOperator children of the current operator. Can be overloaded to - //! change this behavior. - void VisitOperatorChildren(LogicalOperator &op); - //! Automatically calls the Visit method for Expression children of the current operator. Can be overloaded to - //! change this behavior. - void VisitOperatorExpressions(LogicalOperator &op); +class AggregateFunction : public BaseScalarFunction { +public: + DUCKDB_API + AggregateFunction(const string &name, const vector &arguments, const LogicalType &return_type, + aggregate_size_t state_size, aggregate_initialize_t initialize, aggregate_update_t update, + aggregate_combine_t combine, aggregate_finalize_t finalize, + FunctionNullHandling null_handling = FunctionNullHandling::DEFAULT_NULL_HANDLING, + aggregate_simple_update_t simple_update = nullptr, bind_aggregate_function_t bind = nullptr, + aggregate_destructor_t destructor = nullptr, aggregate_statistics_t statistics = nullptr, + aggregate_window_t window = nullptr, aggregate_serialize_t serialize = nullptr, + aggregate_deserialize_t deserialize = nullptr) + : BaseScalarFunction(name, arguments, return_type, FunctionSideEffects::NO_SIDE_EFFECTS, + LogicalType(LogicalTypeId::INVALID), null_handling), + state_size(state_size), initialize(initialize), update(update), combine(combine), finalize(finalize), + simple_update(simple_update), window(window), bind(bind), destructor(destructor), statistics(statistics), + serialize(serialize), deserialize(deserialize) { + } - // The VisitExpressionChildren method is called at the end of every call to VisitExpression to recursively visit all - // expressions in an expression tree. It can be overloaded to prevent automatically visiting the entire tree. - virtual void VisitExpressionChildren(Expression &expression); + DUCKDB_API + AggregateFunction(const string &name, const vector &arguments, const LogicalType &return_type, + aggregate_size_t state_size, aggregate_initialize_t initialize, aggregate_update_t update, + aggregate_combine_t combine, aggregate_finalize_t finalize, + aggregate_simple_update_t simple_update = nullptr, bind_aggregate_function_t bind = nullptr, + aggregate_destructor_t destructor = nullptr, aggregate_statistics_t statistics = nullptr, + aggregate_window_t window = nullptr, aggregate_serialize_t serialize = nullptr, + aggregate_deserialize_t deserialize = nullptr) + : BaseScalarFunction(name, arguments, return_type, FunctionSideEffects::NO_SIDE_EFFECTS, + LogicalType(LogicalTypeId::INVALID)), + state_size(state_size), initialize(initialize), update(update), combine(combine), finalize(finalize), + simple_update(simple_update), window(window), bind(bind), destructor(destructor), statistics(statistics), + serialize(serialize), deserialize(deserialize) { + } - virtual unique_ptr VisitReplace(BoundAggregateExpression &expr, unique_ptr *expr_ptr); - virtual unique_ptr VisitReplace(BoundBetweenExpression &expr, unique_ptr *expr_ptr); - virtual unique_ptr VisitReplace(BoundCaseExpression &expr, unique_ptr *expr_ptr); - virtual unique_ptr VisitReplace(BoundCastExpression &expr, unique_ptr *expr_ptr); - virtual unique_ptr VisitReplace(BoundColumnRefExpression &expr, unique_ptr *expr_ptr); - virtual unique_ptr VisitReplace(BoundComparisonExpression &expr, unique_ptr *expr_ptr); - virtual unique_ptr VisitReplace(BoundConjunctionExpression &expr, unique_ptr *expr_ptr); - virtual unique_ptr VisitReplace(BoundConstantExpression &expr, unique_ptr *expr_ptr); - virtual unique_ptr VisitReplace(BoundDefaultExpression &expr, unique_ptr *expr_ptr); - virtual unique_ptr VisitReplace(BoundFunctionExpression &expr, unique_ptr *expr_ptr); - virtual unique_ptr VisitReplace(BoundOperatorExpression &expr, unique_ptr *expr_ptr); - virtual unique_ptr VisitReplace(BoundReferenceExpression &expr, unique_ptr *expr_ptr); - virtual unique_ptr VisitReplace(BoundSubqueryExpression &expr, unique_ptr *expr_ptr); - virtual unique_ptr VisitReplace(BoundParameterExpression &expr, unique_ptr *expr_ptr); - virtual unique_ptr VisitReplace(BoundWindowExpression &expr, unique_ptr *expr_ptr); - virtual unique_ptr VisitReplace(BoundUnnestExpression &expr, unique_ptr *expr_ptr); -}; -} // namespace duckdb + DUCKDB_API AggregateFunction(const vector &arguments, const LogicalType &return_type, + aggregate_size_t state_size, aggregate_initialize_t initialize, + aggregate_update_t update, aggregate_combine_t combine, aggregate_finalize_t finalize, + FunctionNullHandling null_handling = FunctionNullHandling::DEFAULT_NULL_HANDLING, + aggregate_simple_update_t simple_update = nullptr, + bind_aggregate_function_t bind = nullptr, aggregate_destructor_t destructor = nullptr, + aggregate_statistics_t statistics = nullptr, aggregate_window_t window = nullptr, + aggregate_serialize_t serialize = nullptr, + aggregate_deserialize_t deserialize = nullptr) + : AggregateFunction(string(), arguments, return_type, state_size, initialize, update, combine, finalize, + null_handling, simple_update, bind, destructor, statistics, window, serialize, + deserialize) { + } -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/storage/statistics/distinct_statistics.hpp -// -// -//===----------------------------------------------------------------------===// + DUCKDB_API + AggregateFunction(const vector &arguments, const LogicalType &return_type, aggregate_size_t state_size, + aggregate_initialize_t initialize, aggregate_update_t update, aggregate_combine_t combine, + aggregate_finalize_t finalize, aggregate_simple_update_t simple_update = nullptr, + bind_aggregate_function_t bind = nullptr, aggregate_destructor_t destructor = nullptr, + aggregate_statistics_t statistics = nullptr, aggregate_window_t window = nullptr, + aggregate_serialize_t serialize = nullptr, aggregate_deserialize_t deserialize = nullptr) + : AggregateFunction(string(), arguments, return_type, state_size, initialize, update, combine, finalize, + FunctionNullHandling::DEFAULT_NULL_HANDLING, simple_update, bind, destructor, statistics, + window, serialize, deserialize) { + } + //! The hashed aggregate state sizing function + aggregate_size_t state_size; + //! The hashed aggregate state initialization function + aggregate_initialize_t initialize; + //! The hashed aggregate update state function + aggregate_update_t update; + //! The hashed aggregate combine states function + aggregate_combine_t combine; + //! The hashed aggregate finalization function + aggregate_finalize_t finalize; + //! The simple aggregate update function (may be null) + aggregate_simple_update_t simple_update; + //! The windowed aggregate frame update function (may be null) + aggregate_window_t window; + //! The bind function (may be null) + bind_aggregate_function_t bind; + //! The destructor method (may be null) + aggregate_destructor_t destructor; + //! The statistics propagation function (may be null) + aggregate_statistics_t statistics; + aggregate_serialize_t serialize; + aggregate_deserialize_t deserialize; -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/types/hyperloglog.hpp -// -// -//===----------------------------------------------------------------------===// + DUCKDB_API bool operator==(const AggregateFunction &rhs) const { + return state_size == rhs.state_size && initialize == rhs.initialize && update == rhs.update && + combine == rhs.combine && finalize == rhs.finalize && window == rhs.window; + } + DUCKDB_API bool operator!=(const AggregateFunction &rhs) const { + return !(*this == rhs); + } +public: + template + static AggregateFunction NullaryAggregate(LogicalType return_type) { + return AggregateFunction( + {}, return_type, AggregateFunction::StateSize, AggregateFunction::StateInitialize, + AggregateFunction::NullaryScatterUpdate, AggregateFunction::StateCombine, + AggregateFunction::StateFinalize, AggregateFunction::NullaryUpdate); + } + template + static AggregateFunction + UnaryAggregate(const LogicalType &input_type, LogicalType return_type, + FunctionNullHandling null_handling = FunctionNullHandling::DEFAULT_NULL_HANDLING) { + return AggregateFunction( + {input_type}, return_type, AggregateFunction::StateSize, + AggregateFunction::StateInitialize, AggregateFunction::UnaryScatterUpdate, + AggregateFunction::StateCombine, AggregateFunction::StateFinalize, + null_handling, AggregateFunction::UnaryUpdate); + } + template + static AggregateFunction UnaryAggregateDestructor(LogicalType input_type, LogicalType return_type) { + auto aggregate = UnaryAggregate(input_type, return_type); + aggregate.destructor = AggregateFunction::StateDestroy; + return aggregate; + } + template + static AggregateFunction BinaryAggregate(const LogicalType &a_type, const LogicalType &b_type, + LogicalType return_type) { + return AggregateFunction({a_type, b_type}, return_type, AggregateFunction::StateSize, + AggregateFunction::StateInitialize, + AggregateFunction::BinaryScatterUpdate, + AggregateFunction::StateCombine, + AggregateFunction::StateFinalize, + AggregateFunction::BinaryUpdate); + } +public: + template + static idx_t StateSize() { + return sizeof(STATE); + } + template + static void StateInitialize(data_ptr_t state) { + OP::Initialize((STATE *)state); + } -// LICENSE_CHANGE_BEGIN -// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #1 -// See the end of this file for a list + template + static void NullaryScatterUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, + Vector &states, idx_t count) { + D_ASSERT(input_count == 0); + AggregateExecutor::NullaryScatter(states, aggr_input_data, count); + } -//===----------------------------------------------------------------------===// -// DuckDB -// -// third_party/hyperloglog/hyperloglog.hpp -// -// -//===----------------------------------------------------------------------===// + template + static void NullaryUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, data_ptr_t state, + idx_t count) { + D_ASSERT(input_count == 0); + AggregateExecutor::NullaryUpdate(state, aggr_input_data, count); + } + template + static void UnaryScatterUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, + Vector &states, idx_t count) { + D_ASSERT(input_count == 1); + AggregateExecutor::UnaryScatter(inputs[0], states, aggr_input_data, count); + } + template + static void UnaryUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, data_ptr_t state, + idx_t count) { + D_ASSERT(input_count == 1); + AggregateExecutor::UnaryUpdate(inputs[0], aggr_input_data, state, count); + } -#include -#include + template + static void UnaryWindow(Vector inputs[], const ValidityMask &filter_mask, AggregateInputData &aggr_input_data, + idx_t input_count, data_ptr_t state, const FrameBounds &frame, const FrameBounds &prev, + Vector &result, idx_t rid, idx_t bias) { + D_ASSERT(input_count == 1); + AggregateExecutor::UnaryWindow(inputs[0], filter_mask, aggr_input_data, + state, frame, prev, result, rid, bias); + } -namespace duckdb_hll { + template + static void BinaryScatterUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, + Vector &states, idx_t count) { + D_ASSERT(input_count == 2); + AggregateExecutor::BinaryScatter(aggr_input_data, inputs[0], inputs[1], states, + count); + } -/* Error codes */ -#define HLL_C_OK 0 -#define HLL_C_ERR -1 + template + static void BinaryUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, data_ptr_t state, + idx_t count) { + D_ASSERT(input_count == 2); + AggregateExecutor::BinaryUpdate(aggr_input_data, inputs[0], inputs[1], state, count); + } -typedef struct { - void *ptr; -} robj; + template + static void StateCombine(Vector &source, Vector &target, AggregateInputData &aggr_input_data, idx_t count) { + AggregateExecutor::Combine(source, target, aggr_input_data, count); + } -//! Create a new empty HyperLogLog object -robj *hll_create(void); -//! Convert hll from sparse to dense -int hllSparseToDense(robj *o); -//! Destroy the specified HyperLogLog object -void hll_destroy(robj *obj); -//! Add an element with the specified amount of bytes to the HyperLogLog. Returns C_ERR on failure, otherwise returns 0 -//! if the cardinality did not change, and 1 otherwise. -int hll_add(robj *o, unsigned char *ele, size_t elesize); -//! Returns the estimated amount of unique elements seen by the HyperLogLog. Returns C_OK on success, or C_ERR on -//! failure. -int hll_count(robj *o, size_t *result); -//! Merge hll_count HyperLogLog objects into a single one. Returns NULL on failure, or the new HLL object on success. -robj *hll_merge(robj **hlls, size_t hll_count); -//! Get size (in bytes) of the HLL -uint64_t get_size(); + template + static void StateFinalize(Vector &states, AggregateInputData &aggr_input_data, Vector &result, idx_t count, + idx_t offset) { + AggregateExecutor::Finalize(states, aggr_input_data, result, count, offset); + } -uint64_t MurmurHash64A(const void *key, int len, unsigned int seed); - -} // namespace duckdb_hll - -namespace duckdb { - -void AddToLogsInternal(UnifiedVectorFormat &vdata, idx_t count, uint64_t indices[], uint8_t counts[], void ***logs[], - const SelectionVector *log_sel); - -void AddToSingleLogInternal(UnifiedVectorFormat &vdata, idx_t count, uint64_t indices[], uint8_t counts[], void *log); + template + static void StateDestroy(Vector &states, idx_t count) { + AggregateExecutor::Destroy(states, count); + } +}; } // namespace duckdb -// LICENSE_CHANGE_END - - namespace duckdb { -enum class HLLStorageType { UNCOMPRESSED = 1 }; - -class FieldWriter; -class FieldReader; - -//! The HyperLogLog class holds a HyperLogLog counter for approximate cardinality counting -class HyperLogLog { -public: - HyperLogLog(); - ~HyperLogLog(); - // implicit copying of HyperLogLog is not allowed - HyperLogLog(const HyperLogLog &) = delete; - - //! Adds an element of the specified size to the HyperLogLog counter - void Add(data_ptr_t element, idx_t size); - //! Return the count of this HyperLogLog counter - idx_t Count() const; - //! Merge this HyperLogLog counter with another counter to create a new one - unique_ptr Merge(HyperLogLog &other); - HyperLogLog *MergePointer(HyperLogLog &other); - //! Merge a set of HyperLogLogs to create one big one - static unique_ptr Merge(HyperLogLog logs[], idx_t count); - //! Get the size (in bytes) of a HLL - static idx_t GetSize(); - //! Get pointer to the HLL - data_ptr_t GetPtr() const; - //! Get copy of the HLL - unique_ptr Copy(); - //! (De)Serialize the HLL - void Serialize(FieldWriter &writer) const; - static unique_ptr Deserialize(FieldReader &reader); - +struct UDFWrapper { public: - //! Compute HLL hashes over vdata, and store them in 'hashes' - //! Then, compute register indices and prefix lengths, and also store them in 'hashes' as a pair of uint32_t - static void ProcessEntries(UnifiedVectorFormat &vdata, const LogicalType &type, uint64_t hashes[], uint8_t counts[], - idx_t count); - //! Add the indices and counts to the logs - static void AddToLogs(UnifiedVectorFormat &vdata, idx_t count, uint64_t indices[], uint8_t counts[], - HyperLogLog **logs[], const SelectionVector *log_sel); - //! Add the indices and counts to THIS log - void AddToLog(UnifiedVectorFormat &vdata, idx_t count, uint64_t indices[], uint8_t counts[]); - -private: - explicit HyperLogLog(void *hll); + template + static scalar_function_t CreateScalarFunction(const string &name, TR (*udf_func)(Args...)) { + const std::size_t num_template_argc = sizeof...(Args); + switch (num_template_argc) { + case 1: + return CreateUnaryFunction(name, udf_func); + case 2: + return CreateBinaryFunction(name, udf_func); + case 3: + return CreateTernaryFunction(name, udf_func); + default: // LCOV_EXCL_START + throw std::runtime_error("UDF function only supported until ternary!"); + } // LCOV_EXCL_STOP + } - void *hll; - mutex lock; -}; -} // namespace duckdb + template + static scalar_function_t CreateScalarFunction(const string &name, vector args, LogicalType ret_type, + TR (*udf_func)(Args...)) { + if (!TypesMatch(ret_type)) { // LCOV_EXCL_START + throw std::runtime_error("Return type doesn't match with the first template type."); + } // LCOV_EXCL_STOP + const std::size_t num_template_types = sizeof...(Args); + if (num_template_types != args.size()) { // LCOV_EXCL_START + throw std::runtime_error( + "The number of templated types should be the same quantity of the LogicalType arguments."); + } // LCOV_EXCL_STOP + switch (num_template_types) { + case 1: + return CreateUnaryFunction(name, args, ret_type, udf_func); + case 2: + return CreateBinaryFunction(name, args, ret_type, udf_func); + case 3: + return CreateTernaryFunction(name, args, ret_type, udf_func); + default: // LCOV_EXCL_START + throw std::runtime_error("UDF function only supported until ternary!"); + } // LCOV_EXCL_STOP + } -namespace duckdb { -class Serializer; -class Deserializer; -class Vector; + template + static void RegisterFunction(const string &name, scalar_function_t udf_function, ClientContext &context, + LogicalType varargs = LogicalType(LogicalTypeId::INVALID)) { + vector arguments; + GetArgumentTypesRecursive(arguments); -class DistinctStatistics : public BaseStatistics { -public: - DistinctStatistics(); - explicit DistinctStatistics(unique_ptr log, idx_t sample_count, idx_t total_count); + LogicalType ret_type = GetArgumentType(); - //! The HLL of the table - unique_ptr log; - //! How many values have been sampled into the HLL - atomic sample_count; - //! How many values have been inserted (before sampling) - atomic total_count; + RegisterFunction(name, arguments, ret_type, udf_function, context, varargs); + } -public: - void Merge(const BaseStatistics &other) override; + DUCKDB_API static void RegisterFunction(string name, vector args, LogicalType ret_type, + scalar_function_t udf_function, ClientContext &context, + LogicalType varargs = LogicalType(LogicalTypeId::INVALID)); - unique_ptr Copy() const override; + //--------------------------------- Aggregate UDFs ------------------------------------// + template + static AggregateFunction CreateAggregateFunction(const string &name) { + return CreateUnaryAggregateFunction(name); + } - void Serialize(Serializer &serializer) const override; - void Serialize(FieldWriter &writer) const override; + template + static AggregateFunction CreateAggregateFunction(const string &name) { + return CreateBinaryAggregateFunction(name); + } - static unique_ptr Deserialize(Deserializer &source); - static unique_ptr Deserialize(FieldReader &reader); + template + static AggregateFunction CreateAggregateFunction(const string &name, LogicalType ret_type, LogicalType input_type) { + if (!TypesMatch(ret_type)) { // LCOV_EXCL_START + throw std::runtime_error("The return argument don't match!"); + } // LCOV_EXCL_STOP - void Update(Vector &update, idx_t count, bool sample = true); - void Update(UnifiedVectorFormat &update_data, const LogicalType &ptype, idx_t count, bool sample = true); + if (!TypesMatch(input_type)) { // LCOV_EXCL_START + throw std::runtime_error("The input argument don't match!"); + } // LCOV_EXCL_STOP - string ToString() const override; - idx_t GetCount() const; + return CreateUnaryAggregateFunction(name, ret_type, input_type); + } -private: - //! For distinct statistics we sample the input to speed up insertions - static constexpr const double SAMPLE_RATE = 0.1; -}; + template + static AggregateFunction CreateAggregateFunction(const string &name, LogicalType ret_type, LogicalType input_typeA, + LogicalType input_typeB) { + if (!TypesMatch(ret_type)) { // LCOV_EXCL_START + throw std::runtime_error("The return argument don't match!"); + } -} // namespace duckdb + if (!TypesMatch(input_typeA)) { + throw std::runtime_error("The first input argument don't match!"); + } -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/table_filter.hpp -// -// -//===----------------------------------------------------------------------===// + if (!TypesMatch(input_typeB)) { + throw std::runtime_error("The second input argument don't match!"); + } // LCOV_EXCL_STOP + return CreateBinaryAggregateFunction(name, ret_type, input_typeA, input_typeB); + } + //! A generic CreateAggregateFunction ---------------------------------------------------------------------------// + static AggregateFunction CreateAggregateFunction(string name, vector arguments, + LogicalType return_type, aggregate_size_t state_size, + aggregate_initialize_t initialize, aggregate_update_t update, + aggregate_combine_t combine, aggregate_finalize_t finalize, + aggregate_simple_update_t simple_update = nullptr, + bind_aggregate_function_t bind = nullptr, + aggregate_destructor_t destructor = nullptr) { + AggregateFunction aggr_function(std::move(name), std::move(arguments), std::move(return_type), state_size, + initialize, update, combine, finalize, simple_update, bind, destructor); + aggr_function.null_handling = FunctionNullHandling::SPECIAL_HANDLING; + return aggr_function; + } + DUCKDB_API static void RegisterAggrFunction(AggregateFunction aggr_function, ClientContext &context, + LogicalType varargs = LogicalType(LogicalTypeId::INVALID)); +private: + //-------------------------------- Templated functions --------------------------------// + struct UnaryUDFExecutor { + template + static RESULT_TYPE Operation(INPUT_TYPE input, ValidityMask &mask, idx_t idx, void *dataptr) { + typedef RESULT_TYPE (*unary_function_t)(INPUT_TYPE); + auto udf = (unary_function_t)dataptr; + return udf(input); + } + }; -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/enums/filter_propagate_result.hpp -// -// -//===----------------------------------------------------------------------===// + template + static scalar_function_t CreateUnaryFunction(const string &name, TR (*udf_func)(TA)) { + scalar_function_t udf_function = [=](DataChunk &input, ExpressionState &state, Vector &result) -> void { + UnaryExecutor::GenericExecute(input.data[0], result, input.size(), + (void *)udf_func); + }; + return udf_function; + } + template + static scalar_function_t CreateBinaryFunction(const string &name, TR (*udf_func)(TA, TB)) { + scalar_function_t udf_function = [=](DataChunk &input, ExpressionState &state, Vector &result) -> void { + BinaryExecutor::Execute(input.data[0], input.data[1], result, input.size(), udf_func); + }; + return udf_function; + } + template + static scalar_function_t CreateTernaryFunction(const string &name, TR (*udf_func)(TA, TB, TC)) { + scalar_function_t udf_function = [=](DataChunk &input, ExpressionState &state, Vector &result) -> void { + TernaryExecutor::Execute(input.data[0], input.data[1], input.data[2], result, input.size(), + udf_func); + }; + return udf_function; + } + template + static scalar_function_t CreateUnaryFunction(const string &name, TR (*udf_func)(Args...)) { // LCOV_EXCL_START + throw std::runtime_error("Incorrect number of arguments for unary function"); + } // LCOV_EXCL_STOP + template + static scalar_function_t CreateBinaryFunction(const string &name, TR (*udf_func)(Args...)) { // LCOV_EXCL_START + throw std::runtime_error("Incorrect number of arguments for binary function"); + } // LCOV_EXCL_STOP -namespace duckdb { + template + static scalar_function_t CreateTernaryFunction(const string &name, TR (*udf_func)(Args...)) { // LCOV_EXCL_START + throw std::runtime_error("Incorrect number of arguments for ternary function"); + } // LCOV_EXCL_STOP -enum class FilterPropagateResult : uint8_t { - NO_PRUNING_POSSIBLE = 0, - FILTER_ALWAYS_TRUE = 1, - FILTER_ALWAYS_FALSE = 2, - FILTER_TRUE_OR_NULL = 3, - FILTER_FALSE_OR_NULL = 4 -}; - -} // namespace duckdb - - -namespace duckdb { -class BaseStatistics; -class FieldWriter; -class FieldReader; - -enum class TableFilterType : uint8_t { - CONSTANT_COMPARISON = 0, // constant comparison (e.g. =C, >C, >=C, + static LogicalType GetArgumentType() { + if (std::is_same()) { + return LogicalType(LogicalTypeId::BOOLEAN); + } else if (std::is_same()) { + return LogicalType(LogicalTypeId::TINYINT); + } else if (std::is_same()) { + return LogicalType(LogicalTypeId::SMALLINT); + } else if (std::is_same()) { + return LogicalType(LogicalTypeId::INTEGER); + } else if (std::is_same()) { + return LogicalType(LogicalTypeId::BIGINT); + } else if (std::is_same()) { + return LogicalType(LogicalTypeId::FLOAT); + } else if (std::is_same()) { + return LogicalType(LogicalTypeId::DOUBLE); + } else if (std::is_same()) { + return LogicalType(LogicalTypeId::VARCHAR); + } else { // LCOV_EXCL_START + throw std::runtime_error("Unrecognized type!"); + } // LCOV_EXCL_STOP + } -//! TableFilter represents a filter pushed down into the table scan. -class TableFilter { -public: - TableFilter(TableFilterType filter_type_p) : filter_type(filter_type_p) { + template + static void GetArgumentTypesRecursive(vector &arguments) { + arguments.push_back(GetArgumentType()); + GetArgumentTypesRecursive(arguments); } - virtual ~TableFilter() { + + template + static void GetArgumentTypesRecursive(vector &arguments) { + arguments.push_back(GetArgumentType()); } - TableFilterType filter_type; +private: + //-------------------------------- Argumented functions --------------------------------// -public: - //! Returns true if the statistics indicate that the segment can contain values that satisfy that filter - virtual FilterPropagateResult CheckStatistics(BaseStatistics &stats) = 0; - virtual string ToString(const string &column_name) = 0; - virtual bool Equals(const TableFilter &other) const { - return filter_type != other.filter_type; - } + template + static scalar_function_t CreateUnaryFunction(const string &name, vector args, LogicalType ret_type, + TR (*udf_func)(Args...)) { // LCOV_EXCL_START + throw std::runtime_error("Incorrect number of arguments for unary function"); + } // LCOV_EXCL_STOP - void Serialize(Serializer &serializer) const; - virtual void Serialize(FieldWriter &writer) const = 0; - static unique_ptr Deserialize(Deserializer &source); -}; + template + static scalar_function_t CreateUnaryFunction(const string &name, vector args, LogicalType ret_type, + TR (*udf_func)(TA)) { + if (args.size() != 1) { // LCOV_EXCL_START + throw std::runtime_error("The number of LogicalType arguments (\"args\") should be 1!"); + } + if (!TypesMatch(args[0])) { + throw std::runtime_error("The first arguments don't match!"); + } // LCOV_EXCL_STOP -class TableFilterSet { -public: - unordered_map> filters; + scalar_function_t udf_function = [=](DataChunk &input, ExpressionState &state, Vector &result) -> void { + UnaryExecutor::GenericExecute(input.data[0], result, input.size(), + (void *)udf_func); + }; + return udf_function; + } -public: - void PushFilter(idx_t table_index, unique_ptr filter); + template + static scalar_function_t CreateBinaryFunction(const string &name, vector args, LogicalType ret_type, + TR (*udf_func)(Args...)) { // LCOV_EXCL_START + throw std::runtime_error("Incorrect number of arguments for binary function"); + } // LCOV_EXCL_STOP - bool Equals(TableFilterSet &other) { - if (filters.size() != other.filters.size()) { - return false; + template + static scalar_function_t CreateBinaryFunction(const string &name, vector args, LogicalType ret_type, + TR (*udf_func)(TA, TB)) { + if (args.size() != 2) { // LCOV_EXCL_START + throw std::runtime_error("The number of LogicalType arguments (\"args\") should be 2!"); } - for (auto &entry : filters) { - auto other_entry = other.filters.find(entry.first); - if (other_entry == other.filters.end()) { - return false; - } - if (!entry.second->Equals(*other_entry->second)) { - return false; - } + if (!TypesMatch(args[0])) { + throw std::runtime_error("The first arguments don't match!"); } - return true; + if (!TypesMatch(args[1])) { + throw std::runtime_error("The second arguments don't match!"); + } // LCOV_EXCL_STOP + + scalar_function_t udf_function = [=](DataChunk &input, ExpressionState &state, Vector &result) { + BinaryExecutor::Execute(input.data[0], input.data[1], result, input.size(), udf_func); + }; + return udf_function; } - static bool Equals(TableFilterSet *left, TableFilterSet *right) { - if (left == right) { - return true; + + template + static scalar_function_t CreateTernaryFunction(const string &name, vector args, LogicalType ret_type, + TR (*udf_func)(Args...)) { // LCOV_EXCL_START + throw std::runtime_error("Incorrect number of arguments for ternary function"); + } // LCOV_EXCL_STOP + + template + static scalar_function_t CreateTernaryFunction(const string &name, vector args, LogicalType ret_type, + TR (*udf_func)(TA, TB, TC)) { + if (args.size() != 3) { // LCOV_EXCL_START + throw std::runtime_error("The number of LogicalType arguments (\"args\") should be 3!"); } - if (!left || !right) { - return false; + if (!TypesMatch(args[0])) { + throw std::runtime_error("The first arguments don't match!"); } - return left->Equals(*right); + if (!TypesMatch(args[1])) { + throw std::runtime_error("The second arguments don't match!"); + } + if (!TypesMatch(args[2])) { + throw std::runtime_error("The second arguments don't match!"); + } // LCOV_EXCL_STOP + + scalar_function_t udf_function = [=](DataChunk &input, ExpressionState &state, Vector &result) -> void { + TernaryExecutor::Execute(input.data[0], input.data[1], input.data[2], result, input.size(), + udf_func); + }; + return udf_function; } - void Serialize(Serializer &serializer) const; - static unique_ptr Deserialize(Deserializer &source); -}; + template + static bool TypesMatch(const LogicalType &sql_type) { + switch (sql_type.id()) { + case LogicalTypeId::BOOLEAN: + return std::is_same(); + case LogicalTypeId::TINYINT: + return std::is_same(); + case LogicalTypeId::SMALLINT: + return std::is_same(); + case LogicalTypeId::INTEGER: + return std::is_same(); + case LogicalTypeId::BIGINT: + return std::is_same(); + case LogicalTypeId::DATE: + return std::is_same(); + case LogicalTypeId::TIME: + case LogicalTypeId::TIME_TZ: + return std::is_same(); + case LogicalTypeId::TIMESTAMP: + case LogicalTypeId::TIMESTAMP_MS: + case LogicalTypeId::TIMESTAMP_NS: + case LogicalTypeId::TIMESTAMP_SEC: + case LogicalTypeId::TIMESTAMP_TZ: + return std::is_same(); + case LogicalTypeId::FLOAT: + return std::is_same(); + case LogicalTypeId::DOUBLE: + return std::is_same(); + case LogicalTypeId::VARCHAR: + case LogicalTypeId::CHAR: + case LogicalTypeId::BLOB: + return std::is_same(); + default: // LCOV_EXCL_START + throw std::runtime_error("Type is not supported!"); + } // LCOV_EXCL_STOP + } + +private: + //-------------------------------- Aggregate functions --------------------------------// + template + static AggregateFunction CreateUnaryAggregateFunction(const string &name) { + LogicalType return_type = GetArgumentType(); + LogicalType input_type = GetArgumentType(); + return CreateUnaryAggregateFunction(name, return_type, input_type); + } + + template + static AggregateFunction CreateUnaryAggregateFunction(const string &name, LogicalType ret_type, + LogicalType input_type) { + AggregateFunction aggr_function = + AggregateFunction::UnaryAggregate(input_type, ret_type); + aggr_function.name = name; + return aggr_function; + } + + template + static AggregateFunction CreateBinaryAggregateFunction(const string &name) { + LogicalType return_type = GetArgumentType(); + LogicalType input_typeA = GetArgumentType(); + LogicalType input_typeB = GetArgumentType(); + return CreateBinaryAggregateFunction(name, return_type, input_typeA, input_typeB); + } + + template + static AggregateFunction CreateBinaryAggregateFunction(const string &name, LogicalType ret_type, + LogicalType input_typeA, LogicalType input_typeB) { + AggregateFunction aggr_function = + AggregateFunction::BinaryAggregate(input_typeA, input_typeB, ret_type); + aggr_function.name = name; + return aggr_function; + } +}; // end UDFWrapper } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/catalog/catalog_entry/table_catalog_entry.hpp +// duckdb/main/materialized_query_result.hpp // // //===----------------------------------------------------------------------===// @@ -10072,2789 +10556,1523 @@ class TableFilterSet { //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/catalog/standard_entry.hpp +// duckdb/common/types/column_data_collection.hpp // // //===----------------------------------------------------------------------===// - - -namespace duckdb { -class SchemaCatalogEntry; - -//! A StandardEntry is a catalog entry that is a member of a schema -class StandardEntry : public CatalogEntry { -public: - StandardEntry(CatalogType type, SchemaCatalogEntry *schema, Catalog *catalog, string name) - : CatalogEntry(type, catalog, name), schema(schema) { - } - ~StandardEntry() override { - } - - //! The schema the entry belongs to - SchemaCatalogEntry *schema; -}; -} // namespace duckdb - - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/parser/column_list.hpp +// duckdb/common/pair.hpp // // //===----------------------------------------------------------------------===// +#include -//===----------------------------------------------------------------------===// -// DuckDB +namespace duckdb { +using std::make_pair; +using std::pair; +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB // -// duckdb/common/field_writer.hpp +// duckdb/common/types/column_data_collection_iterators.hpp // // //===----------------------------------------------------------------------===// - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/set.hpp +// duckdb/common/types/column_data_scan_states.hpp // // //===----------------------------------------------------------------------===// -#include -namespace duckdb { -using std::set; -} + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/serializer/buffered_serializer.hpp +// duckdb/common/mutex.hpp // // //===----------------------------------------------------------------------===// +#include + +namespace duckdb { +using std::lock_guard; +using std::mutex; +using std::unique_lock; +} // namespace duckdb namespace duckdb { -#define SERIALIZER_DEFAULT_SIZE 1024 +enum class ColumnDataAllocatorType : uint8_t { + //! Use a buffer manager to allocate large chunks of memory that vectors then use + BUFFER_MANAGER_ALLOCATOR, + //! Use an in-memory allocator, allocating data for every chunk + //! This causes the column data collection to allocate blocks that are not tied to a buffer manager + IN_MEMORY_ALLOCATOR +}; -struct BinaryData { - unique_ptr data; - idx_t size; +enum class ColumnDataScanProperties : uint8_t { + INVALID, + //! Allow zero copy scans - this introduces a dependency on the resulting vector on the scan state of the column + //! data collection, which means vectors might not be valid anymore after the next chunk is scanned. + ALLOW_ZERO_COPY, + //! Disallow zero-copy scans, always copying data into the target vector + //! As a result, data scanned will be valid even after the column data collection is destroyed + DISALLOW_ZERO_COPY }; -class BufferedSerializer : public Serializer { -public: - //! Serializes to a buffer allocated by the serializer, will expand when - //! writing past the initial threshold - DUCKDB_API explicit BufferedSerializer(idx_t maximum_size = SERIALIZER_DEFAULT_SIZE); - //! Serializes to a provided (owned) data pointer - BufferedSerializer(unique_ptr data, idx_t size); - BufferedSerializer(data_ptr_t data, idx_t size); +struct ChunkManagementState { + unordered_map handles; + ColumnDataScanProperties properties = ColumnDataScanProperties::INVALID; +}; - idx_t maximum_size; - data_ptr_t data; +struct ColumnDataAppendState { + ChunkManagementState current_chunk_state; + vector vector_data; +}; - BinaryData blob; +struct ColumnDataScanState { + ChunkManagementState current_chunk_state; + idx_t segment_index; + idx_t chunk_index; + idx_t current_row_index; + idx_t next_row_index; + ColumnDataScanProperties properties; + vector column_ids; +}; + +struct ColumnDataParallelScanState { + ColumnDataScanState scan_state; + mutex lock; +}; + +struct ColumnDataLocalScanState { + ChunkManagementState current_chunk_state; + idx_t current_segment_index = DConstants::INVALID_INDEX; + idx_t current_row_index; +}; +class ColumnDataRow { public: - void WriteData(const_data_ptr_t buffer, uint64_t write_size) override; + ColumnDataRow(DataChunk &chunk, idx_t row_index, idx_t base_index); - //! Retrieves the data after the writing has been completed - BinaryData GetData() { - return std::move(blob); - } + DataChunk &chunk; + idx_t row_index; + idx_t base_index; - void Reset() { - blob.size = 0; - } +public: + Value GetValue(idx_t column_index) const; + idx_t RowIndex() const; }; } // namespace duckdb -#include namespace duckdb { -class BufferedSerializer; - -struct IndexWriteOperation { - template - static DST Operation(SRC input) { - return input.index; - } -}; - -class FieldWriter { -public: - DUCKDB_API FieldWriter(Serializer &serializer); - DUCKDB_API ~FieldWriter(); +class ColumnDataCollection; +class ColumnDataChunkIterationHelper { public: - template - void WriteField(const T &element) { - static_assert(std::is_trivially_destructible(), "WriteField object must be trivially destructible"); + DUCKDB_API ColumnDataChunkIterationHelper(const ColumnDataCollection &collection, vector column_ids); - AddField(); - WriteData((const_data_ptr_t)&element, sizeof(T)); - } +private: + const ColumnDataCollection &collection; + vector column_ids; - //! Write a string with a length prefix - void WriteString(const string &val) { - WriteStringLen((const_data_ptr_t)val.c_str(), val.size()); - } - void WriteStringLen(const_data_ptr_t val, idx_t len) { - AddField(); - Write((uint32_t)len); - if (len > 0) { - WriteData(val, len); - } - } - void WriteBlob(const_data_ptr_t val, idx_t len) { - AddField(); - if (len > 0) { - WriteData(val, len); - } - } +private: + class ColumnDataChunkIterator; - template > - void WriteList(const CONTAINER_TYPE &elements) { - AddField(); - Write(elements.size()); - for (auto &element : elements) { - Write(element); - } - } + class ColumnDataChunkIterator { + public: + DUCKDB_API explicit ColumnDataChunkIterator(const ColumnDataCollection *collection_p, + vector column_ids); - template > - void WriteGenericList(const CONTAINER_TYPE &elements) { - AddField(); - Write(elements.size()); - for (auto &element : elements) { - Write(OP::template Operation(element)); - } - } + const ColumnDataCollection *collection; + ColumnDataScanState scan_state; + shared_ptr scan_chunk; + idx_t row_index; - template - void WriteIndexList(const vector &elements) { - WriteGenericList(elements); - } + public: + DUCKDB_API void Next(); - // vector yay - template > - void WriteListNoReference(const CONTAINER_TYPE &elements) { - AddField(); - Write(elements.size()); - for (auto element : elements) { - Write(element); - } - } + DUCKDB_API ColumnDataChunkIterator &operator++(); + DUCKDB_API bool operator!=(const ColumnDataChunkIterator &other) const; + DUCKDB_API DataChunk &operator*() const; + }; - template - void WriteSerializable(const T &element) { - AddField(); - element.Serialize(*buffer); +public: + DUCKDB_API ColumnDataChunkIterator begin() { + return ColumnDataChunkIterator(&collection, column_ids); } - - template - void WriteSerializableList(const vector> &elements) { - AddField(); - Write(elements.size()); - for (idx_t i = 0; i < elements.size(); i++) { - elements[i]->Serialize(*buffer); - } + DUCKDB_API ColumnDataChunkIterator end() { + return ColumnDataChunkIterator(nullptr, vector()); } +}; - template - void WriteRegularSerializableList(const vector &elements) { - AddField(); - Write(elements.size()); - for (idx_t i = 0; i < elements.size(); i++) { - elements[i].Serialize(*buffer); - } - } +class ColumnDataRowIterationHelper { +public: + DUCKDB_API ColumnDataRowIterationHelper(const ColumnDataCollection &collection); - template - void WriteOptional(const unique_ptr &element) { - AddField(); - Write(element ? true : false); - if (element) { - element->Serialize(*buffer); - } - } +private: + const ColumnDataCollection &collection; - // Called after all fields have been written. Should always be called. - DUCKDB_API void Finalize(); +private: + class ColumnDataRowIterator; - Serializer &GetSerializer() { - return *buffer; - } + class ColumnDataRowIterator { + public: + DUCKDB_API explicit ColumnDataRowIterator(const ColumnDataCollection *collection_p); -private: - void AddField() { - field_count++; - } + const ColumnDataCollection *collection; + ColumnDataScanState scan_state; + shared_ptr scan_chunk; + ColumnDataRow current_row; - template - void Write(const T &element) { - WriteData((const_data_ptr_t)&element, sizeof(T)); - } + public: + void Next(); - DUCKDB_API void WriteData(const_data_ptr_t buffer, idx_t write_size); - -private: - Serializer &serializer; - unique_ptr buffer; - idx_t field_count; - bool finalized; -}; - -template <> -DUCKDB_API void FieldWriter::Write(const string &val); - -class FieldDeserializer : public Deserializer { -public: - FieldDeserializer(Deserializer &root); + DUCKDB_API ColumnDataRowIterator &operator++(); + DUCKDB_API bool operator!=(const ColumnDataRowIterator &other) const; + DUCKDB_API const ColumnDataRow &operator*() const; + }; public: - void ReadData(data_ptr_t buffer, idx_t read_size) override; + DUCKDB_API ColumnDataRowIterator begin(); + DUCKDB_API ColumnDataRowIterator end(); +}; - void SetRemainingData(idx_t remaining_data); - idx_t RemainingData(); - Deserializer &GetRoot() { - return root; - } +} // namespace duckdb -private: - Deserializer &root; - idx_t remaining_data; -}; -struct IndexReadOperation { - template - static DST Operation(SRC input) { - return DST(input); - } -}; +namespace duckdb { +class BufferManager; +class BlockHandle; +class ClientContext; +struct ColumnDataCopyFunction; +class ColumnDataAllocator; +class ColumnDataCollection; +class ColumnDataCollectionSegment; +class ColumnDataRowCollection; -class FieldReader { +//! The ColumnDataCollection represents a set of (buffer-managed) data stored in columnar format +//! It is efficient to read and scan +class ColumnDataCollection { public: - DUCKDB_API FieldReader(Deserializer &source); - DUCKDB_API ~FieldReader(); + //! Constructs an in-memory column data collection from an allocator + DUCKDB_API ColumnDataCollection(Allocator &allocator, vector types); + //! Constructs an empty (but valid) in-memory column data collection from an allocator + DUCKDB_API ColumnDataCollection(Allocator &allocator); + //! Constructs a buffer-managed column data collection + DUCKDB_API ColumnDataCollection(BufferManager &buffer_manager, vector types); + //! Constructs either an in-memory or a buffer-managed column data collection + DUCKDB_API ColumnDataCollection(ClientContext &context, vector types, + ColumnDataAllocatorType type = ColumnDataAllocatorType::BUFFER_MANAGER_ALLOCATOR); + //! Creates a column data collection that inherits the blocks to write to. This allows blocks to be shared + //! between multiple column data collections and prevents wasting space. + //! Note that after one CDC inherits blocks from another, the other + //! cannot be written to anymore (i.e. we take ownership of the half-written blocks). + DUCKDB_API ColumnDataCollection(ColumnDataCollection &parent); + DUCKDB_API ColumnDataCollection(shared_ptr allocator, vector types); + DUCKDB_API ~ColumnDataCollection(); public: - template - T ReadRequired() { - if (field_count >= max_field_count) { - // field is not there, throw an exception - throw SerializationException("Attempting to read a required field, but field is missing"); - } - // field is there, read the actual value - AddField(); - return source.Read(); - } - - template - T ReadField(T default_value) { - if (field_count >= max_field_count) { - // field is not there, read the default value - return default_value; - } - // field is there, read the actual value - AddField(); - return source.Read(); - } - - template > - CONTAINER_TYPE ReadRequiredList() { - if (field_count >= max_field_count) { - // field is not there, throw an exception - throw SerializationException("Attempting to read a required field, but field is missing"); - } - AddField(); - auto result_count = source.Read(); - CONTAINER_TYPE result; - result.reserve(result_count); - for (idx_t i = 0; i < result_count; i++) { - result.push_back(source.Read()); - } - return result; + //! The types of columns in the ColumnDataCollection + DUCKDB_API vector &Types() { + return types; } - - template - vector ReadRequiredGenericList() { - if (field_count >= max_field_count) { - // field is not there, throw an exception - throw SerializationException("Attempting to read a required field, but field is missing"); - } - AddField(); - auto result_count = source.Read(); - vector result; - result.reserve(result_count); - for (idx_t i = 0; i < result_count; i++) { - result.push_back(OP::template Operation(source.Read())); - } - return result; + DUCKDB_API const vector &Types() const { + return types; } - template - vector ReadRequiredIndexList() { - return ReadRequiredGenericList(); + //! The amount of rows in the ColumnDataCollection + DUCKDB_API const idx_t &Count() const { + return count; } - template - set ReadRequiredSet() { - if (field_count >= max_field_count) { - // field is not there, throw an exception - throw SerializationException("Attempting to read a required field, but field is missing"); - } - AddField(); - auto result_count = source.Read(); - set result; - for (idx_t i = 0; i < result_count; i++) { - result.insert(source.Read()); - } - return result; + //! The amount of columns in the ColumnDataCollection + DUCKDB_API idx_t ColumnCount() const { + return types.size(); } - template - unique_ptr ReadOptional(unique_ptr default_value, ARGS &&...args) { - if (field_count >= max_field_count) { - // field is not there, read the default value - return default_value; - } - // field is there, read the actual value - AddField(); - return source.template ReadOptional(std::forward(args)...); - } + //! Get the allocator + DUCKDB_API Allocator &GetAllocator() const; - template > - RETURN_TYPE ReadSerializable(RETURN_TYPE default_value) { - if (field_count >= max_field_count) { - // field is not there, read the default value - return default_value; - } - // field is there, read the actual value - AddField(); - return T::Deserialize(source); - } + //! Initializes an Append state - useful for optimizing many appends made to the same column data collection + DUCKDB_API void InitializeAppend(ColumnDataAppendState &state); + //! Append a DataChunk to this ColumnDataCollection using the specified append state + DUCKDB_API void Append(ColumnDataAppendState &state, DataChunk &new_chunk); - template , typename... ARGS> - RETURN_TYPE ReadSerializable(RETURN_TYPE default_value, ARGS &&...args) { - if (field_count >= max_field_count) { - // field is not there, read the default value - return default_value; - } - // field is there, read the actual value - AddField(); - return T::Deserialize(source, std::forward(args)...); - } + //! Initializes a chunk with the correct types that can be used to call Scan + DUCKDB_API void InitializeScanChunk(DataChunk &chunk) const; + //! Initializes a chunk with the correct types for a given scan state + DUCKDB_API void InitializeScanChunk(ColumnDataScanState &state, DataChunk &chunk) const; + //! Initializes a Scan state for scanning all columns + DUCKDB_API void + InitializeScan(ColumnDataScanState &state, + ColumnDataScanProperties properties = ColumnDataScanProperties::ALLOW_ZERO_COPY) const; + //! Initializes a Scan state for scanning a subset of the columns + DUCKDB_API void + InitializeScan(ColumnDataScanState &state, vector column_ids, + ColumnDataScanProperties properties = ColumnDataScanProperties::ALLOW_ZERO_COPY) const; + //! Initialize a parallel scan over the column data collection over all columns + DUCKDB_API void + InitializeScan(ColumnDataParallelScanState &state, + ColumnDataScanProperties properties = ColumnDataScanProperties::ALLOW_ZERO_COPY) const; + //! Initialize a parallel scan over the column data collection over a subset of the columns + DUCKDB_API void + InitializeScan(ColumnDataParallelScanState &state, vector column_ids, + ColumnDataScanProperties properties = ColumnDataScanProperties::ALLOW_ZERO_COPY) const; + //! Scans a DataChunk from the ColumnDataCollection + DUCKDB_API bool Scan(ColumnDataScanState &state, DataChunk &result) const; + //! Scans a DataChunk from the ColumnDataCollection + DUCKDB_API bool Scan(ColumnDataParallelScanState &state, ColumnDataLocalScanState &lstate, DataChunk &result) const; - template > - RETURN_TYPE ReadRequiredSerializable() { - if (field_count >= max_field_count) { - // field is not there, throw an exception - throw SerializationException("Attempting to read mandatory field, but field is missing"); - } - // field is there, read the actual value - AddField(); - return T::Deserialize(source); - } + //! Append a DataChunk directly to this ColumnDataCollection - calls InitializeAppend and Append internally + DUCKDB_API void Append(DataChunk &new_chunk); - template , typename... ARGS> - RETURN_TYPE ReadRequiredSerializable(ARGS &&...args) { - if (field_count >= max_field_count) { - // field is not there, throw an exception - throw SerializationException("Attempting to read mandatory field, but field is missing"); - } - // field is there, read the actual value - AddField(); - return T::Deserialize(source, std::forward(args)...); - } + //! Appends the other ColumnDataCollection to this, destroying the other data collection + DUCKDB_API void Combine(ColumnDataCollection &other); - template , typename... ARGS> - vector ReadRequiredSerializableList(ARGS &&...args) { - if (field_count >= max_field_count) { - // field is not there, throw an exception - throw SerializationException("Attempting to read mandatory field, but field is missing"); - } - // field is there, read the actual value - AddField(); - auto result_count = source.Read(); + DUCKDB_API void Verify(); - vector result; - for (idx_t i = 0; i < result_count; i++) { - result.push_back(T::Deserialize(source, std::forward(args)...)); - } - return result; - } + DUCKDB_API string ToString() const; + DUCKDB_API void Print() const; - void ReadBlob(data_ptr_t result, idx_t read_size) { - if (field_count >= max_field_count) { - // field is not there, throw an exception - throw SerializationException("Attempting to read a required field, but field is missing"); - } - // field is there, read the actual value - AddField(); - source.ReadData(result, read_size); - } + DUCKDB_API void Reset(); - //! Called after all fields have been read. Should always be called. - DUCKDB_API void Finalize(); + //! Returns the number of data chunks present in the ColumnDataCollection + DUCKDB_API idx_t ChunkCount() const; + //! Fetch an individual chunk from the ColumnDataCollection + DUCKDB_API void FetchChunk(idx_t chunk_idx, DataChunk &result) const; - Deserializer &GetSource() { - return source; - } - -private: - void AddField() { - field_count++; - } - -private: - FieldDeserializer source; - idx_t field_count; - idx_t max_field_count; - idx_t total_size; - bool finalized; -}; - -} // namespace duckdb - - -namespace duckdb { - -//! A set of column definitions -class ColumnList { -public: - class ColumnListIterator; - -public: - ColumnList(bool allow_duplicate_names = false); - - DUCKDB_API void AddColumn(ColumnDefinition column); - void Finalize(); - - DUCKDB_API const ColumnDefinition &GetColumn(LogicalIndex index) const; - DUCKDB_API const ColumnDefinition &GetColumn(PhysicalIndex index) const; - DUCKDB_API const ColumnDefinition &GetColumn(const string &name) const; - DUCKDB_API ColumnDefinition &GetColumnMutable(LogicalIndex index); - DUCKDB_API ColumnDefinition &GetColumnMutable(PhysicalIndex index); - DUCKDB_API ColumnDefinition &GetColumnMutable(const string &name); - - DUCKDB_API bool ColumnExists(const string &name) const; + //! Constructs a class that can be iterated over to fetch individual chunks + //! Iterating over this is syntactic sugar over just calling Scan + DUCKDB_API ColumnDataChunkIterationHelper Chunks() const; + //! Constructs a class that can be iterated over to fetch individual chunks + //! Only the column indexes specified in the column_ids list are scanned + DUCKDB_API ColumnDataChunkIterationHelper Chunks(vector column_ids) const; - DUCKDB_API LogicalIndex GetColumnIndex(string &column_name) const; - DUCKDB_API PhysicalIndex LogicalToPhysical(LogicalIndex index) const; - DUCKDB_API LogicalIndex PhysicalToLogical(PhysicalIndex index) const; + //! Constructs a class that can be iterated over to fetch individual rows + //! Note that row iteration is slow, and the `.Chunks()` method should be used instead + DUCKDB_API ColumnDataRowIterationHelper Rows() const; - idx_t LogicalColumnCount() const { - return columns.size(); - } - idx_t PhysicalColumnCount() const { - return physical_columns.size(); - } - bool empty() const { - return columns.empty(); - } + //! Returns a materialized set of all of the rows in the column data collection + //! Note that usage of this is slow - avoid using this unless the amount of rows is small, or if you do not care + //! about performance + DUCKDB_API ColumnDataRowCollection GetRows() const; - ColumnList Copy() const; - void Serialize(FieldWriter &writer) const; - static ColumnList Deserialize(FieldReader &reader); + //! Compare two column data collections to another. If they are equal according to result equality rules, + //! return true. That means null values are equal, and approx equality is used for floating point values. + //! If they are not equal, return false and fill in the error message. + static bool ResultEquals(const ColumnDataCollection &left, const ColumnDataCollection &right, + string &error_message); - DUCKDB_API ColumnListIterator Logical() const; - DUCKDB_API ColumnListIterator Physical() const; + //! Obtains the next scan index to scan from + bool NextScanIndex(ColumnDataScanState &state, idx_t &chunk_index, idx_t &segment_index, idx_t &row_index) const; + //! Scans at the indices (obtained from NextScanIndex) + void ScanAtIndex(ColumnDataParallelScanState &state, ColumnDataLocalScanState &lstate, DataChunk &result, + idx_t chunk_index, idx_t segment_index, idx_t row_index) const; - void SetAllowDuplicates(bool allow_duplicates) { - allow_duplicate_names = allow_duplicates; - } + //! Initialize the column data collection + void Initialize(vector types); -private: - vector columns; - //! A map of column name to column index - case_insensitive_map_t name_map; - //! The set of physical columns - vector physical_columns; - //! Allow duplicate names or not - bool allow_duplicate_names; + //! Get a vector of references to every chunk (segment, index in segment), and optionally sort by block id + const vector> &GetSegments() const; private: - void AddToNameMap(ColumnDefinition &column); - -public: - // logical iterator - class ColumnListIterator { - public: - DUCKDB_API ColumnListIterator(const ColumnList &list, bool physical) : list(list), physical(physical) { - } - - private: - const ColumnList &list; - bool physical; - - private: - class ColumnLogicalIteratorInternal { - public: - DUCKDB_API ColumnLogicalIteratorInternal(const ColumnList &list, bool physical, idx_t pos, idx_t end) - : list(list), physical(physical), pos(pos), end(end) { - } - - const ColumnList &list; - bool physical; - idx_t pos; - idx_t end; - - public: - DUCKDB_API ColumnLogicalIteratorInternal &operator++() { - pos++; - return *this; - } - DUCKDB_API bool operator!=(const ColumnLogicalIteratorInternal &other) const { - return pos != other.pos || end != other.end || &list != &other.list; - } - DUCKDB_API const ColumnDefinition &operator*() const { - if (physical) { - return list.GetColumn(PhysicalIndex(pos)); - } else { - return list.GetColumn(LogicalIndex(pos)); - } - } - }; - - public: - idx_t Size() { - return physical ? list.PhysicalColumnCount() : list.LogicalColumnCount(); - } - - DUCKDB_API ColumnLogicalIteratorInternal begin() { - return ColumnLogicalIteratorInternal(list, physical, 0, Size()); - } - DUCKDB_API ColumnLogicalIteratorInternal end() { - return ColumnLogicalIteratorInternal(list, physical, Size(), Size()); - } - }; -}; - -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/constraint.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -namespace duckdb { - -class Serializer; -class Deserializer; -class FieldWriter; -class FieldReader; - -//===--------------------------------------------------------------------===// -// Constraint Types -//===--------------------------------------------------------------------===// -enum class ConstraintType : uint8_t { - INVALID = 0, // invalid constraint type - NOT_NULL = 1, // NOT NULL constraint - CHECK = 2, // CHECK constraint - UNIQUE = 3, // UNIQUE constraint - FOREIGN_KEY = 4, // FOREIGN KEY constraint -}; + //! Creates a new segment within the ColumnDataCollection + void CreateSegment(); -enum class ForeignKeyType : uint8_t { - FK_TYPE_PRIMARY_KEY_TABLE = 0, // main table - FK_TYPE_FOREIGN_KEY_TABLE = 1, // referencing table - FK_TYPE_SELF_REFERENCE_TABLE = 2 // self refrencing table -}; + static ColumnDataCopyFunction GetCopyFunction(const LogicalType &type); -struct ForeignKeyInfo { - ForeignKeyType type; - string schema; - //! if type is FK_TYPE_FOREIGN_KEY_TABLE, means main key table, if type is FK_TYPE_PRIMARY_KEY_TABLE, means foreign - //! key table - string table; - //! The set of main key table's column's index - vector pk_keys; - //! The set of foreign key table's column's index - vector fk_keys; +private: + //! The Column Data Allocator + buffer_ptr allocator; + //! The types of the stored entries + vector types; + //! The number of entries stored in the column data collection + idx_t count; + //! The data segments of the column data collection + vector> segments; + //! The set of copy functions + vector copy_functions; + //! When the column data collection is marked as finished - new tuples can no longer be appended to it + bool finished_append; }; -//! Constraint is the base class of any type of table constraint. -class Constraint { +//! The ColumnDataRowCollection represents a set of materialized rows, as obtained from the ColumnDataCollection +class ColumnDataRowCollection { public: - DUCKDB_API explicit Constraint(ConstraintType type); - DUCKDB_API virtual ~Constraint(); - - ConstraintType type; + DUCKDB_API ColumnDataRowCollection(const ColumnDataCollection &collection); public: - DUCKDB_API virtual string ToString() const = 0; - DUCKDB_API void Print() const; - - DUCKDB_API virtual unique_ptr Copy() const = 0; - //! Serializes a Constraint to a stand-alone binary blob - DUCKDB_API void Serialize(Serializer &serializer) const; - //! Serializes a Constraint to a stand-alone binary blob - DUCKDB_API virtual void Serialize(FieldWriter &writer) const = 0; - //! Deserializes a blob back into a Constraint - DUCKDB_API static unique_ptr Deserialize(Deserializer &source); -}; -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/bound_constraint.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - + DUCKDB_API Value GetValue(idx_t column, idx_t index) const; -namespace duckdb { -//! Bound equivalent of Constraint -class BoundConstraint { public: - explicit BoundConstraint(ConstraintType type) : type(type) {}; - virtual ~BoundConstraint() { - } - - void Serialize(Serializer &serializer) const { - serializer.Write(type); - } - - static unique_ptr Deserialize(Deserializer &source) { - return make_unique(source.Read()); + // container API + DUCKDB_API bool empty() const { + return rows.empty(); } - - ConstraintType type; -}; -} // namespace duckdb - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/expression.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/plan_serialization.hpp -// -// -//===----------------------------------------------------------------------===// - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/enums/logical_operator_type.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { - -//===--------------------------------------------------------------------===// -// Logical Operator Types -//===--------------------------------------------------------------------===// -enum class LogicalOperatorType : uint8_t { - LOGICAL_INVALID = 0, - LOGICAL_PROJECTION = 1, - LOGICAL_FILTER = 2, - LOGICAL_AGGREGATE_AND_GROUP_BY = 3, - LOGICAL_WINDOW = 4, - LOGICAL_UNNEST = 5, - LOGICAL_LIMIT = 6, - LOGICAL_ORDER_BY = 7, - LOGICAL_TOP_N = 8, - LOGICAL_COPY_TO_FILE = 10, - LOGICAL_DISTINCT = 11, - LOGICAL_SAMPLE = 12, - LOGICAL_LIMIT_PERCENT = 13, - - // ----------------------------- - // Data sources - // ----------------------------- - LOGICAL_GET = 25, - LOGICAL_CHUNK_GET = 26, - LOGICAL_DELIM_GET = 27, - LOGICAL_EXPRESSION_GET = 28, - LOGICAL_DUMMY_SCAN = 29, - LOGICAL_EMPTY_RESULT = 30, - LOGICAL_CTE_REF = 31, - // ----------------------------- - // Joins - // ----------------------------- - LOGICAL_JOIN = 50, - LOGICAL_DELIM_JOIN = 51, - LOGICAL_COMPARISON_JOIN = 52, - LOGICAL_ANY_JOIN = 53, - LOGICAL_CROSS_PRODUCT = 54, - // ----------------------------- - // SetOps - // ----------------------------- - LOGICAL_UNION = 75, - LOGICAL_EXCEPT = 76, - LOGICAL_INTERSECT = 77, - LOGICAL_RECURSIVE_CTE = 78, - - // ----------------------------- - // Updates - // ----------------------------- - LOGICAL_INSERT = 100, - LOGICAL_DELETE = 101, - LOGICAL_UPDATE = 102, - - // ----------------------------- - // Schema - // ----------------------------- - LOGICAL_ALTER = 125, - LOGICAL_CREATE_TABLE = 126, - LOGICAL_CREATE_INDEX = 127, - LOGICAL_CREATE_SEQUENCE = 128, - LOGICAL_CREATE_VIEW = 129, - LOGICAL_CREATE_SCHEMA = 130, - LOGICAL_CREATE_MACRO = 131, - LOGICAL_DROP = 132, - LOGICAL_PRAGMA = 133, - LOGICAL_TRANSACTION = 134, - LOGICAL_CREATE_TYPE = 135, - - // ----------------------------- - // Explain - // ----------------------------- - LOGICAL_EXPLAIN = 150, - - // ----------------------------- - // Show - // ----------------------------- - LOGICAL_SHOW = 160, - - // ----------------------------- - // Helpers - // ----------------------------- - LOGICAL_PREPARE = 175, - LOGICAL_EXECUTE = 176, - LOGICAL_EXPORT = 177, - LOGICAL_VACUUM = 178, - LOGICAL_SET = 179, - LOGICAL_LOAD = 180, - - LOGICAL_EXTENSION_OPERATOR = 255 -}; - -DUCKDB_API string LogicalOperatorToString(LogicalOperatorType type); - -} // namespace duckdb - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/bound_parameter_map.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - -namespace duckdb { - -struct BoundParameterData; - -using bound_parameter_map_t = unordered_map>; - -} // namespace duckdb - - -namespace duckdb { -class ClientContext; -class LogicalOperator; -struct BoundParameterData; - -struct PlanDeserializationState { - PlanDeserializationState(ClientContext &context); - ~PlanDeserializationState(); - - ClientContext &context; - bound_parameter_map_t parameter_data; -}; - -struct LogicalDeserializationState { - LogicalDeserializationState(PlanDeserializationState &gstate, LogicalOperatorType type, - vector> &children); - - PlanDeserializationState &gstate; - LogicalOperatorType type; - vector> &children; -}; - -struct ExpressionDeserializationState { - ExpressionDeserializationState(PlanDeserializationState &gstate, ExpressionType type); - - PlanDeserializationState &gstate; - ExpressionType type; -}; - -} // namespace duckdb - - -namespace duckdb { -class BaseStatistics; -class FieldWriter; -class FieldReader; -class ClientContext; - -//! The Expression class represents a bound Expression with a return type -class Expression : public BaseExpression { -public: - Expression(ExpressionType type, ExpressionClass expression_class, LogicalType return_type); - ~Expression() override; - - //! The return type of the expression - LogicalType return_type; - //! Expression statistics (if any) - ONLY USED FOR VERIFICATION - unique_ptr verification_stats; - -public: - bool IsAggregate() const override; - bool IsWindow() const override; - bool HasSubquery() const override; - bool IsScalar() const override; - bool HasParameter() const override; - virtual bool HasSideEffects() const; - virtual bool PropagatesNullValues() const; - virtual bool IsFoldable() const; - - hash_t Hash() const override; - - bool Equals(const BaseExpression *other) const override { - if (!BaseExpression::Equals(other)) { - return false; - } - return return_type == ((Expression *)other)->return_type; - } - - static bool Equals(Expression *left, Expression *right) { - return BaseExpression::Equals((BaseExpression *)left, (BaseExpression *)right); - } - //! Create a copy of this expression - virtual unique_ptr Copy() = 0; - - //! Serializes an Expression to a stand-alone binary blob - void Serialize(Serializer &serializer) const; - //! Serializes an Expression to a stand-alone binary blob - virtual void Serialize(FieldWriter &writer) const = 0; - - //! Deserializes a blob back into an Expression [CAN THROW: - //! SerializationException] - static unique_ptr Deserialize(Deserializer &source, PlanDeserializationState &state); - -protected: - //! Copy base Expression properties from another expression to this one, - //! used in Copy method - void CopyProperties(Expression &other) { - type = other.type; - expression_class = other.expression_class; - alias = other.alias; - return_type = other.return_type; - } -}; - -} // namespace duckdb - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/catalog/catalog_entry/column_dependency_manager.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/stack.hpp -// -// -//===----------------------------------------------------------------------===// - - - -#include - -namespace duckdb { -using std::stack; -} - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/index_map.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - -namespace duckdb { - -struct LogicalIndexHashFunction { - uint64_t operator()(const LogicalIndex &index) const { - return std::hash()(index.index); - } -}; - -struct PhysicalIndexHashFunction { - uint64_t operator()(const PhysicalIndex &index) const { - return std::hash()(index.index); - } -}; - -template -using logical_index_map_t = unordered_map; - -using logical_index_set_t = unordered_set; - -template -using physical_index_map_t = unordered_map; - -using physical_index_set_t = unordered_set; - -} // namespace duckdb - - -namespace duckdb { - -//! Dependency Manager local to a table, responsible for keeping track of generated column dependencies - -class ColumnDependencyManager { -public: - DUCKDB_API ColumnDependencyManager(); - DUCKDB_API ~ColumnDependencyManager(); - DUCKDB_API ColumnDependencyManager(ColumnDependencyManager &&other) = default; - ColumnDependencyManager(const ColumnDependencyManager &other) = delete; - -public: - //! Get the bind order that ensures dependencies are resolved before dependents are - stack GetBindOrder(const ColumnList &columns); - - //! Adds a connection between the dependent and its dependencies - void AddGeneratedColumn(LogicalIndex index, const vector &indices, bool root = true); - //! Add a generated column from a column definition - void AddGeneratedColumn(const ColumnDefinition &column, const ColumnList &list); - - //! Removes the column(s) and outputs the new column indices - vector RemoveColumn(LogicalIndex index, idx_t column_amount); - - bool IsDependencyOf(LogicalIndex dependent, LogicalIndex dependency) const; - bool HasDependencies(LogicalIndex index) const; - const logical_index_set_t &GetDependencies(LogicalIndex index) const; - - bool HasDependents(LogicalIndex index) const; - const logical_index_set_t &GetDependents(LogicalIndex index) const; - -private: - void RemoveStandardColumn(LogicalIndex index); - void RemoveGeneratedColumn(LogicalIndex index); - - void AdjustSingle(LogicalIndex idx, idx_t offset); - // Clean up the gaps created by a Remove operation - vector CleanupInternals(idx_t column_amount); - -private: - //! A map of column dependency to generated column(s) - logical_index_map_t dependencies_map; - //! A map of generated column name to (potentially generated)column dependencies - logical_index_map_t dependents_map; - //! For resolve-order purposes, keep track of the 'direct' (not inherited) dependencies of a generated column - logical_index_map_t direct_dependencies; - logical_index_set_t deleted_columns; -}; - -} // namespace duckdb - - -namespace duckdb { - -class DataTable; -struct CreateTableInfo; -struct BoundCreateTableInfo; - -struct RenameColumnInfo; -struct AddColumnInfo; -struct RemoveColumnInfo; -struct SetDefaultInfo; -struct ChangeColumnTypeInfo; -struct AlterForeignKeyInfo; -struct SetNotNullInfo; -struct DropNotNullInfo; - -//! A table catalog entry -class TableCatalogEntry : public StandardEntry { -public: - //! Create a real TableCatalogEntry and initialize storage for it - TableCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, BoundCreateTableInfo *info, - std::shared_ptr inherited_storage = nullptr); - - //! A reference to the underlying storage unit used for this table - std::shared_ptr storage; - //! A list of columns that are part of this table - ColumnList columns; - //! A list of constraints that are part of this table - vector> constraints; - //! A list of constraints that are part of this table - vector> bound_constraints; - ColumnDependencyManager column_dependency_manager; - -public: - bool HasGeneratedColumns() const; - unique_ptr AlterEntry(ClientContext &context, AlterInfo *info) override; - void UndoAlter(ClientContext &context, AlterInfo *info) override; - - //! Returns whether or not a column with the given name exists - DUCKDB_API bool ColumnExists(const string &name); - //! Returns a reference to the column of the specified name. Throws an - //! exception if the column does not exist. - ColumnDefinition &GetColumn(const string &name); - //! Returns a list of types of the table, excluding generated columns - vector GetTypes(); - string ToSQL() override; - - //! Get statistics of a column (physical or virtual) within the table - unique_ptr GetStatistics(ClientContext &context, column_t column_id); - - //! Serialize the meta information of the TableCatalogEntry a serializer - virtual void Serialize(Serializer &serializer); - //! Deserializes to a CreateTableInfo - static unique_ptr Deserialize(Deserializer &source, ClientContext &context); - - unique_ptr Copy(ClientContext &context) override; - - void SetAsRoot() override; - - void CommitAlter(AlterInfo &info); - void CommitDrop(); - - //! Returns the column index of the specified column name. - //! If the column does not exist: - //! If if_column_exists is true, returns DConstants::INVALID_INDEX - //! If if_column_exists is false, throws an exception - LogicalIndex GetColumnIndex(string &name, bool if_exists = false); - -private: - unique_ptr RenameColumn(ClientContext &context, RenameColumnInfo &info); - unique_ptr AddColumn(ClientContext &context, AddColumnInfo &info); - unique_ptr RemoveColumn(ClientContext &context, RemoveColumnInfo &info); - unique_ptr SetDefault(ClientContext &context, SetDefaultInfo &info); - unique_ptr ChangeColumnType(ClientContext &context, ChangeColumnTypeInfo &info); - unique_ptr SetNotNull(ClientContext &context, SetNotNullInfo &info); - unique_ptr DropNotNull(ClientContext &context, DropNotNullInfo &info); - unique_ptr AddForeignKeyConstraint(ClientContext &context, AlterForeignKeyInfo &info); - unique_ptr DropForeignKeyConstraint(ClientContext &context, AlterForeignKeyInfo &info); -}; -} // namespace duckdb - - -namespace duckdb { - -class EstimatedProperties { -public: - EstimatedProperties(double cardinality, double cost) : cardinality(cardinality), cost(cost) {}; - EstimatedProperties() : cardinality(0), cost(0) {}; - - template - T GetCardinality() const { - throw NotImplementedException("Unsupported type for GetCardinality"); - } - double GetCost() const; - void SetCost(double new_cost); - void SetCardinality(double cardinality); - -private: - double cardinality; - double cost; - -public: - unique_ptr Copy(); -}; - -template <> -double EstimatedProperties::GetCardinality() const; - -template <> -idx_t EstimatedProperties::GetCardinality() const; - -} // namespace duckdb - - - - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/column_binding.hpp -// -// -//===----------------------------------------------------------------------===// - - - - -#include - -namespace duckdb { - -struct ColumnBinding { - idx_t table_index; - idx_t column_index; - - ColumnBinding() : table_index(DConstants::INVALID_INDEX), column_index(DConstants::INVALID_INDEX) { - } - ColumnBinding(idx_t table, idx_t column) : table_index(table), column_index(column) { - } - - bool operator==(const ColumnBinding &rhs) const { - return table_index == rhs.table_index && column_index == rhs.column_index; - } -}; - -} // namespace duckdb - - - -#include -#include - -namespace duckdb { - -class FieldWriter; -class FieldReader; - -//! The current version of the plan serialization format. Exposed via by @Serializer & @Deserializer -//! to be used by various Operator to know what format to read and write. -extern const uint64_t PLAN_SERIALIZATION_VERSION; - -//! LogicalOperator is the base class of the logical operators present in the -//! logical query tree -class LogicalOperator { -public: - explicit LogicalOperator(LogicalOperatorType type); - LogicalOperator(LogicalOperatorType type, vector> expressions); - virtual ~LogicalOperator(); - - //! The type of the logical operator - LogicalOperatorType type; - //! The set of children of the operator - vector> children; - //! The set of expressions contained within the operator, if any - vector> expressions; - //! The types returned by this logical operator. Set by calling LogicalOperator::ResolveTypes. - vector types; - //! Estimated Cardinality - idx_t estimated_cardinality; - bool has_estimated_cardinality; - - unique_ptr estimated_props; - -public: - virtual vector GetColumnBindings(); - static vector GenerateColumnBindings(idx_t table_idx, idx_t column_count); - static vector MapTypes(const vector &types, const vector &projection_map); - static vector MapBindings(const vector &types, const vector &projection_map); - - //! Resolve the types of the logical operator and its children - void ResolveOperatorTypes(); - - virtual string GetName() const; - virtual string ParamsToString() const; - virtual string ToString() const; - DUCKDB_API void Print(); - //! Debug method: verify that the integrity of expressions & child nodes are maintained - virtual void Verify(ClientContext &context); - - void AddChild(unique_ptr child); - virtual idx_t EstimateCardinality(ClientContext &context); - - //! Serializes a LogicalOperator to a stand-alone binary blob - void Serialize(Serializer &serializer) const; - //! Serializes an LogicalOperator to a stand-alone binary blob - virtual void Serialize(FieldWriter &writer) const = 0; - - static unique_ptr Deserialize(Deserializer &deserializer, PlanDeserializationState &state); - - virtual unique_ptr Copy(ClientContext &context) const; - - virtual bool RequireOptimizer() const { - return true; - } - - //! Returns the set of table indexes of this operator - virtual vector GetTableIndex() const; - -protected: - //! Resolve types for this specific operator - virtual void ResolveTypes() = 0; -}; -} // namespace duckdb - - -namespace duckdb { - -struct BoundStatement { - unique_ptr plan; - vector types; - vector names; -}; - -} // namespace duckdb - - - - -namespace duckdb { - -//! A ResultModifier -class BoundResultModifier { -public: - explicit BoundResultModifier(ResultModifierType type); - virtual ~BoundResultModifier(); - - ResultModifierType type; -}; - -struct BoundOrderByNode { -public: - BoundOrderByNode(OrderType type, OrderByNullType null_order, unique_ptr expression); - BoundOrderByNode(OrderType type, OrderByNullType null_order, unique_ptr expression, - unique_ptr stats); - - OrderType type; - OrderByNullType null_order; - unique_ptr expression; - unique_ptr stats; - -public: - BoundOrderByNode Copy() const; - string ToString() const; - - void Serialize(Serializer &serializer) const; - static BoundOrderByNode Deserialize(Deserializer &source, PlanDeserializationState &state); -}; - -class BoundLimitModifier : public BoundResultModifier { -public: - BoundLimitModifier(); - - //! LIMIT - int64_t limit_val = NumericLimits::Maximum(); - //! OFFSET - int64_t offset_val = 0; - //! Expression in case limit is not constant - unique_ptr limit; - //! Expression in case limit is not constant - unique_ptr offset; -}; - -class BoundOrderModifier : public BoundResultModifier { -public: - BoundOrderModifier(); - - //! List of order nodes - vector orders; -}; - -class BoundDistinctModifier : public BoundResultModifier { -public: - BoundDistinctModifier(); - - //! list of distinct on targets (if any) - vector> target_distincts; -}; - -class BoundLimitPercentModifier : public BoundResultModifier { -public: - BoundLimitPercentModifier(); - - //! LIMIT % - double limit_percent = 100.0; - //! OFFSET - int64_t offset_val = 0; - //! Expression in case limit is not constant - unique_ptr limit; - //! Expression in case limit is not constant - unique_ptr offset; -}; - -} // namespace duckdb - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/vector_operations/aggregate_executor.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - -namespace duckdb { - -struct AggregateInputData; - -typedef std::pair FrameBounds; - -class AggregateExecutor { -private: - template - static inline void NullaryFlatLoop(STATE_TYPE **__restrict states, AggregateInputData &aggr_input_data, - idx_t count) { - for (idx_t i = 0; i < count; i++) { - OP::template Operation(states[i], aggr_input_data, i); - } - } - - template - static inline void NullaryScatterLoop(STATE_TYPE **__restrict states, AggregateInputData &aggr_input_data, - const SelectionVector &ssel, idx_t count) { - - for (idx_t i = 0; i < count; i++) { - auto sidx = ssel.get_index(i); - OP::template Operation(states[sidx], aggr_input_data, sidx); - } - } - - template - static inline void UnaryFlatLoop(INPUT_TYPE *__restrict idata, AggregateInputData &aggr_input_data, - STATE_TYPE **__restrict states, ValidityMask &mask, idx_t count) { - if (!mask.AllValid()) { - idx_t base_idx = 0; - auto entry_count = ValidityMask::EntryCount(count); - for (idx_t entry_idx = 0; entry_idx < entry_count; entry_idx++) { - auto validity_entry = mask.GetValidityEntry(entry_idx); - idx_t next = MinValue(base_idx + ValidityMask::BITS_PER_VALUE, count); - if (!OP::IgnoreNull() || ValidityMask::AllValid(validity_entry)) { - // all valid: perform operation - for (; base_idx < next; base_idx++) { - OP::template Operation(states[base_idx], aggr_input_data, idata, - mask, base_idx); - } - } else if (ValidityMask::NoneValid(validity_entry)) { - // nothing valid: skip all - base_idx = next; - continue; - } else { - // partially valid: need to check individual elements for validity - idx_t start = base_idx; - for (; base_idx < next; base_idx++) { - if (ValidityMask::RowIsValid(validity_entry, base_idx - start)) { - OP::template Operation(states[base_idx], aggr_input_data, idata, - mask, base_idx); - } - } - } - } - } else { - for (idx_t i = 0; i < count; i++) { - OP::template Operation(states[i], aggr_input_data, idata, mask, i); - } - } - } - - template - static inline void UnaryScatterLoop(INPUT_TYPE *__restrict idata, AggregateInputData &aggr_input_data, - STATE_TYPE **__restrict states, const SelectionVector &isel, - const SelectionVector &ssel, ValidityMask &mask, idx_t count) { - if (OP::IgnoreNull() && !mask.AllValid()) { - // potential NULL values and NULL values are ignored - for (idx_t i = 0; i < count; i++) { - auto idx = isel.get_index(i); - auto sidx = ssel.get_index(i); - if (mask.RowIsValid(idx)) { - OP::template Operation(states[sidx], aggr_input_data, idata, mask, idx); - } - } - } else { - // quick path: no NULL values or NULL values are not ignored - for (idx_t i = 0; i < count; i++) { - auto idx = isel.get_index(i); - auto sidx = ssel.get_index(i); - OP::template Operation(states[sidx], aggr_input_data, idata, mask, idx); - } - } - } - - template - static inline void UnaryFlatUpdateLoop(INPUT_TYPE *__restrict idata, AggregateInputData &aggr_input_data, - STATE_TYPE *__restrict state, idx_t count, ValidityMask &mask) { - idx_t base_idx = 0; - auto entry_count = ValidityMask::EntryCount(count); - for (idx_t entry_idx = 0; entry_idx < entry_count; entry_idx++) { - auto validity_entry = mask.GetValidityEntry(entry_idx); - idx_t next = MinValue(base_idx + ValidityMask::BITS_PER_VALUE, count); - if (!OP::IgnoreNull() || ValidityMask::AllValid(validity_entry)) { - // all valid: perform operation - for (; base_idx < next; base_idx++) { - OP::template Operation(state, aggr_input_data, idata, mask, base_idx); - } - } else if (ValidityMask::NoneValid(validity_entry)) { - // nothing valid: skip all - base_idx = next; - continue; - } else { - // partially valid: need to check individual elements for validity - idx_t start = base_idx; - for (; base_idx < next; base_idx++) { - if (ValidityMask::RowIsValid(validity_entry, base_idx - start)) { - OP::template Operation(state, aggr_input_data, idata, mask, - base_idx); - } - } - } - } - } - - template - static inline void UnaryUpdateLoop(INPUT_TYPE *__restrict idata, AggregateInputData &aggr_input_data, - STATE_TYPE *__restrict state, idx_t count, ValidityMask &mask, - const SelectionVector &__restrict sel_vector) { - if (OP::IgnoreNull() && !mask.AllValid()) { - // potential NULL values and NULL values are ignored - for (idx_t i = 0; i < count; i++) { - auto idx = sel_vector.get_index(i); - if (mask.RowIsValid(idx)) { - OP::template Operation(state, aggr_input_data, idata, mask, idx); - } - } - } else { - // quick path: no NULL values or NULL values are not ignored - for (idx_t i = 0; i < count; i++) { - auto idx = sel_vector.get_index(i); - OP::template Operation(state, aggr_input_data, idata, mask, idx); - } - } - } - - template - static inline void BinaryScatterLoop(A_TYPE *__restrict adata, AggregateInputData &aggr_input_data, - B_TYPE *__restrict bdata, STATE_TYPE **__restrict states, idx_t count, - const SelectionVector &asel, const SelectionVector &bsel, - const SelectionVector &ssel, ValidityMask &avalidity, - ValidityMask &bvalidity) { - if (OP::IgnoreNull() && (!avalidity.AllValid() || !bvalidity.AllValid())) { - // potential NULL values and NULL values are ignored - for (idx_t i = 0; i < count; i++) { - auto aidx = asel.get_index(i); - auto bidx = bsel.get_index(i); - auto sidx = ssel.get_index(i); - if (avalidity.RowIsValid(aidx) && bvalidity.RowIsValid(bidx)) { - OP::template Operation(states[sidx], aggr_input_data, adata, bdata, - avalidity, bvalidity, aidx, bidx); - } - } - } else { - // quick path: no NULL values or NULL values are not ignored - for (idx_t i = 0; i < count; i++) { - auto aidx = asel.get_index(i); - auto bidx = bsel.get_index(i); - auto sidx = ssel.get_index(i); - OP::template Operation(states[sidx], aggr_input_data, adata, bdata, - avalidity, bvalidity, aidx, bidx); - } - } - } - - template - static inline void BinaryUpdateLoop(A_TYPE *__restrict adata, AggregateInputData &aggr_input_data, - B_TYPE *__restrict bdata, STATE_TYPE *__restrict state, idx_t count, - const SelectionVector &asel, const SelectionVector &bsel, - ValidityMask &avalidity, ValidityMask &bvalidity) { - if (OP::IgnoreNull() && (!avalidity.AllValid() || !bvalidity.AllValid())) { - // potential NULL values and NULL values are ignored - for (idx_t i = 0; i < count; i++) { - auto aidx = asel.get_index(i); - auto bidx = bsel.get_index(i); - if (avalidity.RowIsValid(aidx) && bvalidity.RowIsValid(bidx)) { - OP::template Operation(state, aggr_input_data, adata, bdata, - avalidity, bvalidity, aidx, bidx); - } - } - } else { - // quick path: no NULL values or NULL values are not ignored - for (idx_t i = 0; i < count; i++) { - auto aidx = asel.get_index(i); - auto bidx = bsel.get_index(i); - OP::template Operation(state, aggr_input_data, adata, bdata, avalidity, - bvalidity, aidx, bidx); - } - } - } - -public: - template - static void NullaryScatter(Vector &states, AggregateInputData &aggr_input_data, idx_t count) { - if (states.GetVectorType() == VectorType::CONSTANT_VECTOR) { - auto sdata = ConstantVector::GetData(states); - OP::template ConstantOperation(*sdata, aggr_input_data, count); - } else if (states.GetVectorType() == VectorType::FLAT_VECTOR) { - auto sdata = FlatVector::GetData(states); - NullaryFlatLoop(sdata, aggr_input_data, count); - } else { - UnifiedVectorFormat sdata; - states.ToUnifiedFormat(count, sdata); - NullaryScatterLoop((STATE_TYPE **)sdata.data, aggr_input_data, *sdata.sel, count); - } - } - - template - static void NullaryUpdate(data_ptr_t state, AggregateInputData &aggr_input_data, idx_t count) { - OP::template ConstantOperation((STATE_TYPE *)state, aggr_input_data, count); - } - - template - static void UnaryScatter(Vector &input, Vector &states, AggregateInputData &aggr_input_data, idx_t count) { - if (input.GetVectorType() == VectorType::CONSTANT_VECTOR && - states.GetVectorType() == VectorType::CONSTANT_VECTOR) { - if (OP::IgnoreNull() && ConstantVector::IsNull(input)) { - // constant NULL input in function that ignores NULL values - return; - } - // regular constant: get first state - auto idata = ConstantVector::GetData(input); - auto sdata = ConstantVector::GetData(states); - OP::template ConstantOperation(*sdata, aggr_input_data, idata, - ConstantVector::Validity(input), count); - } else if (input.GetVectorType() == VectorType::FLAT_VECTOR && - states.GetVectorType() == VectorType::FLAT_VECTOR) { - auto idata = FlatVector::GetData(input); - auto sdata = FlatVector::GetData(states); - UnaryFlatLoop(idata, aggr_input_data, sdata, FlatVector::Validity(input), - count); - } else { - UnifiedVectorFormat idata, sdata; - input.ToUnifiedFormat(count, idata); - states.ToUnifiedFormat(count, sdata); - UnaryScatterLoop((INPUT_TYPE *)idata.data, aggr_input_data, - (STATE_TYPE **)sdata.data, *idata.sel, *sdata.sel, - idata.validity, count); - } - } - - template - static void UnaryUpdate(Vector &input, AggregateInputData &aggr_input_data, data_ptr_t state, idx_t count) { - switch (input.GetVectorType()) { - case VectorType::CONSTANT_VECTOR: { - if (OP::IgnoreNull() && ConstantVector::IsNull(input)) { - return; - } - auto idata = ConstantVector::GetData(input); - OP::template ConstantOperation((STATE_TYPE *)state, aggr_input_data, idata, - ConstantVector::Validity(input), count); - break; - } - case VectorType::FLAT_VECTOR: { - auto idata = FlatVector::GetData(input); - UnaryFlatUpdateLoop(idata, aggr_input_data, (STATE_TYPE *)state, count, - FlatVector::Validity(input)); - break; - } - default: { - UnifiedVectorFormat idata; - input.ToUnifiedFormat(count, idata); - UnaryUpdateLoop((INPUT_TYPE *)idata.data, aggr_input_data, (STATE_TYPE *)state, - count, idata.validity, *idata.sel); - break; - } - } + DUCKDB_API idx_t size() const { + return rows.size(); } - template - static void BinaryScatter(AggregateInputData &aggr_input_data, Vector &a, Vector &b, Vector &states, idx_t count) { - UnifiedVectorFormat adata, bdata, sdata; - - a.ToUnifiedFormat(count, adata); - b.ToUnifiedFormat(count, bdata); - states.ToUnifiedFormat(count, sdata); + DUCKDB_API ColumnDataRow &operator[](idx_t i); + DUCKDB_API const ColumnDataRow &operator[](idx_t i) const; - BinaryScatterLoop((A_TYPE *)adata.data, aggr_input_data, (B_TYPE *)bdata.data, - (STATE_TYPE **)sdata.data, count, *adata.sel, *bdata.sel, - *sdata.sel, adata.validity, bdata.validity); + DUCKDB_API vector::iterator begin() { + return rows.begin(); + } + DUCKDB_API vector::iterator end() { + return rows.end(); + } + DUCKDB_API vector::const_iterator cbegin() const { + return rows.cbegin(); + } + DUCKDB_API vector::const_iterator cend() const { + return rows.cend(); + } + DUCKDB_API vector::const_iterator begin() const { + return rows.begin(); + } + DUCKDB_API vector::const_iterator end() const { + return rows.end(); } - template - static void BinaryUpdate(AggregateInputData &aggr_input_data, Vector &a, Vector &b, data_ptr_t state, idx_t count) { - UnifiedVectorFormat adata, bdata; +private: + vector rows; + vector> chunks; + ColumnDataScanState scan_state; +}; - a.ToUnifiedFormat(count, adata); - b.ToUnifiedFormat(count, bdata); +} // namespace duckdb - BinaryUpdateLoop((A_TYPE *)adata.data, aggr_input_data, (B_TYPE *)bdata.data, - (STATE_TYPE *)state, count, *adata.sel, *bdata.sel, - adata.validity, bdata.validity); - } - template - static void Combine(Vector &source, Vector &target, AggregateInputData &aggr_input_data, idx_t count) { - D_ASSERT(source.GetType().id() == LogicalTypeId::POINTER && target.GetType().id() == LogicalTypeId::POINTER); - auto sdata = FlatVector::GetData(source); - auto tdata = FlatVector::GetData(target); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/query_result.hpp +// +// +//===----------------------------------------------------------------------===// - for (idx_t i = 0; i < count; i++) { - OP::template Combine(*sdata[i], tdata[i], aggr_input_data); - } - } - template - static void Finalize(Vector &states, AggregateInputData &aggr_input_data, Vector &result, idx_t count, - idx_t offset) { - if (states.GetVectorType() == VectorType::CONSTANT_VECTOR) { - result.SetVectorType(VectorType::CONSTANT_VECTOR); - auto sdata = ConstantVector::GetData(states); - auto rdata = ConstantVector::GetData(result); - OP::template Finalize(result, aggr_input_data, *sdata, rdata, - ConstantVector::Validity(result), 0); - } else { - D_ASSERT(states.GetVectorType() == VectorType::FLAT_VECTOR); - result.SetVectorType(VectorType::FLAT_VECTOR); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/statement_type.hpp +// +// +//===----------------------------------------------------------------------===// - auto sdata = FlatVector::GetData(states); - auto rdata = FlatVector::GetData(result); - for (idx_t i = 0; i < count; i++) { - OP::template Finalize(result, aggr_input_data, sdata[i], rdata, - FlatVector::Validity(result), i + offset); - } - } - } - template - static void UnaryWindow(Vector &input, const ValidityMask &ifilter, AggregateInputData &aggr_input_data, - data_ptr_t state, const FrameBounds &frame, const FrameBounds &prev, Vector &result, - idx_t rid, idx_t bias) { - auto idata = FlatVector::GetData(input) - bias; - const auto &ivalid = FlatVector::Validity(input); - OP::template Window(idata, ifilter, ivalid, aggr_input_data, (STATE *)state, - frame, prev, result, rid, bias); + + + +namespace duckdb { + +//===--------------------------------------------------------------------===// +// Statement Types +//===--------------------------------------------------------------------===// +enum class StatementType : uint8_t { + INVALID_STATEMENT, // invalid statement type + SELECT_STATEMENT, // select statement type + INSERT_STATEMENT, // insert statement type + UPDATE_STATEMENT, // update statement type + CREATE_STATEMENT, // create statement type + DELETE_STATEMENT, // delete statement type + PREPARE_STATEMENT, // prepare statement type + EXECUTE_STATEMENT, // execute statement type + ALTER_STATEMENT, // alter statement type + TRANSACTION_STATEMENT, // transaction statement type, + COPY_STATEMENT, // copy type + ANALYZE_STATEMENT, // analyze type + VARIABLE_SET_STATEMENT, // variable set statement type + CREATE_FUNC_STATEMENT, // create func statement type + EXPLAIN_STATEMENT, // explain statement type + DROP_STATEMENT, // DROP statement type + EXPORT_STATEMENT, // EXPORT statement type + PRAGMA_STATEMENT, // PRAGMA statement type + SHOW_STATEMENT, // SHOW statement type + VACUUM_STATEMENT, // VACUUM statement type + CALL_STATEMENT, // CALL statement type + SET_STATEMENT, // SET statement type + LOAD_STATEMENT, // LOAD statement type + RELATION_STATEMENT, + EXTENSION_STATEMENT, + LOGICAL_PLAN_STATEMENT, + ATTACH_STATEMENT + +}; + +string StatementTypeToString(StatementType type); + +enum class StatementReturnType : uint8_t { + QUERY_RESULT, // the statement returns a query result (e.g. for display to the user) + CHANGED_ROWS, // the statement returns a single row containing the number of changed rows (e.g. an insert stmt) + NOTHING // the statement returns nothing +}; + +string StatementReturnTypeToString(StatementReturnType type); + +//! A struct containing various properties of a SQL statement +struct StatementProperties { + StatementProperties() + : requires_valid_transaction(true), allow_stream_result(false), bound_all_parameters(true), + return_type(StatementReturnType::QUERY_RESULT), parameter_count(0) { } - template - static void Destroy(Vector &states, idx_t count) { - auto sdata = FlatVector::GetData(states); - for (idx_t i = 0; i < count; i++) { - OP::template Destroy(sdata[i]); - } + //! The set of databases this statement will modify + unordered_set modified_databases; + //! Whether or not the statement requires a valid transaction. Almost all statements require this, with the + //! exception of + bool requires_valid_transaction; + //! Whether or not the result can be streamed to the client + bool allow_stream_result; + //! Whether or not all parameters have successfully had their types determined + bool bound_all_parameters; + //! What type of data the statement returns + StatementReturnType return_type; + //! The number of prepared statement parameters + idx_t parameter_count; + + bool IsReadOnly() { + return modified_databases.empty(); } }; } // namespace duckdb -namespace duckdb { -//! This allows us to use the & operator to check if the type is contained in the set -enum class AggregateType : uint8_t { NON_DISTINCT = 1, DISTINCT = 2 }; -class BoundAggregateExpression; -struct AggregateInputData { - AggregateInputData(FunctionData *bind_data_p, Allocator &allocator_p) - : bind_data(bind_data_p), allocator(allocator_p) {}; - FunctionData *bind_data; - Allocator &allocator; +namespace duckdb { +struct BoxRendererConfig; + +enum class QueryResultType : uint8_t { MATERIALIZED_RESULT, STREAM_RESULT, PENDING_RESULT }; + +//! A set of properties from the client context that can be used to interpret the query result +struct ClientProperties { + string timezone; }; -//! The type used for sizing hashed aggregate function states -typedef idx_t (*aggregate_size_t)(); -//! The type used for initializing hashed aggregate function states -typedef void (*aggregate_initialize_t)(data_ptr_t state); -//! The type used for updating hashed aggregate functions -typedef void (*aggregate_update_t)(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, - Vector &state, idx_t count); -//! The type used for combining hashed aggregate states -typedef void (*aggregate_combine_t)(Vector &state, Vector &combined, AggregateInputData &aggr_input_data, idx_t count); -//! The type used for finalizing hashed aggregate function payloads -typedef void (*aggregate_finalize_t)(Vector &state, AggregateInputData &aggr_input_data, Vector &result, idx_t count, - idx_t offset); -//! The type used for propagating statistics in aggregate functions (optional) -typedef unique_ptr (*aggregate_statistics_t)(ClientContext &context, BoundAggregateExpression &expr, - FunctionData *bind_data, - vector> &child_stats, - NodeStatistics *node_stats); -//! Binds the scalar function and creates the function data -typedef unique_ptr (*bind_aggregate_function_t)(ClientContext &context, AggregateFunction &function, - vector> &arguments); -//! The type used for the aggregate destructor method. NOTE: this method is used in destructors and MAY NOT throw. -typedef void (*aggregate_destructor_t)(Vector &state, idx_t count); +class BaseQueryResult { +public: + //! Creates a successful query result with the specified names and types + DUCKDB_API BaseQueryResult(QueryResultType type, StatementType statement_type, StatementProperties properties, + vector types, vector names); + //! Creates an unsuccessful query result with error condition + DUCKDB_API BaseQueryResult(QueryResultType type, PreservedError error); + DUCKDB_API virtual ~BaseQueryResult(); -//! The type used for updating simple (non-grouped) aggregate functions -typedef void (*aggregate_simple_update_t)(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, - data_ptr_t state, idx_t count); + //! The type of the result (MATERIALIZED or STREAMING) + QueryResultType type; + //! The type of the statement that created this result + StatementType statement_type; + //! Properties of the statement + StatementProperties properties; + //! The SQL types of the result + vector types; + //! The names of the result + vector names; -//! The type used for updating complex windowed aggregate functions (optional) -typedef std::pair FrameBounds; -typedef void (*aggregate_window_t)(Vector inputs[], const ValidityMask &filter_mask, - AggregateInputData &aggr_input_data, idx_t input_count, data_ptr_t state, - const FrameBounds &frame, const FrameBounds &prev, Vector &result, idx_t rid, - idx_t bias); +public: + DUCKDB_API void ThrowError(const string &prepended_message = "") const; + DUCKDB_API void SetError(PreservedError error); + DUCKDB_API bool HasError() const; + DUCKDB_API const ExceptionType &GetErrorType() const; + DUCKDB_API const std::string &GetError(); + DUCKDB_API PreservedError &GetErrorObject(); + DUCKDB_API idx_t ColumnCount(); + +protected: + //! Whether or not execution was successful + bool success; + //! The error (in case execution was not successful) + PreservedError error; +}; + +//! The QueryResult object holds the result of a query. It can either be a MaterializedQueryResult, in which case the +//! result contains the entire result set, or a StreamQueryResult in which case the Fetch method can be called to +//! incrementally fetch data from the database. +class QueryResult : public BaseQueryResult { +public: + //! Creates a successful query result with the specified names and types + DUCKDB_API QueryResult(QueryResultType type, StatementType statement_type, StatementProperties properties, + vector types, vector names, ClientProperties client_properties); + //! Creates an unsuccessful query result with error condition + DUCKDB_API QueryResult(QueryResultType type, PreservedError error); + DUCKDB_API virtual ~QueryResult() override; -typedef void (*aggregate_serialize_t)(FieldWriter &writer, const FunctionData *bind_data, - const AggregateFunction &function); -typedef unique_ptr (*aggregate_deserialize_t)(ClientContext &context, FieldReader &reader, - AggregateFunction &function); + //! Properties from the client context + ClientProperties client_properties; + //! The next result (if any) + unique_ptr next; -class AggregateFunction : public BaseScalarFunction { public: - DUCKDB_API - AggregateFunction(const string &name, const vector &arguments, const LogicalType &return_type, - aggregate_size_t state_size, aggregate_initialize_t initialize, aggregate_update_t update, - aggregate_combine_t combine, aggregate_finalize_t finalize, - FunctionNullHandling null_handling = FunctionNullHandling::DEFAULT_NULL_HANDLING, - aggregate_simple_update_t simple_update = nullptr, bind_aggregate_function_t bind = nullptr, - aggregate_destructor_t destructor = nullptr, aggregate_statistics_t statistics = nullptr, - aggregate_window_t window = nullptr, aggregate_serialize_t serialize = nullptr, - aggregate_deserialize_t deserialize = nullptr) - : BaseScalarFunction(name, arguments, return_type, FunctionSideEffects::NO_SIDE_EFFECTS, - LogicalType(LogicalTypeId::INVALID), null_handling), - state_size(state_size), initialize(initialize), update(update), combine(combine), finalize(finalize), - simple_update(simple_update), window(window), bind(bind), destructor(destructor), statistics(statistics), - serialize(serialize), deserialize(deserialize) { - } + //! Returns the name of the column for the given index + DUCKDB_API const string &ColumnName(idx_t index) const; + //! Fetches a DataChunk of normalized (flat) vectors from the query result. + //! Returns nullptr if there are no more results to fetch. + DUCKDB_API virtual unique_ptr Fetch(); + //! Fetches a DataChunk from the query result. The vectors are not normalized and hence any vector types can be + //! returned. + DUCKDB_API virtual unique_ptr FetchRaw() = 0; + //! Converts the QueryResult to a string + DUCKDB_API virtual string ToString() = 0; + //! Converts the QueryResult to a box-rendered string + DUCKDB_API virtual string ToBox(ClientContext &context, const BoxRendererConfig &config); + //! Prints the QueryResult to the console + DUCKDB_API void Print(); + //! Returns true if the two results are identical; false otherwise. Note that this method is destructive; it calls + //! Fetch() until both results are exhausted. The data in the results will be lost. + DUCKDB_API bool Equals(QueryResult &other); - DUCKDB_API - AggregateFunction(const string &name, const vector &arguments, const LogicalType &return_type, - aggregate_size_t state_size, aggregate_initialize_t initialize, aggregate_update_t update, - aggregate_combine_t combine, aggregate_finalize_t finalize, - aggregate_simple_update_t simple_update = nullptr, bind_aggregate_function_t bind = nullptr, - aggregate_destructor_t destructor = nullptr, aggregate_statistics_t statistics = nullptr, - aggregate_window_t window = nullptr, aggregate_serialize_t serialize = nullptr, - aggregate_deserialize_t deserialize = nullptr) - : BaseScalarFunction(name, arguments, return_type, FunctionSideEffects::NO_SIDE_EFFECTS, - LogicalType(LogicalTypeId::INVALID)), - state_size(state_size), initialize(initialize), update(update), combine(combine), finalize(finalize), - simple_update(simple_update), window(window), bind(bind), destructor(destructor), statistics(statistics), - serialize(serialize), deserialize(deserialize) { + DUCKDB_API bool TryFetch(unique_ptr &result, PreservedError &error) { + try { + result = Fetch(); + return success; + } catch (const Exception &ex) { + error = PreservedError(ex); + return false; + } catch (std::exception &ex) { + error = PreservedError(ex); + return false; + } catch (...) { + error = PreservedError("Unknown error in Fetch"); + return false; + } } - DUCKDB_API AggregateFunction(const vector &arguments, const LogicalType &return_type, - aggregate_size_t state_size, aggregate_initialize_t initialize, - aggregate_update_t update, aggregate_combine_t combine, aggregate_finalize_t finalize, - FunctionNullHandling null_handling = FunctionNullHandling::DEFAULT_NULL_HANDLING, - aggregate_simple_update_t simple_update = nullptr, - bind_aggregate_function_t bind = nullptr, aggregate_destructor_t destructor = nullptr, - aggregate_statistics_t statistics = nullptr, aggregate_window_t window = nullptr, - aggregate_serialize_t serialize = nullptr, - aggregate_deserialize_t deserialize = nullptr) - : AggregateFunction(string(), arguments, return_type, state_size, initialize, update, combine, finalize, - null_handling, simple_update, bind, destructor, statistics, window, serialize, - deserialize) { - } + static string GetConfigTimezone(QueryResult &query_result); - DUCKDB_API - AggregateFunction(const vector &arguments, const LogicalType &return_type, aggregate_size_t state_size, - aggregate_initialize_t initialize, aggregate_update_t update, aggregate_combine_t combine, - aggregate_finalize_t finalize, aggregate_simple_update_t simple_update = nullptr, - bind_aggregate_function_t bind = nullptr, aggregate_destructor_t destructor = nullptr, - aggregate_statistics_t statistics = nullptr, aggregate_window_t window = nullptr, - aggregate_serialize_t serialize = nullptr, aggregate_deserialize_t deserialize = nullptr) - : AggregateFunction(string(), arguments, return_type, state_size, initialize, update, combine, finalize, - FunctionNullHandling::DEFAULT_NULL_HANDLING, simple_update, bind, destructor, statistics, - window, serialize, deserialize) { - } - //! The hashed aggregate state sizing function - aggregate_size_t state_size; - //! The hashed aggregate state initialization function - aggregate_initialize_t initialize; - //! The hashed aggregate update state function - aggregate_update_t update; - //! The hashed aggregate combine states function - aggregate_combine_t combine; - //! The hashed aggregate finalization function - aggregate_finalize_t finalize; - //! The simple aggregate update function (may be null) - aggregate_simple_update_t simple_update; - //! The windowed aggregate frame update function (may be null) - aggregate_window_t window; +private: + class QueryResultIterator; + class QueryResultRow { + public: + explicit QueryResultRow(QueryResultIterator &iterator_p, idx_t row_idx) : iterator(iterator_p), row(0) { + } - //! The bind function (may be null) - bind_aggregate_function_t bind; - //! The destructor method (may be null) - aggregate_destructor_t destructor; + QueryResultIterator &iterator; + idx_t row; - //! The statistics propagation function (may be null) - aggregate_statistics_t statistics; + template + T GetValue(idx_t col_idx) const { + return iterator.chunk->GetValue(col_idx, row).GetValue(); + } + }; + //! The row-based query result iterator. Invoking the + class QueryResultIterator { + public: + explicit QueryResultIterator(QueryResult *result_p) : current_row(*this, 0), result(result_p), base_row(0) { + if (result) { + chunk = shared_ptr(result->Fetch().release()); + if (!chunk) { + result = nullptr; + } + } + } - aggregate_serialize_t serialize; - aggregate_deserialize_t deserialize; + QueryResultRow current_row; + shared_ptr chunk; + QueryResult *result; + idx_t base_row; - DUCKDB_API bool operator==(const AggregateFunction &rhs) const { - return state_size == rhs.state_size && initialize == rhs.initialize && update == rhs.update && - combine == rhs.combine && finalize == rhs.finalize && window == rhs.window; - } - DUCKDB_API bool operator!=(const AggregateFunction &rhs) const { - return !(*this == rhs); - } + public: + void Next() { + if (!chunk) { + return; + } + current_row.row++; + if (current_row.row >= chunk->size()) { + base_row += chunk->size(); + chunk = result->Fetch(); + current_row.row = 0; + if (!chunk || chunk->size() == 0) { + // exhausted all rows + base_row = 0; + result = nullptr; + chunk.reset(); + } + } + } + + QueryResultIterator &operator++() { + Next(); + return *this; + } + bool operator!=(const QueryResultIterator &other) const { + return result != other.result || base_row != other.base_row || current_row.row != other.current_row.row; + } + const QueryResultRow &operator*() const { + return current_row; + } + }; public: - template - static AggregateFunction NullaryAggregate(LogicalType return_type) { - return AggregateFunction( - {}, return_type, AggregateFunction::StateSize, AggregateFunction::StateInitialize, - AggregateFunction::NullaryScatterUpdate, AggregateFunction::StateCombine, - AggregateFunction::StateFinalize, AggregateFunction::NullaryUpdate); + DUCKDB_API QueryResultIterator begin() { + return QueryResultIterator(this); } - - template - static AggregateFunction - UnaryAggregate(const LogicalType &input_type, LogicalType return_type, - FunctionNullHandling null_handling = FunctionNullHandling::DEFAULT_NULL_HANDLING) { - return AggregateFunction( - {input_type}, return_type, AggregateFunction::StateSize, - AggregateFunction::StateInitialize, AggregateFunction::UnaryScatterUpdate, - AggregateFunction::StateCombine, AggregateFunction::StateFinalize, - null_handling, AggregateFunction::UnaryUpdate); + DUCKDB_API QueryResultIterator end() { + return QueryResultIterator(nullptr); } - template - static AggregateFunction UnaryAggregateDestructor(LogicalType input_type, LogicalType return_type) { - auto aggregate = UnaryAggregate(input_type, return_type); - aggregate.destructor = AggregateFunction::StateDestroy; - return aggregate; - } +protected: + DUCKDB_API string HeaderToString(); - template - static AggregateFunction BinaryAggregate(const LogicalType &a_type, const LogicalType &b_type, - LogicalType return_type) { - return AggregateFunction({a_type, b_type}, return_type, AggregateFunction::StateSize, - AggregateFunction::StateInitialize, - AggregateFunction::BinaryScatterUpdate, - AggregateFunction::StateCombine, - AggregateFunction::StateFinalize, - AggregateFunction::BinaryUpdate); - } +private: + QueryResult(const QueryResult &) = delete; +}; + +} // namespace duckdb + + +namespace duckdb { + +class ClientContext; +class MaterializedQueryResult : public QueryResult { public: - template - static idx_t StateSize() { - return sizeof(STATE); - } + friend class ClientContext; + //! Creates a successful query result with the specified names and types + DUCKDB_API MaterializedQueryResult(StatementType statement_type, StatementProperties properties, + vector names, unique_ptr collection, + ClientProperties client_properties); + //! Creates an unsuccessful query result with error condition + DUCKDB_API explicit MaterializedQueryResult(PreservedError error); - template - static void StateInitialize(data_ptr_t state) { - OP::Initialize((STATE *)state); +public: + //! Fetches a DataChunk from the query result. + //! This will consume the result (i.e. the result can only be scanned once with this function) + DUCKDB_API unique_ptr Fetch() override; + DUCKDB_API unique_ptr FetchRaw() override; + //! Converts the QueryResult to a string + DUCKDB_API string ToString() override; + DUCKDB_API string ToBox(ClientContext &context, const BoxRendererConfig &config) override; + + //! Gets the (index) value of the (column index) column. + //! Note: this is very slow. Scanning over the underlying collection is much faster. + DUCKDB_API Value GetValue(idx_t column, idx_t index); + + template + T GetValue(idx_t column, idx_t index) { + auto value = GetValue(column, index); + return (T)value.GetValue(); } - template - static void NullaryScatterUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, - Vector &states, idx_t count) { - D_ASSERT(input_count == 0); - AggregateExecutor::NullaryScatter(states, aggr_input_data, count); - } + DUCKDB_API idx_t RowCount() const; - template - static void NullaryUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, data_ptr_t state, - idx_t count) { - D_ASSERT(input_count == 0); - AggregateExecutor::NullaryUpdate(state, aggr_input_data, count); - } + //! Returns a reference to the underlying column data collection + ColumnDataCollection &Collection(); - template - static void UnaryScatterUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, - Vector &states, idx_t count) { - D_ASSERT(input_count == 1); - AggregateExecutor::UnaryScatter(inputs[0], states, aggr_input_data, count); - } +private: + unique_ptr collection; + //! Row collection, only created if GetValue is called + unique_ptr row_collection; + //! Scan state for Fetch calls + ColumnDataScanState scan_state; + bool scan_initialized; +}; - template - static void UnaryUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, data_ptr_t state, - idx_t count) { - D_ASSERT(input_count == 1); - AggregateExecutor::UnaryUpdate(inputs[0], aggr_input_data, state, count); - } +} // namespace duckdb - template - static void UnaryWindow(Vector inputs[], const ValidityMask &filter_mask, AggregateInputData &aggr_input_data, - idx_t input_count, data_ptr_t state, const FrameBounds &frame, const FrameBounds &prev, - Vector &result, idx_t rid, idx_t bias) { - D_ASSERT(input_count == 1); - AggregateExecutor::UnaryWindow(inputs[0], filter_mask, aggr_input_data, - state, frame, prev, result, rid, bias); - } +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/pending_query_result.hpp +// +// +//===----------------------------------------------------------------------===// - template - static void BinaryScatterUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, - Vector &states, idx_t count) { - D_ASSERT(input_count == 2); - AggregateExecutor::BinaryScatter(aggr_input_data, inputs[0], inputs[1], states, - count); - } - template - static void BinaryUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, data_ptr_t state, - idx_t count) { - D_ASSERT(input_count == 2); - AggregateExecutor::BinaryUpdate(aggr_input_data, inputs[0], inputs[1], state, count); - } - template - static void StateCombine(Vector &source, Vector &target, AggregateInputData &aggr_input_data, idx_t count) { - AggregateExecutor::Combine(source, target, aggr_input_data, count); - } - template - static void StateFinalize(Vector &states, AggregateInputData &aggr_input_data, Vector &result, idx_t count, - idx_t offset) { - AggregateExecutor::Finalize(states, aggr_input_data, result, count, offset); - } +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/pending_execution_result.hpp +// +// +//===----------------------------------------------------------------------===// + - template - static void StateDestroy(Vector &states, idx_t count) { - AggregateExecutor::Destroy(states, count); - } -}; -} // namespace duckdb namespace duckdb { -struct UDFWrapper { -public: - template - static scalar_function_t CreateScalarFunction(const string &name, TR (*udf_func)(Args...)) { - const std::size_t num_template_argc = sizeof...(Args); - switch (num_template_argc) { - case 1: - return CreateUnaryFunction(name, udf_func); - case 2: - return CreateBinaryFunction(name, udf_func); - case 3: - return CreateTernaryFunction(name, udf_func); - default: // LCOV_EXCL_START - throw std::runtime_error("UDF function only supported until ternary!"); - } // LCOV_EXCL_STOP - } +enum class PendingExecutionResult : uint8_t { RESULT_READY, RESULT_NOT_READY, EXECUTION_ERROR }; - template - static scalar_function_t CreateScalarFunction(const string &name, vector args, LogicalType ret_type, - TR (*udf_func)(Args...)) { - if (!TypesMatch(ret_type)) { // LCOV_EXCL_START - throw std::runtime_error("Return type doesn't match with the first template type."); - } // LCOV_EXCL_STOP +} // namespace duckdb - const std::size_t num_template_types = sizeof...(Args); - if (num_template_types != args.size()) { // LCOV_EXCL_START - throw std::runtime_error( - "The number of templated types should be the same quantity of the LogicalType arguments."); - } // LCOV_EXCL_STOP +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/execution/executor.hpp +// +// +//===----------------------------------------------------------------------===// - switch (num_template_types) { - case 1: - return CreateUnaryFunction(name, args, ret_type, udf_func); - case 2: - return CreateBinaryFunction(name, args, ret_type, udf_func); - case 3: - return CreateTernaryFunction(name, args, ret_type, udf_func); - default: // LCOV_EXCL_START - throw std::runtime_error("UDF function only supported until ternary!"); - } // LCOV_EXCL_STOP - } - template - static void RegisterFunction(const string &name, scalar_function_t udf_function, ClientContext &context, - LogicalType varargs = LogicalType(LogicalTypeId::INVALID)) { - vector arguments; - GetArgumentTypesRecursive(arguments); - LogicalType ret_type = GetArgumentType(); - RegisterFunction(name, arguments, ret_type, udf_function, context, varargs); - } - DUCKDB_API static void RegisterFunction(string name, vector args, LogicalType ret_type, - scalar_function_t udf_function, ClientContext &context, - LogicalType varargs = LogicalType(LogicalTypeId::INVALID)); - //--------------------------------- Aggregate UDFs ------------------------------------// - template - static AggregateFunction CreateAggregateFunction(const string &name) { - return CreateUnaryAggregateFunction(name); - } - template - static AggregateFunction CreateAggregateFunction(const string &name) { - return CreateBinaryAggregateFunction(name); - } - template - static AggregateFunction CreateAggregateFunction(const string &name, LogicalType ret_type, LogicalType input_type) { - if (!TypesMatch(ret_type)) { // LCOV_EXCL_START - throw std::runtime_error("The return argument don't match!"); - } // LCOV_EXCL_STOP +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parallel/pipeline.hpp +// +// +//===----------------------------------------------------------------------===// - if (!TypesMatch(input_type)) { // LCOV_EXCL_START - throw std::runtime_error("The input argument don't match!"); - } // LCOV_EXCL_STOP - return CreateUnaryAggregateFunction(name, ret_type, input_type); - } - template - static AggregateFunction CreateAggregateFunction(const string &name, LogicalType ret_type, LogicalType input_typeA, - LogicalType input_typeB) { - if (!TypesMatch(ret_type)) { // LCOV_EXCL_START - throw std::runtime_error("The return argument don't match!"); - } +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/atomic.hpp +// +// +//===----------------------------------------------------------------------===// - if (!TypesMatch(input_typeA)) { - throw std::runtime_error("The first input argument don't match!"); - } - if (!TypesMatch(input_typeB)) { - throw std::runtime_error("The second input argument don't match!"); - } // LCOV_EXCL_STOP - return CreateBinaryAggregateFunction(name, ret_type, input_typeA, input_typeB); - } +#include - //! A generic CreateAggregateFunction ---------------------------------------------------------------------------// - static AggregateFunction CreateAggregateFunction(string name, vector arguments, - LogicalType return_type, aggregate_size_t state_size, - aggregate_initialize_t initialize, aggregate_update_t update, - aggregate_combine_t combine, aggregate_finalize_t finalize, - aggregate_simple_update_t simple_update = nullptr, - bind_aggregate_function_t bind = nullptr, - aggregate_destructor_t destructor = nullptr) { +namespace duckdb { +using std::atomic; +} - AggregateFunction aggr_function(move(name), move(arguments), move(return_type), state_size, initialize, update, - combine, finalize, simple_update, bind, destructor); - aggr_function.null_handling = FunctionNullHandling::SPECIAL_HANDLING; - return aggr_function; - } - DUCKDB_API static void RegisterAggrFunction(AggregateFunction aggr_function, ClientContext &context, - LogicalType varargs = LogicalType(LogicalTypeId::INVALID)); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/execution/physical_operator.hpp +// +// +//===----------------------------------------------------------------------===// -private: - //-------------------------------- Templated functions --------------------------------// - struct UnaryUDFExecutor { - template - static RESULT_TYPE Operation(INPUT_TYPE input, ValidityMask &mask, idx_t idx, void *dataptr) { - typedef RESULT_TYPE (*unary_function_t)(INPUT_TYPE); - auto udf = (unary_function_t)dataptr; - return udf(input); - } - }; - template - static scalar_function_t CreateUnaryFunction(const string &name, TR (*udf_func)(TA)) { - scalar_function_t udf_function = [=](DataChunk &input, ExpressionState &state, Vector &result) -> void { - UnaryExecutor::GenericExecute(input.data[0], result, input.size(), - (void *)udf_func); - }; - return udf_function; - } - template - static scalar_function_t CreateBinaryFunction(const string &name, TR (*udf_func)(TA, TB)) { - scalar_function_t udf_function = [=](DataChunk &input, ExpressionState &state, Vector &result) -> void { - BinaryExecutor::Execute(input.data[0], input.data[1], result, input.size(), udf_func); - }; - return udf_function; - } +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/catalog/catalog.hpp +// +// +//===----------------------------------------------------------------------===// + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/catalog/catalog_entry.hpp +// +// +//===----------------------------------------------------------------------===// - template - static scalar_function_t CreateTernaryFunction(const string &name, TR (*udf_func)(TA, TB, TC)) { - scalar_function_t udf_function = [=](DataChunk &input, ExpressionState &state, Vector &result) -> void { - TernaryExecutor::Execute(input.data[0], input.data[1], input.data[2], result, input.size(), - udf_func); - }; - return udf_function; - } - template - static scalar_function_t CreateUnaryFunction(const string &name, TR (*udf_func)(Args...)) { // LCOV_EXCL_START - throw std::runtime_error("Incorrect number of arguments for unary function"); - } // LCOV_EXCL_STOP - template - static scalar_function_t CreateBinaryFunction(const string &name, TR (*udf_func)(Args...)) { // LCOV_EXCL_START - throw std::runtime_error("Incorrect number of arguments for binary function"); - } // LCOV_EXCL_STOP - template - static scalar_function_t CreateTernaryFunction(const string &name, TR (*udf_func)(Args...)) { // LCOV_EXCL_START - throw std::runtime_error("Incorrect number of arguments for ternary function"); - } // LCOV_EXCL_STOP +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/catalog_type.hpp +// +// +//===----------------------------------------------------------------------===// - template - static LogicalType GetArgumentType() { - if (std::is_same()) { - return LogicalType(LogicalTypeId::BOOLEAN); - } else if (std::is_same()) { - return LogicalType(LogicalTypeId::TINYINT); - } else if (std::is_same()) { - return LogicalType(LogicalTypeId::SMALLINT); - } else if (std::is_same()) { - return LogicalType(LogicalTypeId::INTEGER); - } else if (std::is_same()) { - return LogicalType(LogicalTypeId::BIGINT); - } else if (std::is_same()) { - return LogicalType(LogicalTypeId::FLOAT); - } else if (std::is_same()) { - return LogicalType(LogicalTypeId::DOUBLE); - } else if (std::is_same()) { - return LogicalType(LogicalTypeId::VARCHAR); - } else { // LCOV_EXCL_START - throw std::runtime_error("Unrecognized type!"); - } // LCOV_EXCL_STOP - } - template - static void GetArgumentTypesRecursive(vector &arguments) { - arguments.push_back(GetArgumentType()); - GetArgumentTypesRecursive(arguments); - } - template - static void GetArgumentTypesRecursive(vector &arguments) { - arguments.push_back(GetArgumentType()); - } -private: - //-------------------------------- Argumented functions --------------------------------// - template - static scalar_function_t CreateUnaryFunction(const string &name, vector args, LogicalType ret_type, - TR (*udf_func)(Args...)) { // LCOV_EXCL_START - throw std::runtime_error("Incorrect number of arguments for unary function"); - } // LCOV_EXCL_STOP +namespace duckdb { - template - static scalar_function_t CreateUnaryFunction(const string &name, vector args, LogicalType ret_type, - TR (*udf_func)(TA)) { - if (args.size() != 1) { // LCOV_EXCL_START - throw std::runtime_error("The number of LogicalType arguments (\"args\") should be 1!"); - } - if (!TypesMatch(args[0])) { - throw std::runtime_error("The first arguments don't match!"); - } // LCOV_EXCL_STOP +//===--------------------------------------------------------------------===// +// Catalog Types +//===--------------------------------------------------------------------===// +enum class CatalogType : uint8_t { + INVALID = 0, + TABLE_ENTRY = 1, + SCHEMA_ENTRY = 2, + VIEW_ENTRY = 3, + INDEX_ENTRY = 4, + PREPARED_STATEMENT = 5, + SEQUENCE_ENTRY = 6, + COLLATION_ENTRY = 7, + TYPE_ENTRY = 8, + DATABASE_ENTRY = 9, - scalar_function_t udf_function = [=](DataChunk &input, ExpressionState &state, Vector &result) -> void { - UnaryExecutor::GenericExecute(input.data[0], result, input.size(), - (void *)udf_func); - }; - return udf_function; - } + // functions + TABLE_FUNCTION_ENTRY = 25, + SCALAR_FUNCTION_ENTRY = 26, + AGGREGATE_FUNCTION_ENTRY = 27, + PRAGMA_FUNCTION_ENTRY = 28, + COPY_FUNCTION_ENTRY = 29, + MACRO_ENTRY = 30, + TABLE_MACRO_ENTRY = 31, - template - static scalar_function_t CreateBinaryFunction(const string &name, vector args, LogicalType ret_type, - TR (*udf_func)(Args...)) { // LCOV_EXCL_START - throw std::runtime_error("Incorrect number of arguments for binary function"); - } // LCOV_EXCL_STOP + // version info + UPDATED_ENTRY = 50, + DELETED_ENTRY = 51, +}; - template - static scalar_function_t CreateBinaryFunction(const string &name, vector args, LogicalType ret_type, - TR (*udf_func)(TA, TB)) { - if (args.size() != 2) { // LCOV_EXCL_START - throw std::runtime_error("The number of LogicalType arguments (\"args\") should be 2!"); - } - if (!TypesMatch(args[0])) { - throw std::runtime_error("The first arguments don't match!"); - } - if (!TypesMatch(args[1])) { - throw std::runtime_error("The second arguments don't match!"); - } // LCOV_EXCL_STOP +DUCKDB_API string CatalogTypeToString(CatalogType type); - scalar_function_t udf_function = [=](DataChunk &input, ExpressionState &state, Vector &result) { - BinaryExecutor::Execute(input.data[0], input.data[1], result, input.size(), udf_func); - }; - return udf_function; - } +} // namespace duckdb - template - static scalar_function_t CreateTernaryFunction(const string &name, vector args, LogicalType ret_type, - TR (*udf_func)(Args...)) { // LCOV_EXCL_START - throw std::runtime_error("Incorrect number of arguments for ternary function"); - } // LCOV_EXCL_STOP - template - static scalar_function_t CreateTernaryFunction(const string &name, vector args, LogicalType ret_type, - TR (*udf_func)(TA, TB, TC)) { - if (args.size() != 3) { // LCOV_EXCL_START - throw std::runtime_error("The number of LogicalType arguments (\"args\") should be 3!"); - } - if (!TypesMatch(args[0])) { - throw std::runtime_error("The first arguments don't match!"); - } - if (!TypesMatch(args[1])) { - throw std::runtime_error("The second arguments don't match!"); - } - if (!TypesMatch(args[2])) { - throw std::runtime_error("The second arguments don't match!"); - } // LCOV_EXCL_STOP - scalar_function_t udf_function = [=](DataChunk &input, ExpressionState &state, Vector &result) -> void { - TernaryExecutor::Execute(input.data[0], input.data[1], input.data[2], result, input.size(), - udf_func); - }; - return udf_function; - } - template - static bool TypesMatch(const LogicalType &sql_type) { - switch (sql_type.id()) { - case LogicalTypeId::BOOLEAN: - return std::is_same(); - case LogicalTypeId::TINYINT: - return std::is_same(); - case LogicalTypeId::SMALLINT: - return std::is_same(); - case LogicalTypeId::INTEGER: - return std::is_same(); - case LogicalTypeId::BIGINT: - return std::is_same(); - case LogicalTypeId::DATE: - return std::is_same(); - case LogicalTypeId::TIME: - case LogicalTypeId::TIME_TZ: - return std::is_same(); - case LogicalTypeId::TIMESTAMP: - case LogicalTypeId::TIMESTAMP_MS: - case LogicalTypeId::TIMESTAMP_NS: - case LogicalTypeId::TIMESTAMP_SEC: - case LogicalTypeId::TIMESTAMP_TZ: - return std::is_same(); - case LogicalTypeId::FLOAT: - return std::is_same(); - case LogicalTypeId::DOUBLE: - return std::is_same(); - case LogicalTypeId::VARCHAR: - case LogicalTypeId::CHAR: - case LogicalTypeId::BLOB: - return std::is_same(); - default: // LCOV_EXCL_START - throw std::runtime_error("Type is not supported!"); - } // LCOV_EXCL_STOP - } +#include -private: - //-------------------------------- Aggregate functions --------------------------------// - template - static AggregateFunction CreateUnaryAggregateFunction(const string &name) { - LogicalType return_type = GetArgumentType(); - LogicalType input_type = GetArgumentType(); - return CreateUnaryAggregateFunction(name, return_type, input_type); - } +namespace duckdb { +struct AlterInfo; +class Catalog; +class CatalogSet; +class ClientContext; - template - static AggregateFunction CreateUnaryAggregateFunction(const string &name, LogicalType ret_type, - LogicalType input_type) { - AggregateFunction aggr_function = - AggregateFunction::UnaryAggregate(input_type, ret_type); - aggr_function.name = name; - return aggr_function; - } +//! Abstract base class of an entry in the catalog +class CatalogEntry { +public: + CatalogEntry(CatalogType type, Catalog *catalog, string name); + virtual ~CatalogEntry(); - template - static AggregateFunction CreateBinaryAggregateFunction(const string &name) { - LogicalType return_type = GetArgumentType(); - LogicalType input_typeA = GetArgumentType(); - LogicalType input_typeB = GetArgumentType(); - return CreateBinaryAggregateFunction(name, return_type, input_typeA, input_typeB); - } + //! The oid of the entry + idx_t oid; + //! The type of this catalog entry + CatalogType type; + //! Reference to the catalog this entry belongs to + Catalog *catalog; + //! Reference to the catalog set this entry is stored in + CatalogSet *set; + //! The name of the entry + string name; + //! Whether or not the object is deleted + bool deleted; + //! Whether or not the object is temporary and should not be added to the WAL + bool temporary; + //! Whether or not the entry is an internal entry (cannot be deleted, not dumped, etc) + bool internal; + //! Timestamp at which the catalog entry was created + atomic timestamp; + //! Child entry + unique_ptr child; + //! Parent entry (the node that dependents_map this node) + CatalogEntry *parent; + +public: + virtual unique_ptr AlterEntry(ClientContext &context, AlterInfo *info); + virtual void UndoAlter(ClientContext &context, AlterInfo *info); + + virtual unique_ptr Copy(ClientContext &context); - template - static AggregateFunction CreateBinaryAggregateFunction(const string &name, LogicalType ret_type, - LogicalType input_typeA, LogicalType input_typeB) { - AggregateFunction aggr_function = - AggregateFunction::BinaryAggregate(input_typeA, input_typeB, ret_type); - aggr_function.name = name; - return aggr_function; - } -}; // end UDFWrapper + //! Sets the CatalogEntry as the new root entry (i.e. the newest entry) + // this is called on a rollback to an AlterEntry + virtual void SetAsRoot(); + //! Convert the catalog entry to a SQL string that can be used to re-construct the catalog entry + virtual string ToSQL(); + + virtual void Verify(Catalog &catalog); +}; } // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/materialized_query_result.hpp +// duckdb/parser/query_error_context.hpp // // //===----------------------------------------------------------------------===// -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/types/column_data_collection.hpp -// -// -//===----------------------------------------------------------------------===// -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/pair.hpp -// -// -//===----------------------------------------------------------------------===// +namespace duckdb { +class SQLStatement; +class QueryErrorContext { +public: + explicit QueryErrorContext(SQLStatement *statement_ = nullptr, idx_t query_location_ = DConstants::INVALID_INDEX) + : statement(statement_), query_location(query_location_) { + } -#include + //! The query statement + SQLStatement *statement; + //! The location in which the error should be thrown + idx_t query_location; + +public: + DUCKDB_API static string Format(const string &query, const string &error_message, int error_location); + + DUCKDB_API string FormatErrorRecursive(const string &msg, vector &values); + template + string FormatErrorRecursive(const string &msg, vector &values, T param, Args... params) { + values.push_back(ExceptionFormatValue::CreateFormatValue(param)); + return FormatErrorRecursive(msg, values, params...); + } + + template + string FormatError(const string &msg, Args... params) { + vector values; + return FormatErrorRecursive(msg, values, params...); + } +}; -namespace duckdb { -using std::make_pair; -using std::pair; } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/types/column_data_collection_iterators.hpp +// duckdb/catalog/catalog_transaction.hpp // // //===----------------------------------------------------------------------===// -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/types/column_data_scan_states.hpp -// -// -//===----------------------------------------------------------------------===// +namespace duckdb { +class Catalog; +class ClientContext; +class DatabaseInstance; +class Transaction; +struct CatalogTransaction { + CatalogTransaction(Catalog &catalog, ClientContext &context); + CatalogTransaction(DatabaseInstance &db, transaction_t transaction_id_p, transaction_t start_time_p); + DatabaseInstance *db; + ClientContext *context; + Transaction *transaction; + transaction_t transaction_id; + transaction_t start_time; + ClientContext &GetContext(); +}; +} // namespace duckdb -namespace duckdb { -enum class ColumnDataAllocatorType : uint8_t { - //! Use a buffer manager to allocate large chunks of memory that vectors then use - BUFFER_MANAGER_ALLOCATOR, - //! Use an in-memory allocator, allocating data for every chunk - //! This causes the column data collection to allocate blocks that are not tied to a buffer manager - IN_MEMORY_ALLOCATOR -}; -enum class ColumnDataScanProperties : uint8_t { - INVALID, - //! Allow zero copy scans - this introduces a dependency on the resulting vector on the scan state of the column - //! data collection, which means vectors might not be valid anymore after the next chunk is scanned. - ALLOW_ZERO_COPY, - //! Disallow zero-copy scans, always copying data into the target vector - //! As a result, data scanned will be valid even after the column data collection is destroyed - DISALLOW_ZERO_COPY -}; +#include -struct ChunkManagementState { - unordered_map handles; - ColumnDataScanProperties properties = ColumnDataScanProperties::INVALID; -}; +namespace duckdb { +struct CreateSchemaInfo; +struct DropInfo; +struct BoundCreateTableInfo; +struct AlterTableInfo; +struct CreateTableFunctionInfo; +struct CreateCopyFunctionInfo; +struct CreatePragmaFunctionInfo; +struct CreateFunctionInfo; +struct CreateViewInfo; +struct CreateSequenceInfo; +struct CreateCollationInfo; +struct CreateTypeInfo; +struct CreateTableInfo; +struct DatabaseSize; -struct ColumnDataAppendState { - ChunkManagementState current_chunk_state; - vector vector_data; -}; +class AttachedDatabase; +class ClientContext; +class Transaction; -struct ColumnDataScanState { - ChunkManagementState current_chunk_state; - idx_t segment_index; - idx_t chunk_index; - idx_t current_row_index; - idx_t next_row_index; - ColumnDataScanProperties properties; - vector column_ids; -}; +class AggregateFunctionCatalogEntry; +class CollateCatalogEntry; +class SchemaCatalogEntry; +class TableCatalogEntry; +class ViewCatalogEntry; +class SequenceCatalogEntry; +class TableFunctionCatalogEntry; +class CopyFunctionCatalogEntry; +class PragmaFunctionCatalogEntry; +class CatalogSet; +class DatabaseInstance; +class DependencyManager; -struct ColumnDataParallelScanState { - ColumnDataScanState scan_state; - mutex lock; -}; +struct CatalogLookup; +struct CatalogEntryLookup; +struct SimilarCatalogEntry; -struct ColumnDataLocalScanState { - ChunkManagementState current_chunk_state; - idx_t current_segment_index = DConstants::INVALID_INDEX; - idx_t current_row_index; -}; +class Binder; +class LogicalOperator; +class PhysicalOperator; +class LogicalCreateIndex; +class LogicalCreateTable; +class LogicalInsert; +class LogicalDelete; +class LogicalUpdate; +class CreateStatement; -class ColumnDataRow { +//! The Catalog object represents the catalog of the database. +class Catalog { public: - ColumnDataRow(DataChunk &chunk, idx_t row_index, idx_t base_index); - - DataChunk &chunk; - idx_t row_index; - idx_t base_index; + explicit Catalog(AttachedDatabase &db); + virtual ~Catalog(); public: - Value GetValue(idx_t column_index) const; - idx_t RowIndex() const; -}; + //! Get the SystemCatalog from the ClientContext + DUCKDB_API static Catalog &GetSystemCatalog(ClientContext &context); + //! Get the SystemCatalog from the DatabaseInstance + DUCKDB_API static Catalog &GetSystemCatalog(DatabaseInstance &db); + //! Get the specified Catalog from the ClientContext + DUCKDB_API static Catalog &GetCatalog(ClientContext &context, const string &catalog_name); + //! Get the specified Catalog from the DatabaseInstance + DUCKDB_API static Catalog &GetCatalog(DatabaseInstance &db, const string &catalog_name); + //! Get the specific Catalog from the AttachedDatabase + DUCKDB_API static Catalog &GetCatalog(AttachedDatabase &db); -} // namespace duckdb + DUCKDB_API AttachedDatabase &GetAttached(); + DUCKDB_API DatabaseInstance &GetDatabase(); + virtual bool IsDuckCatalog() { + return false; + } + virtual void Initialize(bool load_builtin) = 0; -namespace duckdb { -class ColumnDataCollection; + bool IsSystemCatalog() const; + bool IsTemporaryCatalog() const; -class ColumnDataChunkIterationHelper { -public: - DUCKDB_API ColumnDataChunkIterationHelper(const ColumnDataCollection &collection, vector column_ids); + //! Returns the current version of the catalog (incremented whenever anything changes, not stored between restarts) + DUCKDB_API idx_t GetCatalogVersion(); + //! Trigger a modification in the catalog, increasing the catalog version and returning the previous version + DUCKDB_API idx_t ModifyCatalog(); -private: - const ColumnDataCollection &collection; - vector column_ids; + //! Returns the catalog name - based on how the catalog was attached + DUCKDB_API const string &GetName(); + DUCKDB_API idx_t GetOid(); + DUCKDB_API virtual string GetCatalogType() = 0; + + DUCKDB_API CatalogTransaction GetCatalogTransaction(ClientContext &context); + + //! Creates a schema in the catalog. + DUCKDB_API virtual CatalogEntry *CreateSchema(CatalogTransaction transaction, CreateSchemaInfo *info) = 0; + DUCKDB_API CatalogEntry *CreateSchema(ClientContext &context, CreateSchemaInfo *info); + //! Creates a table in the catalog. + DUCKDB_API CatalogEntry *CreateTable(CatalogTransaction transaction, BoundCreateTableInfo *info); + DUCKDB_API CatalogEntry *CreateTable(ClientContext &context, BoundCreateTableInfo *info); + //! Creates a table in the catalog. + DUCKDB_API CatalogEntry *CreateTable(ClientContext &context, unique_ptr info); + //! Create a table function in the catalog + DUCKDB_API CatalogEntry *CreateTableFunction(CatalogTransaction transaction, CreateTableFunctionInfo *info); + DUCKDB_API CatalogEntry *CreateTableFunction(ClientContext &context, CreateTableFunctionInfo *info); + //! Create a copy function in the catalog + DUCKDB_API CatalogEntry *CreateCopyFunction(CatalogTransaction transaction, CreateCopyFunctionInfo *info); + DUCKDB_API CatalogEntry *CreateCopyFunction(ClientContext &context, CreateCopyFunctionInfo *info); + //! Create a pragma function in the catalog + DUCKDB_API CatalogEntry *CreatePragmaFunction(CatalogTransaction transaction, CreatePragmaFunctionInfo *info); + DUCKDB_API CatalogEntry *CreatePragmaFunction(ClientContext &context, CreatePragmaFunctionInfo *info); + //! Create a scalar or aggregate function in the catalog + DUCKDB_API CatalogEntry *CreateFunction(CatalogTransaction transaction, CreateFunctionInfo *info); + DUCKDB_API CatalogEntry *CreateFunction(ClientContext &context, CreateFunctionInfo *info); + //! Creates a table in the catalog. + DUCKDB_API CatalogEntry *CreateView(CatalogTransaction transaction, CreateViewInfo *info); + DUCKDB_API CatalogEntry *CreateView(ClientContext &context, CreateViewInfo *info); + //! Creates a sequence in the catalog. + DUCKDB_API CatalogEntry *CreateSequence(CatalogTransaction transaction, CreateSequenceInfo *info); + DUCKDB_API CatalogEntry *CreateSequence(ClientContext &context, CreateSequenceInfo *info); + //! Creates a Enum in the catalog. + DUCKDB_API CatalogEntry *CreateType(CatalogTransaction transaction, CreateTypeInfo *info); + DUCKDB_API CatalogEntry *CreateType(ClientContext &context, CreateTypeInfo *info); + //! Creates a collation in the catalog + DUCKDB_API CatalogEntry *CreateCollation(CatalogTransaction transaction, CreateCollationInfo *info); + DUCKDB_API CatalogEntry *CreateCollation(ClientContext &context, CreateCollationInfo *info); + + //! Creates a table in the catalog. + DUCKDB_API CatalogEntry *CreateTable(CatalogTransaction transaction, SchemaCatalogEntry *schema, + BoundCreateTableInfo *info); + //! Create a table function in the catalog + DUCKDB_API CatalogEntry *CreateTableFunction(CatalogTransaction transaction, SchemaCatalogEntry *schema, + CreateTableFunctionInfo *info); + //! Create a copy function in the catalog + DUCKDB_API CatalogEntry *CreateCopyFunction(CatalogTransaction transaction, SchemaCatalogEntry *schema, + CreateCopyFunctionInfo *info); + //! Create a pragma function in the catalog + DUCKDB_API CatalogEntry *CreatePragmaFunction(CatalogTransaction transaction, SchemaCatalogEntry *schema, + CreatePragmaFunctionInfo *info); + //! Create a scalar or aggregate function in the catalog + DUCKDB_API CatalogEntry *CreateFunction(CatalogTransaction transaction, SchemaCatalogEntry *schema, + CreateFunctionInfo *info); + //! Creates a table in the catalog. + DUCKDB_API CatalogEntry *CreateView(CatalogTransaction transaction, SchemaCatalogEntry *schema, + CreateViewInfo *info); + //! Creates a table in the catalog. + DUCKDB_API CatalogEntry *CreateSequence(CatalogTransaction transaction, SchemaCatalogEntry *schema, + CreateSequenceInfo *info); + //! Creates a enum in the catalog. + DUCKDB_API CatalogEntry *CreateType(CatalogTransaction transaction, SchemaCatalogEntry *schema, + CreateTypeInfo *info); + //! Creates a collation in the catalog + DUCKDB_API CatalogEntry *CreateCollation(CatalogTransaction transaction, SchemaCatalogEntry *schema, + CreateCollationInfo *info); + + //! Drops an entry from the catalog + DUCKDB_API void DropEntry(ClientContext &context, DropInfo *info); + + //! Returns the schema object with the specified name, or throws an exception if it does not exist + DUCKDB_API SchemaCatalogEntry *GetSchema(ClientContext &context, const string &name = DEFAULT_SCHEMA, + bool if_exists = false, + QueryErrorContext error_context = QueryErrorContext()); + DUCKDB_API virtual SchemaCatalogEntry *GetSchema(CatalogTransaction transaction, const string &schema_name, + bool if_exists = false, + QueryErrorContext error_context = QueryErrorContext()) = 0; + DUCKDB_API static SchemaCatalogEntry *GetSchema(ClientContext &context, const string &catalog_name, + const string &schema_name, bool if_exists = false, + QueryErrorContext error_context = QueryErrorContext()); + //! Scans all the schemas in the system one-by-one, invoking the callback for each entry + DUCKDB_API virtual void ScanSchemas(ClientContext &context, std::function callback) = 0; + //! Gets the "schema.name" entry of the specified type, if if_exists=true returns nullptr if entry does not + //! exist, otherwise an exception is thrown + DUCKDB_API CatalogEntry *GetEntry(ClientContext &context, CatalogType type, const string &schema, + const string &name, bool if_exists = false, + QueryErrorContext error_context = QueryErrorContext()); + //! Gets the "catalog.schema.name" entry of the specified type, if if_exists=true returns nullptr if entry does not + //! exist, otherwise an exception is thrown + DUCKDB_API static CatalogEntry *GetEntry(ClientContext &context, CatalogType type, const string &catalog, + const string &schema, const string &name, bool if_exists = false, + QueryErrorContext error_context = QueryErrorContext()); + + //! Gets the "schema.name" entry without a specified type, if entry does not exist an exception is thrown + DUCKDB_API CatalogEntry *GetEntry(ClientContext &context, const string &schema, const string &name); + + //! Fetches a logical type from the catalog + DUCKDB_API LogicalType GetType(ClientContext &context, const string &schema, const string &names, bool if_exists); + + DUCKDB_API static LogicalType GetType(ClientContext &context, const string &catalog_name, const string &schema, + const string &name); + + template + T *GetEntry(ClientContext &context, const string &schema_name, const string &name, bool if_exists = false, + QueryErrorContext error_context = QueryErrorContext()) { + auto entry = GetEntry(context, T::Type, schema_name, name, if_exists, error_context); + if (entry && entry->type != T::Type) { + throw CatalogException(error_context.FormatError("%s is not an %s", name, T::Name)); + } + return (T *)entry; + } -private: - class ColumnDataChunkIterator; + //! Append a scalar or aggregate function to the catalog + DUCKDB_API CatalogEntry *AddFunction(ClientContext &context, CreateFunctionInfo *info); - class ColumnDataChunkIterator { - public: - DUCKDB_API explicit ColumnDataChunkIterator(const ColumnDataCollection *collection_p, - vector column_ids); + //! Alter an existing entry in the catalog. + DUCKDB_API void Alter(ClientContext &context, AlterInfo *info); - const ColumnDataCollection *collection; - ColumnDataScanState scan_state; - shared_ptr scan_chunk; - idx_t row_index; + virtual unique_ptr PlanCreateTableAs(ClientContext &context, LogicalCreateTable &op, + unique_ptr plan) = 0; + virtual unique_ptr PlanInsert(ClientContext &context, LogicalInsert &op, + unique_ptr plan) = 0; + virtual unique_ptr PlanDelete(ClientContext &context, LogicalDelete &op, + unique_ptr plan) = 0; + virtual unique_ptr PlanUpdate(ClientContext &context, LogicalUpdate &op, + unique_ptr plan) = 0; + virtual unique_ptr BindCreateIndex(Binder &binder, CreateStatement &stmt, TableCatalogEntry &table, + unique_ptr plan) = 0; - public: - DUCKDB_API void Next(); + virtual DatabaseSize GetDatabaseSize(ClientContext &context) = 0; - DUCKDB_API ColumnDataChunkIterator &operator++(); - DUCKDB_API bool operator!=(const ColumnDataChunkIterator &other) const; - DUCKDB_API DataChunk &operator*() const; - }; + virtual bool InMemory() = 0; + virtual string GetDBPath() = 0; public: - DUCKDB_API ColumnDataChunkIterator begin() { - return ColumnDataChunkIterator(&collection, column_ids); - } - DUCKDB_API ColumnDataChunkIterator end() { - return ColumnDataChunkIterator(nullptr, vector()); + template + static T *GetEntry(ClientContext &context, const string &catalog_name, const string &schema_name, + const string &name, bool if_exists = false, + QueryErrorContext error_context = QueryErrorContext()) { + auto entry = GetEntry(context, T::Type, catalog_name, schema_name, name, if_exists, error_context); + if (entry && entry->type != T::Type) { + throw CatalogException(error_context.FormatError("%s is not an %s", name, T::Name)); + } + return (T *)entry; } -}; - -class ColumnDataRowIterationHelper { -public: - DUCKDB_API ColumnDataRowIterationHelper(const ColumnDataCollection &collection); -private: - const ColumnDataCollection &collection; + DUCKDB_API vector GetSchemas(ClientContext &context); + DUCKDB_API static vector GetSchemas(ClientContext &context, const string &catalog_name); + DUCKDB_API static vector GetAllSchemas(ClientContext &context); -private: - class ColumnDataRowIterator; + virtual void Verify(); - class ColumnDataRowIterator { - public: - DUCKDB_API explicit ColumnDataRowIterator(const ColumnDataCollection *collection_p); +protected: + //! Reference to the database + AttachedDatabase &db; - const ColumnDataCollection *collection; - ColumnDataScanState scan_state; - shared_ptr scan_chunk; - ColumnDataRow current_row; +private: + CatalogEntryLookup LookupEntryInternal(CatalogTransaction transaction, CatalogType type, const string &schema, + const string &name); + CatalogEntryLookup LookupEntry(ClientContext &context, CatalogType type, const string &schema, const string &name, + bool if_exists = false, QueryErrorContext error_context = QueryErrorContext()); + static CatalogEntryLookup LookupEntry(ClientContext &context, vector &lookups, CatalogType type, + const string &name, bool if_exists = false, + QueryErrorContext error_context = QueryErrorContext()); - public: - void Next(); + //! Return an exception with did-you-mean suggestion. + static CatalogException CreateMissingEntryException(ClientContext &context, const string &entry_name, + CatalogType type, + const unordered_set &schemas, + QueryErrorContext error_context); - DUCKDB_API ColumnDataRowIterator &operator++(); - DUCKDB_API bool operator!=(const ColumnDataRowIterator &other) const; - DUCKDB_API const ColumnDataRow &operator*() const; - }; + //! Return the close entry name, the distance and the belonging schema. + static SimilarCatalogEntry SimilarEntryInSchemas(ClientContext &context, const string &entry_name, CatalogType type, + const unordered_set &schemas); -public: - DUCKDB_API ColumnDataRowIterator begin(); - DUCKDB_API ColumnDataRowIterator end(); + virtual void DropSchema(ClientContext &context, DropInfo *info) = 0; }; } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/operator_result_type.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + namespace duckdb { -class BufferManager; -class BlockHandle; -class ClientContext; -struct ColumnDataCopyFunction; -class ColumnDataAllocator; -class ColumnDataCollection; -class ColumnDataCollectionSegment; -class ColumnDataRowCollection; -//! The ColumnDataCollection represents a set of (buffer-managed) data stored in columnar format -//! It is efficient to read and scan -class ColumnDataCollection { -public: - //! Constructs an in-memory column data collection from an allocator - DUCKDB_API ColumnDataCollection(Allocator &allocator, vector types); - //! Constructs an empty (but valid) in-memory column data collection from an allocator - DUCKDB_API ColumnDataCollection(Allocator &allocator); - //! Constructs a buffer-managed column data collection - DUCKDB_API ColumnDataCollection(BufferManager &buffer_manager, vector types); - //! Constructs either an in-memory or a buffer-managed column data collection - DUCKDB_API ColumnDataCollection(ClientContext &context, vector types, - ColumnDataAllocatorType type = ColumnDataAllocatorType::BUFFER_MANAGER_ALLOCATOR); - //! Creates a column data collection that inherits the blocks to write to. This allows blocks to be shared - //! between multiple column data collections and prevents wasting space. - //! Note that after one CDC inherits blocks from another, the other - //! cannot be written to anymore (i.e. we take ownership of the half-written blocks). - DUCKDB_API ColumnDataCollection(ColumnDataCollection &parent); - DUCKDB_API ColumnDataCollection(shared_ptr allocator, vector types); - DUCKDB_API ~ColumnDataCollection(); +//! The OperatorResultType is used to indicate how data should flow around a regular (i.e. non-sink and non-source) +//! physical operator +//! There are three possible results: +//! NEED_MORE_INPUT means the operator is done with the current input and can consume more input if available +//! If there is more input the operator will be called with more input, otherwise the operator will not be called again. +//! HAVE_MORE_OUTPUT means the operator is not finished yet with the current input. +//! The operator will be called again with the same input. +//! FINISHED means the operator has finished the entire pipeline and no more processing is necessary. +//! The operator will not be called again, and neither will any other operators in this pipeline. +enum class OperatorResultType : uint8_t { NEED_MORE_INPUT, HAVE_MORE_OUTPUT, FINISHED }; -public: - //! The types of columns in the ColumnDataCollection - DUCKDB_API vector &Types() { - return types; - } - DUCKDB_API const vector &Types() const { - return types; - } +//! OperatorFinalizeResultType is used to indicate whether operators have finished flushing their cached results. +//! FINISHED means the operator has flushed all cached data. +//! HAVE_MORE_OUTPUT means the operator contains more results. +enum class OperatorFinalizeResultType : uint8_t { HAVE_MORE_OUTPUT, FINISHED }; - //! The amount of rows in the ColumnDataCollection - DUCKDB_API const idx_t &Count() const { - return count; - } +//! The SinkResultType is used to indicate the result of data flowing into a sink +//! There are two possible results: +//! NEED_MORE_INPUT means the sink needs more input +//! FINISHED means the sink is finished executing, and more input will not change the result any further +enum class SinkResultType : uint8_t { NEED_MORE_INPUT, FINISHED }; - //! The amount of columns in the ColumnDataCollection - DUCKDB_API idx_t ColumnCount() const { - return types.size(); - } +//! The SinkFinalizeType is used to indicate the result of a Finalize call on a sink +//! There are two possible results: +//! READY means the sink is ready for further processing +//! NO_OUTPUT_POSSIBLE means the sink will never provide output, and any pipelines involving the sink can be skipped +enum class SinkFinalizeType : uint8_t { READY, NO_OUTPUT_POSSIBLE }; - //! Initializes an Append state - useful for optimizing many appends made to the same column data collection - DUCKDB_API void InitializeAppend(ColumnDataAppendState &state); - //! Append a DataChunk to this ColumnDataCollection using the specified append state - DUCKDB_API void Append(ColumnDataAppendState &state, DataChunk &new_chunk); +} // namespace duckdb - //! Initializes a chunk with the correct types that can be used to call Scan - DUCKDB_API void InitializeScanChunk(DataChunk &chunk) const; - //! Initializes a chunk with the correct types for a given scan state - DUCKDB_API void InitializeScanChunk(ColumnDataScanState &state, DataChunk &chunk) const; - //! Initializes a Scan state for scanning all columns - DUCKDB_API void - InitializeScan(ColumnDataScanState &state, - ColumnDataScanProperties properties = ColumnDataScanProperties::ALLOW_ZERO_COPY) const; - //! Initializes a Scan state for scanning a subset of the columns - DUCKDB_API void - InitializeScan(ColumnDataScanState &state, vector column_ids, - ColumnDataScanProperties properties = ColumnDataScanProperties::ALLOW_ZERO_COPY) const; - //! Initialize a parallel scan over the column data collection over all columns - DUCKDB_API void - InitializeScan(ColumnDataParallelScanState &state, - ColumnDataScanProperties properties = ColumnDataScanProperties::ALLOW_ZERO_COPY) const; - //! Initialize a parallel scan over the column data collection over a subset of the columns - DUCKDB_API void - InitializeScan(ColumnDataParallelScanState &state, vector column_ids, - ColumnDataScanProperties properties = ColumnDataScanProperties::ALLOW_ZERO_COPY) const; - //! Scans a DataChunk from the ColumnDataCollection - DUCKDB_API bool Scan(ColumnDataScanState &state, DataChunk &result) const; - //! Scans a DataChunk from the ColumnDataCollection - DUCKDB_API bool Scan(ColumnDataParallelScanState &state, ColumnDataLocalScanState &lstate, DataChunk &result) const; +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/physical_operator_type.hpp +// +// +//===----------------------------------------------------------------------===// - //! Append a DataChunk directly to this ColumnDataCollection - calls InitializeAppend and Append internally - DUCKDB_API void Append(DataChunk &new_chunk); - //! Appends the other ColumnDataCollection to this, destroying the other data collection - DUCKDB_API void Combine(ColumnDataCollection &other); - DUCKDB_API void Verify(); - DUCKDB_API string ToString() const; - DUCKDB_API void Print() const; - DUCKDB_API void Reset(); +namespace duckdb { - //! Returns the number of data chunks present in the ColumnDataCollection - DUCKDB_API idx_t ChunkCount() const; - //! Fetch an individual chunk from the ColumnDataCollection - DUCKDB_API void FetchChunk(idx_t chunk_idx, DataChunk &result) const; +//===--------------------------------------------------------------------===// +// Physical Operator Types +//===--------------------------------------------------------------------===// +enum class PhysicalOperatorType : uint8_t { + INVALID, + ORDER_BY, + LIMIT, + STREAMING_LIMIT, + LIMIT_PERCENT, + TOP_N, + WINDOW, + UNNEST, + UNGROUPED_AGGREGATE, + HASH_GROUP_BY, + PERFECT_HASH_GROUP_BY, + FILTER, + PROJECTION, + COPY_TO_FILE, + RESERVOIR_SAMPLE, + STREAMING_SAMPLE, + STREAMING_WINDOW, + // ----------------------------- + // Scans + // ----------------------------- + TABLE_SCAN, + DUMMY_SCAN, + COLUMN_DATA_SCAN, + CHUNK_SCAN, + RECURSIVE_CTE_SCAN, + DELIM_SCAN, + EXPRESSION_SCAN, + POSITIONAL_SCAN, + // ----------------------------- + // Joins + // ----------------------------- + BLOCKWISE_NL_JOIN, + NESTED_LOOP_JOIN, + HASH_JOIN, + CROSS_PRODUCT, + PIECEWISE_MERGE_JOIN, + IE_JOIN, + DELIM_JOIN, + INDEX_JOIN, + POSITIONAL_JOIN, + // ----------------------------- + // SetOps + // ----------------------------- + UNION, + RECURSIVE_CTE, + + // ----------------------------- + // Updates + // ----------------------------- + INSERT, + BATCH_INSERT, + DELETE_OPERATOR, + UPDATE, + + // ----------------------------- + // Schema + // ----------------------------- + CREATE_TABLE, + CREATE_TABLE_AS, + BATCH_CREATE_TABLE_AS, + CREATE_INDEX, + ALTER, + CREATE_SEQUENCE, + CREATE_VIEW, + CREATE_SCHEMA, + CREATE_MACRO, + DROP, + PRAGMA, + TRANSACTION, + CREATE_TYPE, + ATTACH, - //! Constructs a class that can be iterated over to fetch individual chunks - //! Iterating over this is syntactic sugar over just calling Scan - DUCKDB_API ColumnDataChunkIterationHelper Chunks() const; - //! Constructs a class that can be iterated over to fetch individual chunks - //! Only the column indexes specified in the column_ids list are scanned - DUCKDB_API ColumnDataChunkIterationHelper Chunks(vector column_ids) const; + // ----------------------------- + // Helpers + // ----------------------------- + EXPLAIN, + EXPLAIN_ANALYZE, + EMPTY_RESULT, + EXECUTE, + PREPARE, + VACUUM, + EXPORT, + SET, + LOAD, + INOUT_FUNCTION, + RESULT_COLLECTOR, + RESET, + EXTENSION +}; - //! Constructs a class that can be iterated over to fetch individual rows - //! Note that row iteration is slow, and the `.Chunks()` method should be used instead - DUCKDB_API ColumnDataRowIterationHelper Rows() const; +string PhysicalOperatorToString(PhysicalOperatorType type); - //! Returns a materialized set of all of the rows in the column data collection - //! Note that usage of this is slow - avoid using this unless the amount of rows is small, or if you do not care - //! about performance - DUCKDB_API ColumnDataRowCollection GetRows() const; +} // namespace duckdb - //! Compare two column data collections to another. If they are equal according to result equality rules, - //! return true. That means null values are equal, and approx equality is used for floating point values. - //! If they are not equal, return false and fill in the error message. - static bool ResultEquals(const ColumnDataCollection &left, const ColumnDataCollection &right, - string &error_message); - //! Obtains the next scan index to scan from - bool NextScanIndex(ColumnDataScanState &state, idx_t &chunk_index, idx_t &segment_index, idx_t &row_index) const; - //! Scans at the indices (obtained from NextScanIndex) - void ScanAtIndex(ColumnDataParallelScanState &state, ColumnDataLocalScanState &lstate, DataChunk &result, - idx_t chunk_index, idx_t segment_index, idx_t row_index) const; +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/execution/execution_context.hpp +// +// +//===----------------------------------------------------------------------===// - //! Initialize the column data collection - void Initialize(vector types); - //! Get a vector of references to every chunk (segment, index in segment), and optionally sort by block id - const vector> &GetSegments() const; -private: - //! Creates a new segment within the ColumnDataCollection - void CreateSegment(); - static ColumnDataCopyFunction GetCopyFunction(const LogicalType &type); -private: - //! The Column Data Allocator - buffer_ptr allocator; - //! The types of the stored entries - vector types; - //! The number of entries stored in the column data collection - idx_t count; - //! The data segments of the column data collection - vector> segments; - //! The set of copy functions - vector copy_functions; - //! When the column data collection is marked as finished - new tuples can no longer be appended to it - bool finished_append; -}; +namespace duckdb { +class ClientContext; +class ThreadContext; +class Pipeline; -//! The ColumnDataRowCollection represents a set of materialized rows, as obtained from the ColumnDataCollection -class ColumnDataRowCollection { +class ExecutionContext { public: - DUCKDB_API ColumnDataRowCollection(const ColumnDataCollection &collection); + ExecutionContext(ClientContext &client_p, ThreadContext &thread_p, Pipeline *pipeline_p) + : client(client_p), thread(thread_p), pipeline(pipeline_p) { + } -public: - DUCKDB_API Value GetValue(idx_t column, idx_t index) const; + //! The client-global context; caution needs to be taken when used in parallel situations + ClientContext &client; + //! The thread-local context for this execution + ThreadContext &thread; + //! Reference to the pipeline for this execution, can be used for example by operators determine caching strategy + Pipeline *pipeline; +}; -public: - // container API - DUCKDB_API bool empty() const { - return rows.empty(); - } - DUCKDB_API idx_t size() const { - return rows.size(); - } +} // namespace duckdb - DUCKDB_API ColumnDataRow &operator[](idx_t i); - DUCKDB_API const ColumnDataRow &operator[](idx_t i) const; +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/join_order/join_node.hpp +// +// +//===----------------------------------------------------------------------===// - DUCKDB_API vector::iterator begin() { - return rows.begin(); - } - DUCKDB_API vector::iterator end() { - return rows.end(); - } - DUCKDB_API vector::const_iterator cbegin() const { - return rows.cbegin(); - } - DUCKDB_API vector::const_iterator cend() const { - return rows.cend(); - } - DUCKDB_API vector::const_iterator begin() const { - return rows.begin(); - } - DUCKDB_API vector::const_iterator end() const { - return rows.end(); - } -private: - vector rows; - vector> chunks; - ColumnDataScanState scan_state; -}; -} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/query_result.hpp +// duckdb/optimizer/join_order/estimated_properties.hpp // // //===----------------------------------------------------------------------===// + + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/enums/statement_type.hpp +// duckdb/optimizer/join_order/join_relation.hpp // // //===----------------------------------------------------------------------===// @@ -12863,307 +12081,278 @@ class ColumnDataRowCollection { + + namespace duckdb { +class LogicalOperator; -//===--------------------------------------------------------------------===// -// Statement Types -//===--------------------------------------------------------------------===// -enum class StatementType : uint8_t { - INVALID_STATEMENT, // invalid statement type - SELECT_STATEMENT, // select statement type - INSERT_STATEMENT, // insert statement type - UPDATE_STATEMENT, // update statement type - CREATE_STATEMENT, // create statement type - DELETE_STATEMENT, // delete statement type - PREPARE_STATEMENT, // prepare statement type - EXECUTE_STATEMENT, // execute statement type - ALTER_STATEMENT, // alter statement type - TRANSACTION_STATEMENT, // transaction statement type, - COPY_STATEMENT, // copy type - ANALYZE_STATEMENT, // analyze type - VARIABLE_SET_STATEMENT, // variable set statement type - CREATE_FUNC_STATEMENT, // create func statement type - EXPLAIN_STATEMENT, // explain statement type - DROP_STATEMENT, // DROP statement type - EXPORT_STATEMENT, // EXPORT statement type - PRAGMA_STATEMENT, // PRAGMA statement type - SHOW_STATEMENT, // SHOW statement type - VACUUM_STATEMENT, // VACUUM statement type - CALL_STATEMENT, // CALL statement type - SET_STATEMENT, // SET statement type - LOAD_STATEMENT, // LOAD statement type - RELATION_STATEMENT, - EXTENSION_STATEMENT, - LOGICAL_PLAN_STATEMENT +//! Represents a single relation and any metadata accompanying that relation +struct SingleJoinRelation { + LogicalOperator *op; + LogicalOperator *parent; + SingleJoinRelation() { + } + SingleJoinRelation(LogicalOperator *op, LogicalOperator *parent) : op(op), parent(parent) { + } }; -string StatementTypeToString(StatementType type); +//! Set of relations, used in the join graph. +struct JoinRelationSet { + JoinRelationSet(unique_ptr relations, idx_t count) : relations(std::move(relations)), count(count) { + } -enum class StatementReturnType : uint8_t { - QUERY_RESULT, // the statement returns a query result (e.g. for display to the user) - CHANGED_ROWS, // the statement returns a single row containing the number of changed rows (e.g. an insert stmt) - NOTHING // the statement returns nothing + string ToString() const; + + unique_ptr relations; + idx_t count; + + static bool IsSubset(JoinRelationSet *super, JoinRelationSet *sub); }; -string StatementReturnTypeToString(StatementReturnType type); +//! The JoinRelationTree is a structure holding all the created JoinRelationSet objects and allowing fast lookup on to +//! them +class JoinRelationSetManager { +public: + //! Contains a node with a JoinRelationSet and child relations + // FIXME: this structure is inefficient, could use a bitmap for lookup instead (todo: profile) + struct JoinRelationTreeNode { + unique_ptr relation; + unordered_map> children; + }; -//! A struct containing various properties of a SQL statement -struct StatementProperties { - StatementProperties() - : read_only(true), requires_valid_transaction(true), allow_stream_result(false), bound_all_parameters(true), - return_type(StatementReturnType::QUERY_RESULT), parameter_count(0) { - } +public: + //! Create or get a JoinRelationSet from a single node with the given index + JoinRelationSet *GetJoinRelation(idx_t index); + //! Create or get a JoinRelationSet from a set of relation bindings + JoinRelationSet *GetJoinRelation(unordered_set &bindings); + //! Create or get a JoinRelationSet from a (sorted, duplicate-free!) list of relations + JoinRelationSet *GetJoinRelation(unique_ptr relations, idx_t count); + //! Union two sets of relations together and create a new relation set + JoinRelationSet *Union(JoinRelationSet *left, JoinRelationSet *right); + // //! Create the set difference of left \ right (i.e. all elements in left that are not in right) + // JoinRelationSet *Difference(JoinRelationSet *left, JoinRelationSet *right); - //! Whether or not the statement is a read-only statement, or whether it can result in changes to the database - bool read_only; - //! Whether or not the statement requires a valid transaction. Almost all statements require this, with the - //! exception of - bool requires_valid_transaction; - //! Whether or not the result can be streamed to the client - bool allow_stream_result; - //! Whether or not all parameters have successfully had their types determined - bool bound_all_parameters; - //! What type of data the statement returns - StatementReturnType return_type; - //! The number of prepared statement parameters - idx_t parameter_count; +private: + JoinRelationTreeNode root; }; } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/expression_map.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + +namespace duckdb { +class Expression; + +struct ExpressionHashFunction { + uint64_t operator()(const BaseExpression *const &expr) const { + return (uint64_t)expr->Hash(); + } +}; +struct ExpressionEquality { + bool operator()(const BaseExpression *const &a, const BaseExpression *const &b) const { + return a->Equals(b); + } +}; +template +using expression_map_t = unordered_map; +using expression_set_t = unordered_set; -namespace duckdb { +} // namespace duckdb -enum class QueryResultType : uint8_t { MATERIALIZED_RESULT, STREAM_RESULT, PENDING_RESULT }; +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/logical_operator_visitor.hpp +// +// +//===----------------------------------------------------------------------===// -//! A set of properties from the client context that can be used to interpret the query result -struct ClientProperties { - string timezone; -}; -class BaseQueryResult { -public: - //! Creates a successful query result with the specified names and types - DUCKDB_API BaseQueryResult(QueryResultType type, StatementType statement_type, StatementProperties properties, - vector types, vector names); - //! Creates an unsuccessful query result with error condition - DUCKDB_API BaseQueryResult(QueryResultType type, PreservedError error); - DUCKDB_API virtual ~BaseQueryResult(); - //! The type of the result (MATERIALIZED or STREAMING) - QueryResultType type; - //! The type of the statement that created this result - StatementType statement_type; - //! Properties of the statement - StatementProperties properties; - //! The SQL types of the result - vector types; - //! The names of the result - vector names; -public: - DUCKDB_API void ThrowError(const string &prepended_message = "") const; - DUCKDB_API void SetError(PreservedError error); - DUCKDB_API bool HasError() const; - DUCKDB_API const ExceptionType &GetErrorType() const; - DUCKDB_API const std::string &GetError(); - DUCKDB_API PreservedError &GetErrorObject(); - DUCKDB_API idx_t ColumnCount(); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/bound_tokens.hpp +// +// +//===----------------------------------------------------------------------===// -protected: - //! Whether or not execution was successful - bool success; - //! The error (in case execution was not successful) - PreservedError error; -}; -//! The QueryResult object holds the result of a query. It can either be a MaterializedQueryResult, in which case the -//! result contains the entire result set, or a StreamQueryResult in which case the Fetch method can be called to -//! incrementally fetch data from the database. -class QueryResult : public BaseQueryResult { -public: - //! Creates a successful query result with the specified names and types - DUCKDB_API QueryResult(QueryResultType type, StatementType statement_type, StatementProperties properties, - vector types, vector names, ClientProperties client_properties); - //! Creates an unsuccessful query result with error condition - DUCKDB_API QueryResult(QueryResultType type, PreservedError error); - DUCKDB_API virtual ~QueryResult() override; - //! Properties from the client context - ClientProperties client_properties; - //! The next result (if any) - unique_ptr next; +namespace duckdb { -public: - //! Fetches a DataChunk of normalized (flat) vectors from the query result. - //! Returns nullptr if there are no more results to fetch. - DUCKDB_API virtual unique_ptr Fetch(); - //! Fetches a DataChunk from the query result. The vectors are not normalized and hence any vector types can be - //! returned. - DUCKDB_API virtual unique_ptr FetchRaw() = 0; - //! Converts the QueryResult to a string - DUCKDB_API virtual string ToString() = 0; - //! Prints the QueryResult to the console - DUCKDB_API void Print(); - //! Returns true if the two results are identical; false otherwise. Note that this method is destructive; it calls - //! Fetch() until both results are exhausted. The data in the results will be lost. - DUCKDB_API bool Equals(QueryResult &other); +//===--------------------------------------------------------------------===// +// Query Node +//===--------------------------------------------------------------------===// +class BoundQueryNode; +class BoundSelectNode; +class BoundSetOperationNode; +class BoundRecursiveCTENode; - DUCKDB_API bool TryFetch(unique_ptr &result, PreservedError &error) { - try { - result = Fetch(); - return success; - } catch (const Exception &ex) { - error = PreservedError(ex); - return false; - } catch (std::exception &ex) { - error = PreservedError(ex); - return false; - } catch (...) { - error = PreservedError("Unknown error in Fetch"); - return false; - } - } +//===--------------------------------------------------------------------===// +// Expressions +//===--------------------------------------------------------------------===// +class Expression; - static string GetConfigTimezone(QueryResult &query_result); +class BoundAggregateExpression; +class BoundBetweenExpression; +class BoundCaseExpression; +class BoundCastExpression; +class BoundColumnRefExpression; +class BoundComparisonExpression; +class BoundConjunctionExpression; +class BoundConstantExpression; +class BoundDefaultExpression; +class BoundFunctionExpression; +class BoundOperatorExpression; +class BoundParameterExpression; +class BoundReferenceExpression; +class BoundSubqueryExpression; +class BoundUnnestExpression; +class BoundWindowExpression; -private: - class QueryResultIterator; - class QueryResultRow { - public: - explicit QueryResultRow(QueryResultIterator &iterator_p, idx_t row_idx) : iterator(iterator_p), row(0) { - } +//===--------------------------------------------------------------------===// +// TableRefs +//===--------------------------------------------------------------------===// +class BoundTableRef; - QueryResultIterator &iterator; - idx_t row; +class BoundBaseTableRef; +class BoundJoinRef; +class BoundSubqueryRef; +class BoundTableFunction; +class BoundEmptyTableRef; +class BoundExpressionListRef; +class BoundCTERef; - template - T GetValue(idx_t col_idx) const { - return iterator.chunk->GetValue(col_idx, row).GetValue(); - } - }; - //! The row-based query result iterator. Invoking the - class QueryResultIterator { - public: - explicit QueryResultIterator(QueryResult *result_p) : current_row(*this, 0), result(result_p), base_row(0) { - if (result) { - chunk = shared_ptr(result->Fetch().release()); - if (!chunk) { - result = nullptr; - } - } - } +} // namespace duckdb - QueryResultRow current_row; - shared_ptr chunk; - QueryResult *result; - idx_t base_row; +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/logical_tokens.hpp +// +// +//===----------------------------------------------------------------------===// - public: - void Next() { - if (!chunk) { - return; - } - current_row.row++; - if (current_row.row >= chunk->size()) { - base_row += chunk->size(); - chunk = result->Fetch(); - current_row.row = 0; - if (!chunk || chunk->size() == 0) { - // exhausted all rows - base_row = 0; - result = nullptr; - chunk.reset(); - } - } - } - QueryResultIterator &operator++() { - Next(); - return *this; - } - bool operator!=(const QueryResultIterator &other) const { - return result != other.result || base_row != other.base_row || current_row.row != other.current_row.row; - } - const QueryResultRow &operator*() const { - return current_row; - } - }; -public: - DUCKDB_API QueryResultIterator begin() { - return QueryResultIterator(this); - } - DUCKDB_API QueryResultIterator end() { - return QueryResultIterator(nullptr); - } +namespace duckdb { -protected: - DUCKDB_API string HeaderToString(); +class LogicalOperator; -private: - QueryResult(const QueryResult &) = delete; -}; +class LogicalAggregate; +class LogicalAnyJoin; +class LogicalColumnDataGet; +class LogicalComparisonJoin; +class LogicalCopyToFile; +class LogicalCreate; +class LogicalCreateTable; +class LogicalCreateIndex; +class LogicalCreateTable; +class LogicalCrossProduct; +class LogicalCTERef; +class LogicalDelete; +class LogicalDelimGet; +class LogicalDelimJoin; +class LogicalDistinct; +class LogicalDummyScan; +class LogicalEmptyResult; +class LogicalExecute; +class LogicalExplain; +class LogicalExport; +class LogicalExpressionGet; +class LogicalFilter; +class LogicalGet; +class LogicalInsert; +class LogicalJoin; +class LogicalLimit; +class LogicalOrder; +class LogicalPositionalJoin; +class LogicalPragma; +class LogicalPrepare; +class LogicalProjection; +class LogicalRecursiveCTE; +class LogicalSetOperation; +class LogicalSample; +class LogicalShow; +class LogicalSimple; +class LogicalSet; +class LogicalReset; +class LogicalTopN; +class LogicalUnnest; +class LogicalUpdate; +class LogicalWindow; } // namespace duckdb -namespace duckdb { - -class ClientContext; - -class MaterializedQueryResult : public QueryResult { -public: - friend class ClientContext; - //! Creates a successful query result with the specified names and types - DUCKDB_API MaterializedQueryResult(StatementType statement_type, StatementProperties properties, - vector names, unique_ptr collection, - ClientProperties client_properties); - //! Creates an unsuccessful query result with error condition - DUCKDB_API explicit MaterializedQueryResult(PreservedError error); +#include +namespace duckdb { +//! The LogicalOperatorVisitor is an abstract base class that implements the +//! Visitor pattern on LogicalOperator. +class LogicalOperatorVisitor { public: - //! Fetches a DataChunk from the query result. - //! This will consume the result (i.e. the result can only be scanned once with this function) - DUCKDB_API unique_ptr Fetch() override; - DUCKDB_API unique_ptr FetchRaw() override; - //! Converts the QueryResult to a string - DUCKDB_API string ToString() override; + virtual ~LogicalOperatorVisitor() {}; - //! Gets the (index) value of the (column index) column. - //! Note: this is very slow. Scanning over the underlying collection is much faster. - DUCKDB_API Value GetValue(idx_t column, idx_t index); + virtual void VisitOperator(LogicalOperator &op); + virtual void VisitExpression(unique_ptr *expression); - template - T GetValue(idx_t column, idx_t index) { - auto value = GetValue(column, index); - return (T)value.GetValue(); - } + static void EnumerateExpressions(LogicalOperator &op, + const std::function *child)> &callback); - DUCKDB_API idx_t RowCount() const; +protected: + //! Automatically calls the Visit method for LogicalOperator children of the current operator. Can be overloaded to + //! change this behavior. + void VisitOperatorChildren(LogicalOperator &op); + //! Automatically calls the Visit method for Expression children of the current operator. Can be overloaded to + //! change this behavior. + void VisitOperatorExpressions(LogicalOperator &op); - //! Returns a reference to the underlying column data collection - ColumnDataCollection &Collection(); + // The VisitExpressionChildren method is called at the end of every call to VisitExpression to recursively visit all + // expressions in an expression tree. It can be overloaded to prevent automatically visiting the entire tree. + virtual void VisitExpressionChildren(Expression &expression); -private: - unique_ptr collection; - //! Row collection, only created if GetValue is called - unique_ptr row_collection; - //! Scan state for Fetch calls - ColumnDataScanState scan_state; - bool scan_initialized; + virtual unique_ptr VisitReplace(BoundAggregateExpression &expr, unique_ptr *expr_ptr); + virtual unique_ptr VisitReplace(BoundBetweenExpression &expr, unique_ptr *expr_ptr); + virtual unique_ptr VisitReplace(BoundCaseExpression &expr, unique_ptr *expr_ptr); + virtual unique_ptr VisitReplace(BoundCastExpression &expr, unique_ptr *expr_ptr); + virtual unique_ptr VisitReplace(BoundColumnRefExpression &expr, unique_ptr *expr_ptr); + virtual unique_ptr VisitReplace(BoundComparisonExpression &expr, unique_ptr *expr_ptr); + virtual unique_ptr VisitReplace(BoundConjunctionExpression &expr, unique_ptr *expr_ptr); + virtual unique_ptr VisitReplace(BoundConstantExpression &expr, unique_ptr *expr_ptr); + virtual unique_ptr VisitReplace(BoundDefaultExpression &expr, unique_ptr *expr_ptr); + virtual unique_ptr VisitReplace(BoundFunctionExpression &expr, unique_ptr *expr_ptr); + virtual unique_ptr VisitReplace(BoundOperatorExpression &expr, unique_ptr *expr_ptr); + virtual unique_ptr VisitReplace(BoundReferenceExpression &expr, unique_ptr *expr_ptr); + virtual unique_ptr VisitReplace(BoundSubqueryExpression &expr, unique_ptr *expr_ptr); + virtual unique_ptr VisitReplace(BoundParameterExpression &expr, unique_ptr *expr_ptr); + virtual unique_ptr VisitReplace(BoundWindowExpression &expr, unique_ptr *expr_ptr); + virtual unique_ptr VisitReplace(BoundUnnestExpression &expr, unique_ptr *expr_ptr); }; - } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/pending_query_result.hpp +// duckdb/storage/statistics/distinct_statistics.hpp // // //===----------------------------------------------------------------------===// @@ -13174,7 +12363,7 @@ class MaterializedQueryResult : public QueryResult { //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/enums/pending_execution_result.hpp +// duckdb/common/types/hyperloglog.hpp // // //===----------------------------------------------------------------------===// @@ -13183,99 +12372,182 @@ class MaterializedQueryResult : public QueryResult { -namespace duckdb { -enum class PendingExecutionResult : uint8_t { RESULT_READY, RESULT_NOT_READY, EXECUTION_ERROR }; -} // namespace duckdb +// LICENSE_CHANGE_BEGIN +// The following code up to LICENSE_CHANGE_END is subject to THIRD PARTY LICENSE #1 +// See the end of this file for a list //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/execution/executor.hpp +// third_party/hyperloglog/hyperloglog.hpp // // //===----------------------------------------------------------------------===// +#include +#include +namespace duckdb_hll { +/* Error codes */ +#define HLL_C_OK 0 +#define HLL_C_ERR -1 +typedef struct { + void *ptr; +} robj; +//! Create a new empty HyperLogLog object +robj *hll_create(void); +//! Convert hll from sparse to dense +int hllSparseToDense(robj *o); +//! Destroy the specified HyperLogLog object +void hll_destroy(robj *obj); +//! Add an element with the specified amount of bytes to the HyperLogLog. Returns C_ERR on failure, otherwise returns 0 +//! if the cardinality did not change, and 1 otherwise. +int hll_add(robj *o, unsigned char *ele, size_t elesize); +//! Returns the estimated amount of unique elements seen by the HyperLogLog. Returns C_OK on success, or C_ERR on +//! failure. +int hll_count(robj *o, size_t *result); +//! Merge hll_count HyperLogLog objects into a single one. Returns NULL on failure, or the new HLL object on success. +robj *hll_merge(robj **hlls, size_t hll_count); +//! Get size (in bytes) of the HLL +uint64_t get_size(); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parallel/pipeline.hpp -// -// -//===----------------------------------------------------------------------===// +uint64_t MurmurHash64A(const void *key, int len, unsigned int seed); +} // namespace duckdb_hll +namespace duckdb { +void AddToLogsInternal(UnifiedVectorFormat &vdata, idx_t count, uint64_t indices[], uint8_t counts[], void ***logs[], + const SelectionVector *log_sel); +void AddToSingleLogInternal(UnifiedVectorFormat &vdata, idx_t count, uint64_t indices[], uint8_t counts[], void *log); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/execution/physical_operator.hpp -// -// -//===----------------------------------------------------------------------===// +} // namespace duckdb + + +// LICENSE_CHANGE_END +namespace duckdb { +enum class HLLStorageType { UNCOMPRESSED = 1 }; +class FieldWriter; +class FieldReader; -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/enums/operator_result_type.hpp -// -// -//===----------------------------------------------------------------------===// +//! The HyperLogLog class holds a HyperLogLog counter for approximate cardinality counting +class HyperLogLog { +public: + HyperLogLog(); + ~HyperLogLog(); + // implicit copying of HyperLogLog is not allowed + HyperLogLog(const HyperLogLog &) = delete; + + //! Adds an element of the specified size to the HyperLogLog counter + void Add(data_ptr_t element, idx_t size); + //! Return the count of this HyperLogLog counter + idx_t Count() const; + //! Merge this HyperLogLog counter with another counter to create a new one + unique_ptr Merge(HyperLogLog &other); + HyperLogLog *MergePointer(HyperLogLog &other); + //! Merge a set of HyperLogLogs to create one big one + static unique_ptr Merge(HyperLogLog logs[], idx_t count); + //! Get the size (in bytes) of a HLL + static idx_t GetSize(); + //! Get pointer to the HLL + data_ptr_t GetPtr() const; + //! Get copy of the HLL + unique_ptr Copy(); + //! (De)Serialize the HLL + void Serialize(FieldWriter &writer) const; + static unique_ptr Deserialize(FieldReader &reader); + +public: + //! Compute HLL hashes over vdata, and store them in 'hashes' + //! Then, compute register indices and prefix lengths, and also store them in 'hashes' as a pair of uint32_t + static void ProcessEntries(UnifiedVectorFormat &vdata, const LogicalType &type, uint64_t hashes[], uint8_t counts[], + idx_t count); + //! Add the indices and counts to the logs + static void AddToLogs(UnifiedVectorFormat &vdata, idx_t count, uint64_t indices[], uint8_t counts[], + HyperLogLog **logs[], const SelectionVector *log_sel); + //! Add the indices and counts to THIS log + void AddToLog(UnifiedVectorFormat &vdata, idx_t count, uint64_t indices[], uint8_t counts[]); +private: + explicit HyperLogLog(void *hll); + void *hll; + mutex lock; +}; +} // namespace duckdb namespace duckdb { +class Serializer; +class Deserializer; +class Vector; + +class DistinctStatistics : public BaseStatistics { +public: + DistinctStatistics(); + explicit DistinctStatistics(unique_ptr log, idx_t sample_count, idx_t total_count); + + //! The HLL of the table + unique_ptr log; + //! How many values have been sampled into the HLL + atomic sample_count; + //! How many values have been inserted (before sampling) + atomic total_count; + +public: + void Merge(const BaseStatistics &other) override; + + unique_ptr Copy() const override; + + void Serialize(Serializer &serializer) const override; + void Serialize(FieldWriter &writer) const override; + + static unique_ptr Deserialize(Deserializer &source); + static unique_ptr Deserialize(FieldReader &reader); + + void Update(Vector &update, idx_t count, bool sample = true); + void Update(UnifiedVectorFormat &update_data, const LogicalType &ptype, idx_t count, bool sample = true); + + string ToString() const override; + idx_t GetCount() const; + +private: + //! For distinct statistics we sample the input to speed up insertions + static constexpr const double SAMPLE_RATE = 0.1; +}; + +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/table_filter.hpp +// +// +//===----------------------------------------------------------------------===// -//! The OperatorResultType is used to indicate how data should flow around a regular (i.e. non-sink and non-source) -//! physical operator -//! There are three possible results: -//! NEED_MORE_INPUT means the operator is done with the current input and can consume more input if available -//! If there is more input the operator will be called with more input, otherwise the operator will not be called again. -//! HAVE_MORE_OUTPUT means the operator is not finished yet with the current input. -//! The operator will be called again with the same input. -//! FINISHED means the operator has finished the entire pipeline and no more processing is necessary. -//! The operator will not be called again, and neither will any other operators in this pipeline. -enum class OperatorResultType : uint8_t { NEED_MORE_INPUT, HAVE_MORE_OUTPUT, FINISHED }; -//! OperatorFinalizeResultType is used to indicate whether operators have finished flushing their cached results. -//! FINISHED means the operator has flushed all cached data. -//! HAVE_MORE_OUTPUT means the operator contains more results. -enum class OperatorFinalizeResultType : uint8_t { HAVE_MORE_OUTPUT, FINISHED }; -//! The SinkResultType is used to indicate the result of data flowing into a sink -//! There are two possible results: -//! NEED_MORE_INPUT means the sink needs more input -//! FINISHED means the sink is finished executing, and more input will not change the result any further -enum class SinkResultType : uint8_t { NEED_MORE_INPUT, FINISHED }; -//! The SinkFinalizeType is used to indicate the result of a Finalize call on a sink -//! There are two possible results: -//! READY means the sink is ready for further processing -//! NO_OUTPUT_POSSIBLE means the sink will never provide output, and any pipelines involving the sink can be skipped -enum class SinkFinalizeType : uint8_t { READY, NO_OUTPUT_POSSIBLE }; -} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/common/enums/physical_operator_type.hpp +// duckdb/common/enums/filter_propagate_result.hpp // // //===----------------------------------------------------------------------===// @@ -13286,137 +12558,128 @@ enum class SinkFinalizeType : uint8_t { READY, NO_OUTPUT_POSSIBLE }; namespace duckdb { -//===--------------------------------------------------------------------===// -// Physical Operator Types -//===--------------------------------------------------------------------===// -enum class PhysicalOperatorType : uint8_t { - INVALID, - ORDER_BY, - LIMIT, - STREAMING_LIMIT, - LIMIT_PERCENT, - TOP_N, - WINDOW, - UNNEST, - UNGROUPED_AGGREGATE, - HASH_GROUP_BY, - PERFECT_HASH_GROUP_BY, - FILTER, - PROJECTION, - COPY_TO_FILE, - RESERVOIR_SAMPLE, - STREAMING_SAMPLE, - STREAMING_WINDOW, - // ----------------------------- - // Scans - // ----------------------------- - TABLE_SCAN, - DUMMY_SCAN, - COLUMN_DATA_SCAN, - CHUNK_SCAN, - RECURSIVE_CTE_SCAN, - DELIM_SCAN, - EXPRESSION_SCAN, - // ----------------------------- - // Joins - // ----------------------------- - BLOCKWISE_NL_JOIN, - NESTED_LOOP_JOIN, - HASH_JOIN, - CROSS_PRODUCT, - PIECEWISE_MERGE_JOIN, - IE_JOIN, - DELIM_JOIN, - INDEX_JOIN, - // ----------------------------- - // SetOps - // ----------------------------- - UNION, - RECURSIVE_CTE, +enum class FilterPropagateResult : uint8_t { + NO_PRUNING_POSSIBLE = 0, + FILTER_ALWAYS_TRUE = 1, + FILTER_ALWAYS_FALSE = 2, + FILTER_TRUE_OR_NULL = 3, + FILTER_FALSE_OR_NULL = 4 +}; - // ----------------------------- - // Updates - // ----------------------------- - INSERT, - BATCH_INSERT, - DELETE_OPERATOR, - UPDATE, +} // namespace duckdb - // ----------------------------- - // Schema - // ----------------------------- - CREATE_TABLE, - CREATE_TABLE_AS, - BATCH_CREATE_TABLE_AS, - CREATE_INDEX, - ALTER, - CREATE_SEQUENCE, - CREATE_VIEW, - CREATE_SCHEMA, - CREATE_MACRO, - DROP, - PRAGMA, - TRANSACTION, - CREATE_TYPE, - // ----------------------------- - // Helpers - // ----------------------------- - EXPLAIN, - EXPLAIN_ANALYZE, - EMPTY_RESULT, - EXECUTE, - PREPARE, - VACUUM, - EXPORT, - SET, - LOAD, - INOUT_FUNCTION, - RESULT_COLLECTOR +namespace duckdb { +class BaseStatistics; +class FieldWriter; +class FieldReader; + +enum class TableFilterType : uint8_t { + CONSTANT_COMPARISON = 0, // constant comparison (e.g. =C, >C, >=C, Deserialize(Deserializer &source); +}; + +class TableFilterSet { +public: + unordered_map> filters; + +public: + void PushFilter(idx_t table_index, unique_ptr filter); + bool Equals(TableFilterSet &other) { + if (filters.size() != other.filters.size()) { + return false; + } + for (auto &entry : filters) { + auto other_entry = other.filters.find(entry.first); + if (other_entry == other.filters.end()) { + return false; + } + if (!entry.second->Equals(*other_entry->second)) { + return false; + } + } + return true; + } + static bool Equals(TableFilterSet *left, TableFilterSet *right) { + if (left == right) { + return true; + } + if (!left || !right) { + return false; + } + return left->Equals(*right); + } + void Serialize(Serializer &serializer) const; + static unique_ptr Deserialize(Deserializer &source); +}; +} // namespace duckdb namespace duckdb { -class ClientContext; -class ThreadContext; -class Pipeline; -class ExecutionContext { +class EstimatedProperties { public: - ExecutionContext(ClientContext &client_p, ThreadContext &thread_p, Pipeline *pipeline_p) - : client(client_p), thread(thread_p), pipeline(pipeline_p) { + EstimatedProperties(double cardinality, double cost) : cardinality(cardinality), cost(cost) {}; + EstimatedProperties() : cardinality(0), cost(0) {}; + + template + T GetCardinality() const { + throw NotImplementedException("Unsupported type for GetCardinality"); } + double GetCost() const; + void SetCost(double new_cost); + void SetCardinality(double cardinality); - //! The client-global context; caution needs to be taken when used in parallel situations - ClientContext &client; - //! The thread-local context for this execution - ThreadContext &thread; - //! Reference to the pipeline for this execution, can be used for example by operators determine caching strategy - Pipeline *pipeline; +private: + double cardinality; + double cost; + +public: + unique_ptr Copy(); }; +template <> +double EstimatedProperties::GetCardinality() const; + +template <> +idx_t EstimatedProperties::GetCardinality() const; + } // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/join_node.hpp +// duckdb/optimizer/join_order/query_graph.hpp // // //===----------------------------------------------------------------------===// @@ -13425,10 +12688,14 @@ class ExecutionContext { + + + + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/optimizer/join_order/query_graph.hpp +// duckdb/planner/column_binding.hpp // // //===----------------------------------------------------------------------===// @@ -13436,11 +12703,26 @@ class ExecutionContext { +#include +namespace duckdb { +struct ColumnBinding { + idx_t table_index; + // This index is local to a Binding, and has no meaning outside of the context of the Binding that created it + idx_t column_index; + ColumnBinding() : table_index(DConstants::INVALID_INDEX), column_index(DConstants::INVALID_INDEX) { + } + ColumnBinding(idx_t table, idx_t column) : table_index(table), column_index(column) { + } + bool operator==(const ColumnBinding &rhs) const { + return table_index == rhs.table_index && column_index == rhs.column_index; + } +}; +} // namespace duckdb #include @@ -13505,9 +12787,6 @@ class QueryGraph { - - - namespace duckdb { class JoinOrderOptimizer; @@ -13833,6 +13112,7 @@ class CachingPhysicalOperator : public PhysicalOperator { namespace duckdb { class BaseStatistics; +class DependencyList; class LogicalGet; class TableFilterSet; @@ -13910,6 +13190,44 @@ struct TableFunctionInput { GlobalTableFunctionState *global_state; }; +enum ScanType { TABLE, PARQUET }; + +struct BindInfo { +public: + explicit BindInfo(ScanType type_p) : type(type_p) {}; + unordered_map options; + ScanType type; + void InsertOption(string name, Value value) { + if (options.find(name) != options.end()) { + throw InternalException("This option already exists"); + } + options[name] = value; + } + template + T GetOption(string name) { + if (options.find(name) == options.end()) { + throw InternalException("This option does not exist"); + } + return options[name].GetValue(); + } + template + vector GetOptionList(string name) { + if (options.find(name) == options.end()) { + throw InternalException("This option does not exist"); + } + auto option = options[name]; + if (option.type().id() != LogicalTypeId::LIST) { + throw InternalException("This option is not a list"); + } + vector result; + auto list_children = ListValue::GetChildren(option); + for (auto &child : list_children) { + result.emplace_back(child.GetValue()); + } + return result; + } +}; + typedef unique_ptr (*table_function_bind_t)(ClientContext &context, TableFunctionBindInput &input, vector &return_types, vector &names); typedef unique_ptr (*table_function_init_global_t)(ClientContext &context, @@ -13928,9 +13246,12 @@ typedef OperatorFinalizeResultType (*table_in_out_function_final_t)(ExecutionCon typedef idx_t (*table_function_get_batch_index_t)(ClientContext &context, const FunctionData *bind_data, LocalTableFunctionState *local_state, GlobalTableFunctionState *global_state); + +typedef BindInfo (*table_function_get_bind_info)(const FunctionData *bind_data); + typedef double (*table_function_progress_t)(ClientContext &context, const FunctionData *bind_data, const GlobalTableFunctionState *global_state); -typedef void (*table_function_dependency_t)(unordered_set &dependencies, const FunctionData *bind_data); +typedef void (*table_function_dependency_t)(DependencyList &dependencies, const FunctionData *bind_data); typedef unique_ptr (*table_function_cardinality_t)(ClientContext &context, const FunctionData *bind_data); typedef void (*table_function_pushdown_complex_filter_t)(ClientContext &context, LogicalGet &get, @@ -13991,6 +13312,8 @@ class TableFunction : public SimpleNamedParameterFunction { table_function_progress_t table_scan_progress; //! (Optional) returns the current batch index of the current scan operator table_function_get_batch_index_t get_batch_index; + //! (Optional) returns the extra batch info, currently only used for the substrait extension + table_function_get_bind_info get_batch_info; table_function_serialize_t serialize; table_function_deserialize_t deserialize; @@ -14103,8 +13426,8 @@ class TaskScheduler { TaskScheduler(DatabaseInstance &db); ~TaskScheduler(); - static TaskScheduler &GetScheduler(ClientContext &context); - static TaskScheduler &GetScheduler(DatabaseInstance &db); + DUCKDB_API static TaskScheduler &GetScheduler(ClientContext &context); + DUCKDB_API static TaskScheduler &GetScheduler(DatabaseInstance &db); unique_ptr CreateProducer(); //! Schedule a task to be executed by the task scheduler @@ -14123,7 +13446,7 @@ class TaskScheduler { //! The main thread will also be used for execution void SetThreads(int32_t n); //! Returns the number of threads - int32_t NumberOfThreads(); + DUCKDB_API int32_t NumberOfThreads(); //! Send signals to n threads, signalling for them to wake up and attempt to execute a task void Signal(idx_t n); @@ -14332,6 +13655,9 @@ class Executor { //! Returns the query result - can only be used if `HasResultCollector` returns true unique_ptr GetResult(); + //! Returns true if all pipelines have been completed + bool ExecutionIsFinished(); + private: void InitializeInternal(PhysicalOperator *physical_plan); @@ -14448,6 +13774,7 @@ class PendingQueryResult : public BaseQueryResult { + namespace duckdb { class ClientContext; class PreparedStatementData; @@ -14457,7 +13784,7 @@ class PreparedStatement { public: //! Create a successfully prepared prepared statement object with the given name DUCKDB_API PreparedStatement(shared_ptr context, shared_ptr data, - string query, idx_t n_param); + string query, idx_t n_param, case_insensitive_map_t named_param_map); //! Create a prepared statement that was not successfully prepared DUCKDB_API explicit PreparedStatement(PreservedError error); @@ -14476,22 +13803,26 @@ class PreparedStatement { PreservedError error; //! The amount of bound parameters idx_t n_param; + //! The (optional) named parameters + case_insensitive_map_t named_param_map; public: //! Returns the stored error message - const string &GetError(); + DUCKDB_API const string &GetError(); //! Returns whether or not an error occurred - bool HasError() const; + DUCKDB_API bool HasError() const; //! Returns the number of columns in the result - idx_t ColumnCount(); + DUCKDB_API idx_t ColumnCount(); //! Returns the statement type of the underlying prepared statement object - StatementType GetStatementType(); + DUCKDB_API StatementType GetStatementType(); //! Returns the underlying statement properties - StatementProperties GetStatementProperties(); + DUCKDB_API StatementProperties GetStatementProperties(); //! Returns the result SQL types of the prepared statement - const vector &GetTypes(); + DUCKDB_API const vector &GetTypes(); //! Returns the result names of the prepared statement - const vector &GetNames(); + DUCKDB_API const vector &GetNames(); + //! Returns the map of parameter index to the expected type of parameter + DUCKDB_API vector GetExpectedParameterTypes() const; //! Create a pending query result of the prepared statement with the given set of arguments template @@ -14628,6 +13959,7 @@ enum class RelationType : uint8_t { DELETE_RELATION, UPDATE_RELATION, WRITE_CSV_RELATION, + WRITE_PARQUET_RELATION, READ_CSV_RELATION, SUBQUERY_RELATION, TABLE_FUNCTION_RELATION, @@ -14653,103 +13985,579 @@ string RelationTypeToString(RelationType type); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/catalog/catalog_entry/schema_catalog_entry.hpp -// -// -//===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/catalog/catalog_entry/schema_catalog_entry.hpp +// +// +//===----------------------------------------------------------------------===// + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/catalog/catalog_set.hpp +// +// +//===----------------------------------------------------------------------===// + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/catalog/default/default_generator.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { +class ClientContext; + +class DefaultGenerator { +public: + explicit DefaultGenerator(Catalog &catalog) : catalog(catalog), created_all_entries(false) { + } + virtual ~DefaultGenerator() { + } + + Catalog &catalog; + atomic created_all_entries; + +public: + //! Creates a default entry with the specified name, or returns nullptr if no such entry can be generated + virtual unique_ptr CreateDefaultEntry(ClientContext &context, const string &entry_name) = 0; + //! Get a list of all default entries in the generator + virtual vector GetDefaultEntries() = 0; +}; + +} // namespace duckdb + + + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/transaction/transaction.hpp +// +// +//===----------------------------------------------------------------------===// + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/catalog/catalog_entry/sequence_catalog_entry.hpp +// +// +//===----------------------------------------------------------------------===// + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/catalog/standard_entry.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { +class SchemaCatalogEntry; + +//! A StandardEntry is a catalog entry that is a member of a schema +class StandardEntry : public CatalogEntry { +public: + StandardEntry(CatalogType type, SchemaCatalogEntry *schema, Catalog *catalog, string name) + : CatalogEntry(type, catalog, name), schema(schema) { + } + ~StandardEntry() override { + } + + //! The schema the entry belongs to + SchemaCatalogEntry *schema; +}; +} // namespace duckdb + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/parsed_data/create_sequence_info.hpp +// +// +//===----------------------------------------------------------------------===// + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/parsed_data/create_info.hpp +// +// +//===----------------------------------------------------------------------===// + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/field_writer.hpp +// +// +//===----------------------------------------------------------------------===// + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/set.hpp +// +// +//===----------------------------------------------------------------------===// + + + +#include + +namespace duckdb { +using std::set; +} + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/serializer/buffered_serializer.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +#define SERIALIZER_DEFAULT_SIZE 1024 + +struct BinaryData { + unique_ptr data; + idx_t size; +}; + +class BufferedSerializer : public Serializer { +public: + //! Serializes to a buffer allocated by the serializer, will expand when + //! writing past the initial threshold + DUCKDB_API explicit BufferedSerializer(idx_t maximum_size = SERIALIZER_DEFAULT_SIZE); + //! Serializes to a provided (owned) data pointer + BufferedSerializer(unique_ptr data, idx_t size); + BufferedSerializer(data_ptr_t data, idx_t size); + + idx_t maximum_size; + data_ptr_t data; + + BinaryData blob; + +public: + void WriteData(const_data_ptr_t buffer, uint64_t write_size) override; + + //! Retrieves the data after the writing has been completed + BinaryData GetData() { + return std::move(blob); + } + + void Reset() { + blob.size = 0; + } +}; + +} // namespace duckdb + +#include + +namespace duckdb { +class BufferedSerializer; + +struct IndexWriteOperation { + template + static DST Operation(SRC input) { + return input.index; + } +}; + +class FieldWriter { +public: + DUCKDB_API FieldWriter(Serializer &serializer); + DUCKDB_API ~FieldWriter(); + +public: + template + void WriteField(const T &element) { + static_assert(std::is_trivially_destructible(), "WriteField object must be trivially destructible"); + + AddField(); + WriteData((const_data_ptr_t)&element, sizeof(T)); + } + + //! Write a string with a length prefix + void WriteString(const string &val) { + WriteStringLen((const_data_ptr_t)val.c_str(), val.size()); + } + void WriteStringLen(const_data_ptr_t val, idx_t len) { + AddField(); + Write((uint32_t)len); + if (len > 0) { + WriteData(val, len); + } + } + void WriteBlob(const_data_ptr_t val, idx_t len) { + AddField(); + if (len > 0) { + WriteData(val, len); + } + } + + template > + void WriteList(const CONTAINER_TYPE &elements) { + AddField(); + Write(elements.size()); + for (auto &element : elements) { + Write(element); + } + } + + template > + void WriteGenericList(const CONTAINER_TYPE &elements) { + AddField(); + Write(elements.size()); + for (auto &element : elements) { + Write(OP::template Operation(element)); + } + } + template + void WriteIndexList(const vector &elements) { + WriteGenericList(elements); + } + // vector yay + template > + void WriteListNoReference(const CONTAINER_TYPE &elements) { + AddField(); + Write(elements.size()); + for (auto element : elements) { + Write(element); + } + } + template + void WriteSerializable(const T &element) { + AddField(); + element.Serialize(*buffer); + } -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/catalog/catalog_set.hpp -// -// -//===----------------------------------------------------------------------===// + template + void WriteSerializableList(const vector> &elements) { + AddField(); + Write(elements.size()); + for (idx_t i = 0; i < elements.size(); i++) { + elements[i]->Serialize(*buffer); + } + } + template + void WriteRegularSerializableList(const vector &elements) { + AddField(); + Write(elements.size()); + for (idx_t i = 0; i < elements.size(); i++) { + elements[i].Serialize(*buffer); + } + } + template + void WriteOptional(const unique_ptr &element) { + AddField(); + Write(element ? true : false); + if (element) { + element->Serialize(*buffer); + } + } + // Called after all fields have been written. Should always be called. + DUCKDB_API void Finalize(); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/catalog/default/default_generator.hpp -// -// -//===----------------------------------------------------------------------===// + Serializer &GetSerializer() { + return *buffer; + } +private: + void AddField() { + field_count++; + } + template + void Write(const T &element) { + WriteData((const_data_ptr_t)&element, sizeof(T)); + } + DUCKDB_API void WriteData(const_data_ptr_t buffer, idx_t write_size); +private: + Serializer &serializer; + unique_ptr buffer; + idx_t field_count; + bool finalized; +}; +template <> +DUCKDB_API void FieldWriter::Write(const string &val); -namespace duckdb { -class ClientContext; +class FieldDeserializer : public Deserializer { +public: + FieldDeserializer(Deserializer &root); -class DefaultGenerator { public: - explicit DefaultGenerator(Catalog &catalog) : catalog(catalog), created_all_entries(false) { - } - virtual ~DefaultGenerator() { + void ReadData(data_ptr_t buffer, idx_t read_size) override; + + void SetRemainingData(idx_t remaining_data); + idx_t RemainingData(); + Deserializer &GetRoot() { + return root; } - Catalog &catalog; - atomic created_all_entries; +private: + Deserializer &root; + idx_t remaining_data; +}; -public: - //! Creates a default entry with the specified name, or returns nullptr if no such entry can be generated - virtual unique_ptr CreateDefaultEntry(ClientContext &context, const string &entry_name) = 0; - //! Get a list of all default entries in the generator - virtual vector GetDefaultEntries() = 0; +struct IndexReadOperation { + template + static DST Operation(SRC input) { + return DST(input); + } }; -} // namespace duckdb +class FieldReader { +public: + DUCKDB_API FieldReader(Deserializer &source); + DUCKDB_API ~FieldReader(); +public: + template + T ReadRequired() { + if (field_count >= max_field_count) { + // field is not there, throw an exception + throw SerializationException("Attempting to read a required field, but field is missing"); + } + // field is there, read the actual value + AddField(); + return source.Read(); + } + template + T ReadField(T default_value) { + if (field_count >= max_field_count) { + // field is not there, read the default value + return default_value; + } + // field is there, read the actual value + AddField(); + return source.Read(); + } + template > + bool ReadList(CONTAINER_TYPE &result) { + if (field_count >= max_field_count) { + // field is not there, return false and leave the result empty + return false; + } + AddField(); + auto result_count = source.Read(); + result.reserve(result_count); + for (idx_t i = 0; i < result_count; i++) { + result.push_back(source.Read()); + } + return true; + } + template > + CONTAINER_TYPE ReadRequiredList() { + if (field_count >= max_field_count) { + // field is not there, throw an exception + throw SerializationException("Attempting to read a required field, but field is missing"); + } + AddField(); + auto result_count = source.Read(); + CONTAINER_TYPE result; + result.reserve(result_count); + for (idx_t i = 0; i < result_count; i++) { + result.push_back(source.Read()); + } + return result; + } + template + vector ReadRequiredGenericList() { + if (field_count >= max_field_count) { + // field is not there, throw an exception + throw SerializationException("Attempting to read a required field, but field is missing"); + } + AddField(); + auto result_count = source.Read(); + vector result; + result.reserve(result_count); + for (idx_t i = 0; i < result_count; i++) { + result.push_back(OP::template Operation(source.Read())); + } + return result; + } + template + vector ReadRequiredIndexList() { + return ReadRequiredGenericList(); + } + template + set ReadRequiredSet() { + if (field_count >= max_field_count) { + // field is not there, throw an exception + throw SerializationException("Attempting to read a required field, but field is missing"); + } + AddField(); + auto result_count = source.Read(); + set result; + for (idx_t i = 0; i < result_count; i++) { + result.insert(source.Read()); + } + return result; + } -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/catalog/catalog_entry/sequence_catalog_entry.hpp -// -// -//===----------------------------------------------------------------------===// + template + unique_ptr ReadOptional(unique_ptr default_value, ARGS &&... args) { + if (field_count >= max_field_count) { + // field is not there, read the default value + return default_value; + } + // field is there, read the actual value + AddField(); + return source.template ReadOptional(std::forward(args)...); + } + template > + RETURN_TYPE ReadSerializable(RETURN_TYPE default_value) { + if (field_count >= max_field_count) { + // field is not there, read the default value + return default_value; + } + // field is there, read the actual value + AddField(); + return T::Deserialize(source); + } + template , typename... ARGS> + RETURN_TYPE ReadSerializable(RETURN_TYPE default_value, ARGS &&... args) { + if (field_count >= max_field_count) { + // field is not there, read the default value + return default_value; + } + // field is there, read the actual value + AddField(); + return T::Deserialize(source, std::forward(args)...); + } + template > + RETURN_TYPE ReadRequiredSerializable() { + if (field_count >= max_field_count) { + // field is not there, throw an exception + throw SerializationException("Attempting to read mandatory field, but field is missing"); + } + // field is there, read the actual value + AddField(); + return T::Deserialize(source); + } + template , typename... ARGS> + RETURN_TYPE ReadRequiredSerializable(ARGS &&... args) { + if (field_count >= max_field_count) { + // field is not there, throw an exception + throw SerializationException("Attempting to read mandatory field, but field is missing"); + } + // field is there, read the actual value + AddField(); + return T::Deserialize(source, std::forward(args)...); + } -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/parsed_data/create_sequence_info.hpp -// -// -//===----------------------------------------------------------------------===// + template , typename... ARGS> + vector ReadRequiredSerializableList(ARGS &&... args) { + if (field_count >= max_field_count) { + // field is not there, throw an exception + throw SerializationException("Attempting to read mandatory field, but field is missing"); + } + // field is there, read the actual value + AddField(); + auto result_count = source.Read(); + vector result; + for (idx_t i = 0; i < result_count; i++) { + result.push_back(T::Deserialize(source, std::forward(args)...)); + } + return result; + } + void ReadBlob(data_ptr_t result, idx_t read_size) { + if (field_count >= max_field_count) { + // field is not there, throw an exception + throw SerializationException("Attempting to read a required field, but field is missing"); + } + // field is there, read the actual value + AddField(); + source.ReadData(result, read_size); + } -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/parsed_data/create_info.hpp -// -// -//===----------------------------------------------------------------------===// + //! Called after all fields have been read. Should always be called. + DUCKDB_API void Finalize(); + Deserializer &GetSource() { + return source; + } +private: + void AddField() { + field_count++; + } +private: + FieldDeserializer source; + idx_t field_count; + idx_t max_field_count; + idx_t total_size; + bool finalized; +}; +} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB @@ -14789,15 +14597,17 @@ enum class OnCreateConflict : uint8_t { }; struct CreateInfo : public ParseInfo { - explicit CreateInfo(CatalogType type, string schema = DEFAULT_SCHEMA) - : type(type), schema(schema), on_conflict(OnCreateConflict::ERROR_ON_CONFLICT), temporary(false), - internal(false) { + explicit CreateInfo(CatalogType type, string schema = DEFAULT_SCHEMA, string catalog_p = INVALID_CATALOG) + : type(type), catalog(std::move(catalog_p)), schema(schema), on_conflict(OnCreateConflict::ERROR_ON_CONFLICT), + temporary(false), internal(false) { } ~CreateInfo() override { } //! The to-be-created catalog type CatalogType type; + //! The catalog name of the entry + string catalog; //! The schema name of the entry string schema; //! What to do on create conflict @@ -14881,7 +14691,7 @@ struct CreateSequenceInfo : public CreateInfo { result->max_value = max_value; result->start_value = start_value; result->cycle = cycle; - return move(result); + return std::move(result); } protected: @@ -14927,17 +14737,34 @@ enum class AlterType : uint8_t { ALTER_FUNCTION = 5 }; +struct AlterEntryData { + AlterEntryData() { + } + AlterEntryData(string catalog_p, string schema_p, string name_p, bool if_exists) + : catalog(std::move(catalog_p)), schema(std::move(schema_p)), name(std::move(name_p)), if_exists(if_exists) { + } + + string catalog; + string schema; + string name; + bool if_exists; +}; + struct AlterInfo : public ParseInfo { - AlterInfo(AlterType type, string schema, string name, bool if_exists); + AlterInfo(AlterType type, string catalog, string schema, string name, bool if_exists); virtual ~AlterInfo() override; AlterType type; //! if exists bool if_exists; + //! Catalog name to alter + string catalog; //! Schema name to alter string schema; //! Entry name to alter string name; + //! Allow altering internal entries + bool allow_internal; public: virtual CatalogType GetCatalogType() const = 0; @@ -14945,11 +14772,83 @@ struct AlterInfo : public ParseInfo { void Serialize(Serializer &serializer) const; virtual void Serialize(FieldWriter &writer) const = 0; static unique_ptr Deserialize(Deserializer &source); + + AlterEntryData GetAlterEntryData() const; }; } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/constraint.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +namespace duckdb { + +class Serializer; +class Deserializer; +class FieldWriter; +class FieldReader; + +//===--------------------------------------------------------------------===// +// Constraint Types +//===--------------------------------------------------------------------===// +enum class ConstraintType : uint8_t { + INVALID = 0, // invalid constraint type + NOT_NULL = 1, // NOT NULL constraint + CHECK = 2, // CHECK constraint + UNIQUE = 3, // UNIQUE constraint + FOREIGN_KEY = 4, // FOREIGN KEY constraint +}; + +enum class ForeignKeyType : uint8_t { + FK_TYPE_PRIMARY_KEY_TABLE = 0, // main table + FK_TYPE_FOREIGN_KEY_TABLE = 1, // referencing table + FK_TYPE_SELF_REFERENCE_TABLE = 2 // self refrencing table +}; + +struct ForeignKeyInfo { + ForeignKeyType type; + string schema; + //! if type is FK_TYPE_FOREIGN_KEY_TABLE, means main key table, if type is FK_TYPE_PRIMARY_KEY_TABLE, means foreign + //! key table + string table; + //! The set of main key table's column's index + vector pk_keys; + //! The set of foreign key table's column's index + vector fk_keys; +}; + +//! Constraint is the base class of any type of table constraint. +class Constraint { +public: + DUCKDB_API explicit Constraint(ConstraintType type); + DUCKDB_API virtual ~Constraint(); + + ConstraintType type; + +public: + DUCKDB_API virtual string ToString() const = 0; + DUCKDB_API void Print() const; + + DUCKDB_API virtual unique_ptr Copy() const = 0; + //! Serializes a Constraint to a stand-alone binary blob + DUCKDB_API void Serialize(Serializer &serializer) const; + //! Serializes a Constraint to a stand-alone binary blob + DUCKDB_API virtual void Serialize(FieldWriter &writer) const = 0; + //! Deserializes a blob back into a Constraint + DUCKDB_API static unique_ptr Deserialize(Deserializer &source); +}; +} // namespace duckdb @@ -14961,8 +14860,8 @@ enum AlterForeignKeyType : uint8_t { AFT_ADD = 0, AFT_DELETE = 1 }; // Change Ownership //===--------------------------------------------------------------------===// struct ChangeOwnershipInfo : public AlterInfo { - ChangeOwnershipInfo(CatalogType entry_catalog_type, string entry_schema, string entry_name, string owner_schema, - string owner_name, bool if_exists); + ChangeOwnershipInfo(CatalogType entry_catalog_type, string entry_catalog, string entry_schema, string entry_name, + string owner_schema, string owner_name, bool if_exists); // Catalog type refers to the entry type, since this struct is usually built from an // ALTER . OWNED BY . statement @@ -14995,7 +14894,7 @@ enum class AlterTableType : uint8_t { }; struct AlterTableInfo : public AlterInfo { - AlterTableInfo(AlterTableType type, string schema, string table, bool if_exists); + AlterTableInfo(AlterTableType type, AlterEntryData data); ~AlterTableInfo() override; AlterTableType alter_table_type; @@ -15011,7 +14910,7 @@ struct AlterTableInfo : public AlterInfo { // RenameColumnInfo //===--------------------------------------------------------------------===// struct RenameColumnInfo : public AlterTableInfo { - RenameColumnInfo(string schema, string table, bool if_exists, string old_name_p, string new_name_p); + RenameColumnInfo(AlterEntryData data, string old_name_p, string new_name_p); ~RenameColumnInfo() override; //! Column old name @@ -15022,14 +14921,14 @@ struct RenameColumnInfo : public AlterTableInfo { public: unique_ptr Copy() const override; void SerializeAlterTable(FieldWriter &writer) const override; - static unique_ptr Deserialize(FieldReader &reader, string schema, string table, bool if_exists); + static unique_ptr Deserialize(FieldReader &reader, AlterEntryData data); }; //===--------------------------------------------------------------------===// // RenameTableInfo //===--------------------------------------------------------------------===// struct RenameTableInfo : public AlterTableInfo { - RenameTableInfo(string schema, string table, bool if_exists, string new_name); + RenameTableInfo(AlterEntryData data, string new_name); ~RenameTableInfo() override; //! Relation new name @@ -15038,14 +14937,14 @@ struct RenameTableInfo : public AlterTableInfo { public: unique_ptr Copy() const override; void SerializeAlterTable(FieldWriter &writer) const override; - static unique_ptr Deserialize(FieldReader &reader, string schema, string table, bool if_exists); + static unique_ptr Deserialize(FieldReader &reader, AlterEntryData data); }; //===--------------------------------------------------------------------===// // AddColumnInfo //===--------------------------------------------------------------------===// struct AddColumnInfo : public AlterTableInfo { - AddColumnInfo(string schema, string table, bool if_exists, ColumnDefinition new_column, bool if_column_not_exists); + AddColumnInfo(AlterEntryData data, ColumnDefinition new_column, bool if_column_not_exists); ~AddColumnInfo() override; //! New column @@ -15056,15 +14955,14 @@ struct AddColumnInfo : public AlterTableInfo { public: unique_ptr Copy() const override; void SerializeAlterTable(FieldWriter &writer) const override; - static unique_ptr Deserialize(FieldReader &reader, string schema, string table, bool if_exists); + static unique_ptr Deserialize(FieldReader &reader, AlterEntryData data); }; //===--------------------------------------------------------------------===// // RemoveColumnInfo //===--------------------------------------------------------------------===// struct RemoveColumnInfo : public AlterTableInfo { - RemoveColumnInfo(string schema, string table, bool if_exists, string removed_column, bool if_column_exists, - bool cascade); + RemoveColumnInfo(AlterEntryData data, string removed_column, bool if_column_exists, bool cascade); ~RemoveColumnInfo() override; //! The column to remove @@ -15077,14 +14975,14 @@ struct RemoveColumnInfo : public AlterTableInfo { public: unique_ptr Copy() const override; void SerializeAlterTable(FieldWriter &writer) const override; - static unique_ptr Deserialize(FieldReader &reader, string schema, string table, bool if_exists); + static unique_ptr Deserialize(FieldReader &reader, AlterEntryData data); }; //===--------------------------------------------------------------------===// // ChangeColumnTypeInfo //===--------------------------------------------------------------------===// struct ChangeColumnTypeInfo : public AlterTableInfo { - ChangeColumnTypeInfo(string schema, string table, bool if_exists, string column_name, LogicalType target_type, + ChangeColumnTypeInfo(AlterEntryData data, string column_name, LogicalType target_type, unique_ptr expression); ~ChangeColumnTypeInfo() override; @@ -15098,15 +14996,14 @@ struct ChangeColumnTypeInfo : public AlterTableInfo { public: unique_ptr Copy() const override; void SerializeAlterTable(FieldWriter &writer) const override; - static unique_ptr Deserialize(FieldReader &reader, string schema, string table, bool if_exists); + static unique_ptr Deserialize(FieldReader &reader, AlterEntryData data); }; //===--------------------------------------------------------------------===// // SetDefaultInfo //===--------------------------------------------------------------------===// struct SetDefaultInfo : public AlterTableInfo { - SetDefaultInfo(string schema, string table, bool if_exists, string column_name, - unique_ptr new_default); + SetDefaultInfo(AlterEntryData data, string column_name, unique_ptr new_default); ~SetDefaultInfo() override; //! The column name to alter @@ -15117,16 +15014,15 @@ struct SetDefaultInfo : public AlterTableInfo { public: unique_ptr Copy() const override; void SerializeAlterTable(FieldWriter &writer) const override; - static unique_ptr Deserialize(FieldReader &reader, string schema, string table, bool if_exists); + static unique_ptr Deserialize(FieldReader &reader, AlterEntryData data); }; //===--------------------------------------------------------------------===// // AlterForeignKeyInfo //===--------------------------------------------------------------------===// struct AlterForeignKeyInfo : public AlterTableInfo { - AlterForeignKeyInfo(string schema, string table, bool if_exists, string fk_table, vector pk_columns, - vector fk_columns, vector pk_keys, vector fk_keys, - AlterForeignKeyType type); + AlterForeignKeyInfo(AlterEntryData data, string fk_table, vector pk_columns, vector fk_columns, + vector pk_keys, vector fk_keys, AlterForeignKeyType type); ~AlterForeignKeyInfo() override; string fk_table; @@ -15139,7 +15035,39 @@ struct AlterForeignKeyInfo : public AlterTableInfo { public: unique_ptr Copy() const override; void SerializeAlterTable(FieldWriter &writer) const override; - static unique_ptr Deserialize(FieldReader &reader, string schema, string table, bool if_exists); + static unique_ptr Deserialize(FieldReader &reader, AlterEntryData data); +}; + +//===--------------------------------------------------------------------===// +// SetNotNullInfo +//===--------------------------------------------------------------------===// +struct SetNotNullInfo : public AlterTableInfo { + SetNotNullInfo(AlterEntryData data, string column_name); + ~SetNotNullInfo() override; + + //! The column name to alter + string column_name; + +public: + unique_ptr Copy() const override; + void SerializeAlterTable(FieldWriter &writer) const override; + static unique_ptr Deserialize(FieldReader &reader, AlterEntryData data); +}; + +//===--------------------------------------------------------------------===// +// DropNotNullInfo +//===--------------------------------------------------------------------===// +struct DropNotNullInfo : public AlterTableInfo { + DropNotNullInfo(AlterEntryData data, string column_name); + ~DropNotNullInfo() override; + + //! The column name to alter + string column_name; + +public: + unique_ptr Copy() const override; + void SerializeAlterTable(FieldWriter &writer) const override; + static unique_ptr Deserialize(FieldReader &reader, AlterEntryData data); }; //===--------------------------------------------------------------------===// @@ -15148,7 +15076,7 @@ struct AlterForeignKeyInfo : public AlterTableInfo { enum class AlterViewType : uint8_t { INVALID = 0, RENAME_VIEW = 1 }; struct AlterViewInfo : public AlterInfo { - AlterViewInfo(AlterViewType type, string schema, string view, bool if_exists); + AlterViewInfo(AlterViewType type, AlterEntryData data); ~AlterViewInfo() override; AlterViewType alter_view_type; @@ -15164,7 +15092,7 @@ struct AlterViewInfo : public AlterInfo { // RenameViewInfo //===--------------------------------------------------------------------===// struct RenameViewInfo : public AlterViewInfo { - RenameViewInfo(string schema, string view, bool if_exists, string new_name); + RenameViewInfo(AlterEntryData data, string new_name); ~RenameViewInfo() override; //! Relation new name @@ -15173,39 +15101,7 @@ struct RenameViewInfo : public AlterViewInfo { public: unique_ptr Copy() const override; void SerializeAlterView(FieldWriter &writer) const override; - static unique_ptr Deserialize(FieldReader &reader, string schema, string view, bool if_exists); -}; - -//===--------------------------------------------------------------------===// -// SetNotNullInfo -//===--------------------------------------------------------------------===// -struct SetNotNullInfo : public AlterTableInfo { - SetNotNullInfo(string schema, string table, bool if_exists, string column_name); - ~SetNotNullInfo() override; - - //! The column name to alter - string column_name; - -public: - unique_ptr Copy() const override; - void SerializeAlterTable(FieldWriter &writer) const override; - static unique_ptr Deserialize(FieldReader &reader, string schema, string table, bool if_exists); -}; - -//===--------------------------------------------------------------------===// -// DropNotNullInfo -//===--------------------------------------------------------------------===// -struct DropNotNullInfo : public AlterTableInfo { - DropNotNullInfo(string schema, string table, bool if_exists, string column_name); - ~DropNotNullInfo() override; - - //! The column name to alter - string column_name; - -public: - unique_ptr Copy() const override; - void SerializeAlterTable(FieldWriter &writer) const override; - static unique_ptr Deserialize(FieldReader &reader, string schema, string table, bool if_exists); + static unique_ptr Deserialize(FieldReader &reader, AlterEntryData data); }; } // namespace duckdb @@ -15227,6 +15123,10 @@ struct SequenceValue { //! A sequence catalog entry class SequenceCatalogEntry : public StandardEntry { +public: + static constexpr const CatalogType Type = CatalogType::SEQUENCE_ENTRY; + static constexpr const char *Name = "sequence"; + public: //! Create a real TableCatalogEntry and initialize storage for it SequenceCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateSequenceInfo *info); @@ -15262,18 +15162,6 @@ class SequenceCatalogEntry : public StandardEntry { }; } // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/transaction/transaction.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - //===----------------------------------------------------------------------===// // DuckDB @@ -15328,7 +15216,7 @@ class UndoBuffer { }; public: - UndoBuffer(const shared_ptr &context); + UndoBuffer(ClientContext &context); //! Reserve space for an entry of the specified type and length in the undo //! buffer @@ -15351,48 +15239,22 @@ class UndoBuffer { ClientContext &context; ArenaAllocator allocator; -private: - template - void IterateEntries(UndoBuffer::IteratorState &state, T &&callback); - template - void IterateEntries(UndoBuffer::IteratorState &state, UndoBuffer::IteratorState &end_state, T &&callback); - template - void ReverseIterateEntries(T &&callback); -}; - -} // namespace duckdb - - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/transaction/transaction_data.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - -namespace duckdb { -class Transaction; - -struct TransactionData { - TransactionData(Transaction &transaction_p); - TransactionData(transaction_t transaction_id_p, transaction_t start_time_p); - - Transaction *transaction; - transaction_t transaction_id; - transaction_t start_time; +private: + template + void IterateEntries(UndoBuffer::IteratorState &state, T &&callback); + template + void IterateEntries(UndoBuffer::IteratorState &state, UndoBuffer::IteratorState &end_state, T &&callback); + template + void ReverseIterateEntries(T &&callback); }; } // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/valid_checker.hpp +// duckdb/transaction/transaction_data.hpp // // //===----------------------------------------------------------------------===// @@ -15401,42 +15263,17 @@ struct TransactionData { - - namespace duckdb { -class DatabaseInstance; +class DuckTransaction; class Transaction; -class ValidChecker { -public: - ValidChecker(); - - DUCKDB_API static ValidChecker &Get(DatabaseInstance &db); - DUCKDB_API static ValidChecker &Get(Transaction &transaction); - - DUCKDB_API void Invalidate(string error); - DUCKDB_API bool IsInvalidated(); - DUCKDB_API string InvalidatedMessage(); - - template - static bool IsInvalidated(T &o) { - return Get(o).IsInvalidated(); - } - template - static void Invalidate(T &o, string error) { - Get(o).Invalidate(move(error)); - } - - template - static string InvalidatedMessage(T &o) { - return Get(o).InvalidatedMessage(); - } +struct TransactionData { + TransactionData(DuckTransaction &transaction_p); + TransactionData(transaction_t transaction_id_p, transaction_t start_time_p); -private: - //! Set to true if a fatal exception has occurred - mutex invalidate_lock; - atomic is_invalidated; - string invalidated_msg; + DuckTransaction *transaction; + transaction_t transaction_id; + transaction_t start_time; }; } // namespace duckdb @@ -15446,12 +15283,15 @@ namespace duckdb { class SequenceCatalogEntry; class SchemaCatalogEntry; +class AttachedDatabase; class ColumnData; class ClientContext; class CatalogEntry; class DataTable; class DatabaseInstance; class LocalStorage; +class MetaTransaction; +class TransactionManager; class WriteAheadLog; class ChunkVectorInfo; @@ -15463,68 +15303,59 @@ struct UpdateInfo; //! transaction class Transaction { public: - Transaction(ClientContext &context, transaction_t start_time, transaction_t transaction_id, - timestamp_t start_timestamp, idx_t catalog_version); - ~Transaction(); + DUCKDB_API Transaction(TransactionManager &manager, ClientContext &context); + DUCKDB_API virtual ~Transaction(); + TransactionManager &manager; weak_ptr context; - //! The start timestamp of this transaction - transaction_t start_time; - //! The transaction id of this transaction - transaction_t transaction_id; - //! The commit id of this transaction, if it has successfully been committed - transaction_t commit_id; - //! Highest active query when the transaction finished, used for cleaning up - transaction_t highest_active_query; //! The current active query for the transaction. Set to MAXIMUM_QUERY_ID if //! no query is active. atomic active_query; - //! The timestamp when the transaction started - timestamp_t start_timestamp; - //! The catalog version when the transaction was started - idx_t catalog_version; - //! Map of all sequences that were used during the transaction and the value they had in this transaction - unordered_map sequence_usage; - //! The validity checker of the transaction - ValidChecker transaction_validity; - //! A pointer to the temporary objects of the client context - shared_ptr temporary_objects; - -public: - static Transaction &GetTransaction(ClientContext &context); - LocalStorage &GetLocalStorage(); - - void PushCatalogEntry(CatalogEntry *entry, data_ptr_t extra_data = nullptr, idx_t extra_data_size = 0); - - //! Commit the current transaction with the given commit identifier. Returns an error message if the transaction - //! commit failed, or an empty string if the commit was sucessful - string Commit(DatabaseInstance &db, transaction_t commit_id, bool checkpoint) noexcept; - //! Returns whether or not a commit of this transaction should trigger an automatic checkpoint - bool AutomaticCheckpoint(DatabaseInstance &db); - - //! Rollback - void Rollback() noexcept; - //! Cleanup the undo buffer - void Cleanup(); - bool ChangesMade(); +public: + DUCKDB_API static Transaction &Get(ClientContext &context, AttachedDatabase &db); + DUCKDB_API static Transaction &Get(ClientContext &context, Catalog &catalog); + + //! Whether or not the transaction has made any modifications to the database so far + DUCKDB_API bool IsReadOnly(); - timestamp_t GetCurrentTransactionStartTimestamp() { - return start_timestamp; + virtual bool IsDuckTransaction() const { + return false; } +}; - void PushDelete(DataTable *table, ChunkVectorInfo *vinfo, row_t rows[], idx_t count, idx_t base_row); - void PushAppend(DataTable *table, idx_t row_start, idx_t row_count); - UpdateInfo *CreateUpdateInfo(idx_t type_size, idx_t entries); +} // namespace duckdb -private: - //! The undo buffer is used to store old versions of rows that are updated - //! or deleted - UndoBuffer undo_buffer; - //! The set of uncommitted appends for the transaction - unique_ptr storage; - Transaction(const Transaction &) = delete; +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/catalog/similar_catalog_entry.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { +class SchemaCatalogEntry; + +//! Return value of SimilarEntryInSchemas +struct SimilarCatalogEntry { + //! The entry name. Empty if absent + string name; + //! The distance to the given name. + idx_t distance = idx_t(-1); + //! The schema of the entry. + SchemaCatalogEntry *schema = nullptr; + + DUCKDB_API bool Found() const { + return !name.empty(); + } + + DUCKDB_API string GetQualifiedName(bool qualify_catalog, bool qualify_schema) const; }; } // namespace duckdb @@ -15536,9 +15367,14 @@ namespace duckdb { struct AlterInfo; class ClientContext; +class DependencyList; struct MappingValue; struct EntryIndex; +class DuckCatalog; +class TableCatalogEntry; +class SequenceCatalogEntry; + typedef unordered_map> set_lock_map_t; struct EntryValue { @@ -15546,7 +15382,7 @@ struct EntryValue { throw InternalException("EntryValue called without a catalog entry"); } - explicit EntryValue(unique_ptr entry_p) : entry(move(entry_p)), reference_count(0) { + explicit EntryValue(unique_ptr entry_p) : entry(std::move(entry_p)), reference_count(0) { } //! enable move constructors EntryValue(EntryValue &&other) noexcept { @@ -15579,23 +15415,31 @@ class CatalogSet { //! Create an entry in the catalog set. Returns whether or not it was //! successful. + DUCKDB_API bool CreateEntry(CatalogTransaction transaction, const string &name, unique_ptr value, + DependencyList &dependencies); DUCKDB_API bool CreateEntry(ClientContext &context, const string &name, unique_ptr value, - unordered_set &dependencies); + DependencyList &dependencies); - DUCKDB_API bool AlterEntry(ClientContext &context, const string &name, AlterInfo *alter_info); + DUCKDB_API bool AlterEntry(CatalogTransaction transaction, const string &name, AlterInfo *alter_info); - DUCKDB_API bool DropEntry(ClientContext &context, const string &name, bool cascade); + DUCKDB_API bool DropEntry(CatalogTransaction transaction, const string &name, bool cascade, + bool allow_drop_internal = false); + DUCKDB_API bool DropEntry(ClientContext &context, const string &name, bool cascade, + bool allow_drop_internal = false); - bool AlterOwnership(ClientContext &context, ChangeOwnershipInfo *info); + DUCKDB_API DuckCatalog &GetCatalog(); + + bool AlterOwnership(CatalogTransaction transaction, ChangeOwnershipInfo *info); void CleanupEntry(CatalogEntry *catalog_entry); //! Returns the entry with the specified name + DUCKDB_API CatalogEntry *GetEntry(CatalogTransaction transaction, const string &name); DUCKDB_API CatalogEntry *GetEntry(ClientContext &context, const string &name); //! Gets the entry that is most similar to the given name (i.e. smallest levenshtein distance), or empty string if //! none is found. The returned pair consists of the entry name and the distance (smaller means closer). - pair SimilarEntry(ClientContext &context, const string &name); + SimilarCatalogEntry SimilarEntry(CatalogTransaction transaction, const string &name); //! Rollback to be the currently valid entry for a certain catalog //! entry @@ -15604,20 +15448,23 @@ class CatalogSet { //! Scan the catalog set, invoking the callback method for every committed entry DUCKDB_API void Scan(const std::function &callback); //! Scan the catalog set, invoking the callback method for every entry + DUCKDB_API void Scan(CatalogTransaction transaction, const std::function &callback); DUCKDB_API void Scan(ClientContext &context, const std::function &callback); template - vector GetEntries(ClientContext &context) { + vector GetEntries(CatalogTransaction transaction) { vector result; - Scan(context, [&](CatalogEntry *entry) { result.push_back((T *)entry); }); + Scan(transaction, [&](CatalogEntry *entry) { result.push_back((T *)entry); }); return result; } - DUCKDB_API static bool HasConflict(ClientContext &context, transaction_t timestamp); - DUCKDB_API static bool UseTimestamp(ClientContext &context, transaction_t timestamp); + DUCKDB_API bool HasConflict(CatalogTransaction transaction, transaction_t timestamp); + DUCKDB_API bool UseTimestamp(CatalogTransaction transaction, transaction_t timestamp); void UpdateTimestamp(CatalogEntry *entry, transaction_t timestamp); + void Verify(Catalog &catalog); + private: //! Adjusts table dependencies on the event of an UNDO void AdjustTableDependencies(CatalogEntry *entry); @@ -15626,28 +15473,30 @@ class CatalogSet { //! Adjust User dependency void AdjustUserDependency(CatalogEntry *entry, ColumnDefinition &column, bool remove); //! Given a root entry, gets the entry valid for this transaction - CatalogEntry *GetEntryForTransaction(ClientContext &context, CatalogEntry *current); + CatalogEntry *GetEntryForTransaction(CatalogTransaction transaction, CatalogEntry *current); CatalogEntry *GetCommittedEntry(CatalogEntry *current); - bool GetEntryInternal(ClientContext &context, const string &name, EntryIndex *entry_index, CatalogEntry *&entry); - bool GetEntryInternal(ClientContext &context, EntryIndex &entry_index, CatalogEntry *&entry); + bool GetEntryInternal(CatalogTransaction transaction, const string &name, EntryIndex *entry_index, + CatalogEntry *&entry); + bool GetEntryInternal(CatalogTransaction transaction, EntryIndex &entry_index, CatalogEntry *&entry); //! Drops an entry from the catalog set; must hold the catalog_lock to safely call this - void DropEntryInternal(ClientContext &context, EntryIndex entry_index, CatalogEntry &entry, bool cascade); - CatalogEntry *CreateEntryInternal(ClientContext &context, unique_ptr entry); - MappingValue *GetMapping(ClientContext &context, const string &name, bool get_latest = false); - void PutMapping(ClientContext &context, const string &name, EntryIndex entry_index); - void DeleteMapping(ClientContext &context, const string &name); - void DropEntryDependencies(ClientContext &context, EntryIndex &entry_index, CatalogEntry &entry, bool cascade); + void DropEntryInternal(CatalogTransaction transaction, EntryIndex entry_index, CatalogEntry &entry, bool cascade); + CatalogEntry *CreateEntryInternal(CatalogTransaction transaction, unique_ptr entry); + MappingValue *GetMapping(CatalogTransaction transaction, const string &name, bool get_latest = false); + void PutMapping(CatalogTransaction transaction, const string &name, EntryIndex entry_index); + void DeleteMapping(CatalogTransaction transaction, const string &name); + void DropEntryDependencies(CatalogTransaction transaction, EntryIndex &entry_index, CatalogEntry &entry, + bool cascade); //! Create all default entries - void CreateDefaultEntries(ClientContext &context, unique_lock &lock); + void CreateDefaultEntries(CatalogTransaction transaction, unique_lock &lock); //! Attempt to create a default entry with the specified name. Returns the entry if successful, nullptr otherwise. - CatalogEntry *CreateDefaultEntry(ClientContext &context, const string &name, unique_lock &lock); + CatalogEntry *CreateDefaultEntry(CatalogTransaction transaction, const string &name, unique_lock &lock); EntryIndex PutEntry(idx_t entry_index, unique_ptr entry); void PutEntry(EntryIndex index, unique_ptr entry); private: - Catalog &catalog; + DuckCatalog &catalog; //! The catalog lock is used to make changes to the data mutex catalog_lock; //! The set of catalog entries @@ -15692,38 +15541,19 @@ struct DropInfo; //! A schema in the catalog class SchemaCatalogEntry : public CatalogEntry { - friend class Catalog; +public: + static constexpr const CatalogType Type = CatalogType::SCHEMA_ENTRY; + static constexpr const char *Name = "schema"; public: SchemaCatalogEntry(Catalog *catalog, string name, bool is_internal); -private: - //! The catalog set holding the tables - CatalogSet tables; - //! The catalog set holding the indexes - CatalogSet indexes; - //! The catalog set holding the table functions - CatalogSet table_functions; - //! The catalog set holding the copy functions - CatalogSet copy_functions; - //! The catalog set holding the pragma functions - CatalogSet pragma_functions; - //! The catalog set holding the scalar and aggregate functions - CatalogSet functions; - //! The catalog set holding the sequences - CatalogSet sequences; - //! The catalog set holding the collations - CatalogSet collations; - //! The catalog set holding the types - CatalogSet types; - -public: - static SchemaCatalogEntry *GetTemporaryObjects(ClientContext &context); - +public: //! Scan the specified catalog set, invoking the callback method for every entry - void Scan(ClientContext &context, CatalogType type, const std::function &callback); + virtual void Scan(ClientContext &context, CatalogType type, + const std::function &callback) = 0; //! Scan the specified catalog set, invoking the callback method for every committed entry - void Scan(CatalogType type, const std::function &callback); + virtual void Scan(CatalogType type, const std::function &callback) = 0; //! Serialize the meta information of the SchemaCatalogEntry a serializer virtual void Serialize(Serializer &serializer); @@ -15733,45 +15563,37 @@ class SchemaCatalogEntry : public CatalogEntry { string ToSQL() override; //! Creates an index with the given name in the schema - CatalogEntry *CreateIndex(ClientContext &context, CreateIndexInfo *info, TableCatalogEntry *table); - -private: + virtual CatalogEntry *CreateIndex(ClientContext &context, CreateIndexInfo *info, TableCatalogEntry *table) = 0; //! Create a scalar or aggregate function within the given schema - CatalogEntry *CreateFunction(ClientContext &context, CreateFunctionInfo *info); + virtual CatalogEntry *CreateFunction(CatalogTransaction transaction, CreateFunctionInfo *info) = 0; //! Creates a table with the given name in the schema - CatalogEntry *CreateTable(ClientContext &context, BoundCreateTableInfo *info); + virtual CatalogEntry *CreateTable(CatalogTransaction transaction, BoundCreateTableInfo *info) = 0; //! Creates a view with the given name in the schema - CatalogEntry *CreateView(ClientContext &context, CreateViewInfo *info); + virtual CatalogEntry *CreateView(CatalogTransaction transaction, CreateViewInfo *info) = 0; //! Creates a sequence with the given name in the schema - CatalogEntry *CreateSequence(ClientContext &context, CreateSequenceInfo *info); + virtual CatalogEntry *CreateSequence(CatalogTransaction transaction, CreateSequenceInfo *info) = 0; //! Create a table function within the given schema - CatalogEntry *CreateTableFunction(ClientContext &context, CreateTableFunctionInfo *info); + virtual CatalogEntry *CreateTableFunction(CatalogTransaction transaction, CreateTableFunctionInfo *info) = 0; //! Create a copy function within the given schema - CatalogEntry *CreateCopyFunction(ClientContext &context, CreateCopyFunctionInfo *info); + virtual CatalogEntry *CreateCopyFunction(CatalogTransaction transaction, CreateCopyFunctionInfo *info) = 0; //! Create a pragma function within the given schema - CatalogEntry *CreatePragmaFunction(ClientContext &context, CreatePragmaFunctionInfo *info); + virtual CatalogEntry *CreatePragmaFunction(CatalogTransaction transaction, CreatePragmaFunctionInfo *info) = 0; //! Create a collation within the given schema - CatalogEntry *CreateCollation(ClientContext &context, CreateCollationInfo *info); + virtual CatalogEntry *CreateCollation(CatalogTransaction transaction, CreateCollationInfo *info) = 0; //! Create a enum within the given schema - CatalogEntry *CreateType(ClientContext &context, CreateTypeInfo *info); + virtual CatalogEntry *CreateType(CatalogTransaction transaction, CreateTypeInfo *info) = 0; - //! Drops an entry from the schema - void DropEntry(ClientContext &context, DropInfo *info); + DUCKDB_API virtual CatalogEntry *GetEntry(CatalogTransaction transaction, CatalogType type, const string &name) = 0; + DUCKDB_API virtual SimilarCatalogEntry GetSimilarEntry(CatalogTransaction transaction, CatalogType type, + const string &name); - //! Append a scalar or aggregate function within the given schema - CatalogEntry *AddFunction(ClientContext &context, CreateFunctionInfo *info); + //! Drops an entry from the schema + virtual void DropEntry(ClientContext &context, DropInfo *info) = 0; //! Alters a catalog entry - void Alter(ClientContext &context, AlterInfo *info); - - //! Add a catalog entry to this schema - CatalogEntry *AddEntry(ClientContext &context, unique_ptr entry, OnCreateConflict on_conflict); - //! Add a catalog entry to this schema - CatalogEntry *AddEntry(ClientContext &context, unique_ptr entry, OnCreateConflict on_conflict, - unordered_set dependencies); + virtual void Alter(ClientContext &context, AlterInfo *info) = 0; - //! Get the catalog set for the specified type - CatalogSet &GetCatalogSet(CatalogType type); + CatalogTransaction GetCatalogTransaction(ClientContext &context); }; } // namespace duckdb @@ -15890,1987 +15712,2432 @@ struct TableDescription { + namespace duckdb { class ClientContext; +class MetaTransaction; class Transaction; class TransactionManager; -//! The transaction context keeps track of all the information relating to the -//! current transaction -class TransactionContext { -public: - TransactionContext(TransactionManager &transaction_manager, ClientContext &context) - : transaction_manager(transaction_manager), context(context), auto_commit(true), current_transaction(nullptr) { - } - ~TransactionContext(); +//! The transaction context keeps track of all the information relating to the +//! current transaction +class TransactionContext { +public: + TransactionContext(ClientContext &context); + ~TransactionContext(); + + MetaTransaction &ActiveTransaction() { + if (!current_transaction) { + throw InternalException("TransactionContext::ActiveTransaction called without active transaction"); + } + return *current_transaction; + } + + bool HasActiveTransaction() { + return !!current_transaction; + } + + void BeginTransaction(); + void Commit(); + void Rollback(); + void ClearTransaction(); + + void SetAutoCommit(bool value); + bool IsAutoCommit() { + return auto_commit; + } + + idx_t GetActiveQuery(); + void ResetActiveQuery(); + void SetActiveQuery(transaction_t query_number); + +private: + ClientContext &context; + bool auto_commit; + + unique_ptr current_transaction; + + TransactionContext(const TransactionContext &) = delete; +}; + +} // namespace duckdb + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/client_config.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/output_type.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + +namespace duckdb { + +enum class ExplainOutputType : uint8_t { ALL = 0, OPTIMIZED_ONLY = 1, PHYSICAL_ONLY = 2 }; + +} // namespace duckdb + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/progress_bar/progress_bar.hpp +// +// +//===----------------------------------------------------------------------===// + + + +//===----------------------------------------------------------------------===// +// +// DuckDB +// +// duckdb.h +// +// +//===----------------------------------------------------------------------===// + + + +// duplicate of duckdb/main/winapi.hpp +#ifndef DUCKDB_API +#ifdef _WIN32 +#if defined(DUCKDB_BUILD_LIBRARY) && !defined(DUCKDB_BUILD_LOADABLE_EXTENSION) +#define DUCKDB_API __declspec(dllexport) +#else +#define DUCKDB_API __declspec(dllimport) +#endif +#else +#define DUCKDB_API +#endif +#endif + +// duplicate of duckdb/main/winapi.hpp +#ifndef DUCKDB_EXTENSION_API +#ifdef _WIN32 +#ifdef DUCKDB_BUILD_LOADABLE_EXTENSION +#define DUCKDB_EXTENSION_API __declspec(dllexport) +#else +#define DUCKDB_EXTENSION_API +#endif +#else +#define DUCKDB_EXTENSION_API __attribute__((visibility("default"))) +#endif +#endif + +// duplicate of duckdb/common/constants.hpp +#ifndef DUCKDB_API_0_3_1 +#define DUCKDB_API_0_3_1 1 +#endif +#ifndef DUCKDB_API_0_3_2 +#define DUCKDB_API_0_3_2 2 +#endif +#ifndef DUCKDB_API_LATEST +#define DUCKDB_API_LATEST DUCKDB_API_0_3_2 +#endif + +#ifndef DUCKDB_API_VERSION +#define DUCKDB_API_VERSION DUCKDB_API_LATEST +#endif + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +//===--------------------------------------------------------------------===// +// Type Information +//===--------------------------------------------------------------------===// +typedef uint64_t idx_t; + +typedef enum DUCKDB_TYPE { + DUCKDB_TYPE_INVALID = 0, + // bool + DUCKDB_TYPE_BOOLEAN, + // int8_t + DUCKDB_TYPE_TINYINT, + // int16_t + DUCKDB_TYPE_SMALLINT, + // int32_t + DUCKDB_TYPE_INTEGER, + // int64_t + DUCKDB_TYPE_BIGINT, + // uint8_t + DUCKDB_TYPE_UTINYINT, + // uint16_t + DUCKDB_TYPE_USMALLINT, + // uint32_t + DUCKDB_TYPE_UINTEGER, + // uint64_t + DUCKDB_TYPE_UBIGINT, + // float + DUCKDB_TYPE_FLOAT, + // double + DUCKDB_TYPE_DOUBLE, + // duckdb_timestamp, in microseconds + DUCKDB_TYPE_TIMESTAMP, + // duckdb_date + DUCKDB_TYPE_DATE, + // duckdb_time + DUCKDB_TYPE_TIME, + // duckdb_interval + DUCKDB_TYPE_INTERVAL, + // duckdb_hugeint + DUCKDB_TYPE_HUGEINT, + // const char* + DUCKDB_TYPE_VARCHAR, + // duckdb_blob + DUCKDB_TYPE_BLOB, + // decimal + DUCKDB_TYPE_DECIMAL, + // duckdb_timestamp, in seconds + DUCKDB_TYPE_TIMESTAMP_S, + // duckdb_timestamp, in milliseconds + DUCKDB_TYPE_TIMESTAMP_MS, + // duckdb_timestamp, in nanoseconds + DUCKDB_TYPE_TIMESTAMP_NS, + // enum type, only useful as logical type + DUCKDB_TYPE_ENUM, + // list type, only useful as logical type + DUCKDB_TYPE_LIST, + // struct type, only useful as logical type + DUCKDB_TYPE_STRUCT, + // map type, only useful as logical type + DUCKDB_TYPE_MAP, + // duckdb_hugeint + DUCKDB_TYPE_UUID, + // union type, only useful as logical type + DUCKDB_TYPE_UNION, + // duckdb_bit + DUCKDB_TYPE_BIT, +} duckdb_type; + +//! Days are stored as days since 1970-01-01 +//! Use the duckdb_from_date/duckdb_to_date function to extract individual information +typedef struct { + int32_t days; +} duckdb_date; - Transaction &ActiveTransaction() { - D_ASSERT(current_transaction); - return *current_transaction; - } +typedef struct { + int32_t year; + int8_t month; + int8_t day; +} duckdb_date_struct; - bool HasActiveTransaction() { - return !!current_transaction; - } +//! Time is stored as microseconds since 00:00:00 +//! Use the duckdb_from_time/duckdb_to_time function to extract individual information +typedef struct { + int64_t micros; +} duckdb_time; - void RecordQuery(string query); - void BeginTransaction(); - void Commit(); - void Rollback(); - void ClearTransaction(); +typedef struct { + int8_t hour; + int8_t min; + int8_t sec; + int32_t micros; +} duckdb_time_struct; - void SetAutoCommit(bool value); - bool IsAutoCommit() { - return auto_commit; - } +//! Timestamps are stored as microseconds since 1970-01-01 +//! Use the duckdb_from_timestamp/duckdb_to_timestamp function to extract individual information +typedef struct { + int64_t micros; +} duckdb_timestamp; -private: - TransactionManager &transaction_manager; - ClientContext &context; - bool auto_commit; +typedef struct { + duckdb_date_struct date; + duckdb_time_struct time; +} duckdb_timestamp_struct; - Transaction *current_transaction; +typedef struct { + int32_t months; + int32_t days; + int64_t micros; +} duckdb_interval; - TransactionContext(const TransactionContext &) = delete; -}; +//! Hugeints are composed in a (lower, upper) component +//! The value of the hugeint is upper * 2^64 + lower +//! For easy usage, the functions duckdb_hugeint_to_double/duckdb_double_to_hugeint are recommended +typedef struct { + uint64_t lower; + int64_t upper; +} duckdb_hugeint; -} // namespace duckdb +typedef struct { + uint8_t width; + uint8_t scale; + duckdb_hugeint value; +} duckdb_decimal; +typedef struct { + char *data; + idx_t size; +} duckdb_string; -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/client_config.hpp -// -// -//===----------------------------------------------------------------------===// +typedef struct { + void *data; + idx_t size; +} duckdb_blob; +typedef struct { + uint64_t offset; + uint64_t length; +} duckdb_list_entry; +typedef struct { +#if DUCKDB_API_VERSION < DUCKDB_API_0_3_2 + void *data; + bool *nullmask; + duckdb_type type; + char *name; +#else + // deprecated, use duckdb_column_data + void *__deprecated_data; + // deprecated, use duckdb_nullmask_data + bool *__deprecated_nullmask; + // deprecated, use duckdb_column_type + duckdb_type __deprecated_type; + // deprecated, use duckdb_column_name + char *__deprecated_name; +#endif + void *internal_data; +} duckdb_column; +typedef struct { +#if DUCKDB_API_VERSION < DUCKDB_API_0_3_2 + idx_t column_count; + idx_t row_count; + idx_t rows_changed; + duckdb_column *columns; + char *error_message; +#else + // deprecated, use duckdb_column_count + idx_t __deprecated_column_count; + // deprecated, use duckdb_row_count + idx_t __deprecated_row_count; + // deprecated, use duckdb_rows_changed + idx_t __deprecated_rows_changed; + // deprecated, use duckdb_column_ family of functions + duckdb_column *__deprecated_columns; + // deprecated, use duckdb_result_error + char *__deprecated_error_message; +#endif + void *internal_data; +} duckdb_result; +typedef struct _duckdb_database { + void *__db; +} * duckdb_database; +typedef struct _duckdb_connection { + void *__conn; +} * duckdb_connection; +typedef struct _duckdb_prepared_statement { + void *__prep; +} * duckdb_prepared_statement; +typedef struct _duckdb_extracted_statements { + void *__extrac; +} * duckdb_extracted_statements; +typedef struct _duckdb_pending_result { + void *__pend; +} * duckdb_pending_result; +typedef struct _duckdb_appender { + void *__appn; +} * duckdb_appender; +typedef struct _duckdb_arrow { + void *__arrw; +} * duckdb_arrow; +typedef struct _duckdb_config { + void *__cnfg; +} * duckdb_config; +typedef struct _duckdb_arrow_schema { + void *__arrs; +} * duckdb_arrow_schema; +typedef struct _duckdb_arrow_array { + void *__arra; +} * duckdb_arrow_array; +typedef struct _duckdb_logical_type { + void *__lglt; +} * duckdb_logical_type; +typedef struct _duckdb_data_chunk { + void *__dtck; +} * duckdb_data_chunk; +typedef struct _duckdb_vector { + void *__vctr; +} * duckdb_vector; +typedef struct _duckdb_value { + void *__val; +} * duckdb_value; -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/enums/output_type.hpp -// -// -//===----------------------------------------------------------------------===// +typedef enum { DuckDBSuccess = 0, DuckDBError = 1 } duckdb_state; +typedef enum { + DUCKDB_PENDING_RESULT_READY = 0, + DUCKDB_PENDING_RESULT_NOT_READY = 1, + DUCKDB_PENDING_ERROR = 2 +} duckdb_pending_state; +//===--------------------------------------------------------------------===// +// Open/Connect +//===--------------------------------------------------------------------===// +/*! +Creates a new database or opens an existing database file stored at the the given path. +If no path is given a new in-memory database is created instead. +* path: Path to the database file on disk, or `nullptr` or `:memory:` to open an in-memory database. +* out_database: The result database object. +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_open(const char *path, duckdb_database *out_database); +/*! +Extended version of duckdb_open. Creates a new database or opens an existing database file stored at the the given path. -namespace duckdb { +* path: Path to the database file on disk, or `nullptr` or `:memory:` to open an in-memory database. +* out_database: The result database object. +* config: (Optional) configuration used to start up the database system. +* out_error: If set and the function returns DuckDBError, this will contain the reason why the start-up failed. +Note that the error must be freed using `duckdb_free`. +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_open_ext(const char *path, duckdb_database *out_database, duckdb_config config, + char **out_error); -enum class ExplainOutputType : uint8_t { ALL = 0, OPTIMIZED_ONLY = 1, PHYSICAL_ONLY = 2 }; +/*! +Closes the specified database and de-allocates all memory allocated for that database. +This should be called after you are done with any database allocated through `duckdb_open`. +Note that failing to call `duckdb_close` (in case of e.g. a program crash) will not cause data corruption. +Still it is recommended to always correctly close a database object after you are done with it. -} // namespace duckdb +* database: The database object to shut down. +*/ +DUCKDB_API void duckdb_close(duckdb_database *database); +/*! +Opens a connection to a database. Connections are required to query the database, and store transactional state +associated with the connection. +* database: The database file to connect to. +* out_connection: The result connection object. +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_connect(duckdb_database database, duckdb_connection *out_connection); +/*! +Closes the specified connection and de-allocates all memory allocated for that connection. -namespace duckdb { -class ClientContext; -class PhysicalResultCollector; -class PreparedStatementData; +* connection: The connection to close. +*/ +DUCKDB_API void duckdb_disconnect(duckdb_connection *connection); -typedef std::function(ClientContext &context, PreparedStatementData &data)> - get_result_collector_t; +/*! +Returns the version of the linked DuckDB, with a version postfix for dev versions -struct ClientConfig { - //! The home directory used by the system (if any) - string home_directory; - //! If the query profiler is enabled or not. - bool enable_profiler = false; - //! If detailed query profiling is enabled - bool enable_detailed_profiling = false; - //! The format to print query profiling information in (default: query_tree), if enabled. - ProfilerPrintFormat profiler_print_format = ProfilerPrintFormat::QUERY_TREE; - //! The file to save query profiling information to, instead of printing it to the console - //! (empty = print to console) - string profiler_save_location; +Usually used for developing C extensions that must return this for a compatibility check. +*/ +DUCKDB_API const char *duckdb_library_version(); - //! Allows suppressing profiler output, even if enabled. We turn on the profiler on all test runs but don't want - //! to output anything - bool emit_profiler_output = true; +//===--------------------------------------------------------------------===// +// Configuration +//===--------------------------------------------------------------------===// +/*! +Initializes an empty configuration object that can be used to provide start-up options for the DuckDB instance +through `duckdb_open_ext`. - //! If the progress bar is enabled or not. - bool enable_progress_bar = false; - //! If the print of the progress bar is enabled - bool print_progress_bar = true; - //! The wait time before showing the progress bar - int wait_time = 2000; +This will always succeed unless there is a malloc failure. - //! Preserve identifier case while parsing. - //! If false, all unquoted identifiers are lower-cased (e.g. "MyTable" -> "mytable"). - bool preserve_identifier_case = true; - //! The maximum expression depth limit in the parser - idx_t max_expression_depth = 1000; +* out_config: The result configuration object. +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_create_config(duckdb_config *out_config); - //! Whether or not aggressive query verification is enabled - bool query_verification_enabled = false; - //! Whether or not verification of external operators is enabled, used for testing - bool verify_external = false; - //! Whether or not we should verify the serializer - bool verify_serializer = false; - //! Enable the running of optimizers - bool enable_optimizer = true; - //! Force parallelism of small tables, used for testing - bool verify_parallelism = false; - //! Force index join independent of table cardinality, used for testing - bool force_index_join = false; - //! Force out-of-core computation for operators that support it, used for testing - bool force_external = false; - //! Force disable cross product generation when hyper graph isn't connected, used for testing - bool force_no_cross_product = false; - //! Maximum bits allowed for using a perfect hash table (i.e. the perfect HT can hold up to 2^perfect_ht_threshold - //! elements) - idx_t perfect_ht_threshold = 12; +/*! +This returns the total amount of configuration options available for usage with `duckdb_get_config_flag`. - //! The explain output type used when none is specified (default: PHYSICAL_ONLY) - ExplainOutputType explain_output_type = ExplainOutputType::PHYSICAL_ONLY; +This should not be called in a loop as it internally loops over all the options. - //! Generic options - case_insensitive_map_t set_variables; +* returns: The amount of config options available. +*/ +DUCKDB_API size_t duckdb_config_count(); - //! Function that is used to create the result collector for a materialized result - //! Defaults to PhysicalMaterializedCollector - get_result_collector_t result_collector = nullptr; +/*! +Obtains a human-readable name and description of a specific configuration option. This can be used to e.g. +display configuration options. This will succeed unless `index` is out of range (i.e. `>= duckdb_config_count`). -public: - static ClientConfig &GetConfig(ClientContext &context); - static const ClientConfig &GetConfig(const ClientContext &context); +The result name or description MUST NOT be freed. - static string ExtractTimezoneFromConfig(ClientConfig &config); +* index: The index of the configuration option (between 0 and `duckdb_config_count`) +* out_name: A name of the configuration flag. +* out_description: A description of the configuration flag. +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_get_config_flag(size_t index, const char **out_name, const char **out_description); - string ExtractTimezone() const; +/*! +Sets the specified option for the specified configuration. The configuration option is indicated by name. +To obtain a list of config options, see `duckdb_get_config_flag`. - bool AnyVerification() { - return query_verification_enabled || verify_external || verify_serializer; - } -}; +In the source code, configuration options are defined in `config.cpp`. -} // namespace duckdb +This can fail if either the name is invalid, or if the value provided for the option is invalid. +* duckdb_config: The configuration object to set the option on. +* name: The name of the configuration flag to set. +* option: The value to set the configuration flag to. +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_set_config(duckdb_config config, const char *name, const char *option); +/*! +Destroys the specified configuration option and de-allocates all memory allocated for the object. +* config: The configuration object to destroy. +*/ +DUCKDB_API void duckdb_destroy_config(duckdb_config *config); -namespace duckdb { -class Appender; -class Catalog; -class CatalogSearchPath; -class ColumnDataCollection; -class DatabaseInstance; -class FileOpener; -class LogicalOperator; -class PreparedStatementData; -class Relation; -class BufferedFileWriter; -class QueryProfiler; -class ClientContextLock; -struct CreateScalarFunctionInfo; -class ScalarFunctionCatalogEntry; -struct ActiveQueryContext; -struct ParserOptions; -struct ClientData; +//===--------------------------------------------------------------------===// +// Query Execution +//===--------------------------------------------------------------------===// +/*! +Executes a SQL query within a connection and stores the full (materialized) result in the out_result pointer. +If the query fails to execute, DuckDBError is returned and the error message can be retrieved by calling +`duckdb_result_error`. -struct PendingQueryParameters { - //! Prepared statement parameters (if any) - vector *parameters = nullptr; - //! Whether or not a stream result should be allowed - bool allow_stream_result = false; -}; +Note that after running `duckdb_query`, `duckdb_destroy_result` must be called on the result object even if the +query fails, otherwise the error stored within the result will not be freed correctly. -//! The ClientContext holds information relevant to the current client session -//! during execution -class ClientContext : public std::enable_shared_from_this { - friend class PendingQueryResult; - friend class StreamQueryResult; - friend class TransactionManager; +* connection: The connection to perform the query in. +* query: The SQL query to run. +* out_result: The query result. +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_query(duckdb_connection connection, const char *query, duckdb_result *out_result); -public: - DUCKDB_API explicit ClientContext(shared_ptr db); - DUCKDB_API ~ClientContext(); +/*! +Closes the result and de-allocates all memory allocated for that connection. - //! The database that this client is connected to - shared_ptr db; - //! Data for the currently running transaction - TransactionContext transaction; - //! Whether or not the query is interrupted - atomic interrupted; - //! External Objects (e.g., Python objects) that views depend of - unordered_map>> external_dependencies; +* result: The result to destroy. +*/ +DUCKDB_API void duckdb_destroy_result(duckdb_result *result); - //! The client configuration - ClientConfig config; - //! The set of client-specific data - unique_ptr client_data; +/*! +Returns the column name of the specified column. The result should not need be freed; the column names will +automatically be destroyed when the result is destroyed. -public: - DUCKDB_API Transaction &ActiveTransaction() { - return transaction.ActiveTransaction(); - } +Returns `NULL` if the column is out of range. - //! Interrupt execution of a query - DUCKDB_API void Interrupt(); - //! Enable query profiling - DUCKDB_API void EnableProfiling(); - //! Disable query profiling - DUCKDB_API void DisableProfiling(); +* result: The result object to fetch the column name from. +* col: The column index. +* returns: The column name of the specified column. +*/ +DUCKDB_API const char *duckdb_column_name(duckdb_result *result, idx_t col); - //! Issue a query, returning a QueryResult. The QueryResult can be either a StreamQueryResult or a - //! MaterializedQueryResult. The StreamQueryResult will only be returned in the case of a successful SELECT - //! statement. - DUCKDB_API unique_ptr Query(const string &query, bool allow_stream_result); - DUCKDB_API unique_ptr Query(unique_ptr statement, bool allow_stream_result); +/*! +Returns the column type of the specified column. - //! Issues a query to the database and returns a Pending Query Result. Note that "query" may only contain - //! a single statement. - DUCKDB_API unique_ptr PendingQuery(const string &query, bool allow_stream_result); - //! Issues a query to the database and returns a Pending Query Result - DUCKDB_API unique_ptr PendingQuery(unique_ptr statement, - bool allow_stream_result); +Returns `DUCKDB_TYPE_INVALID` if the column is out of range. - //! Destroy the client context - DUCKDB_API void Destroy(); +* result: The result object to fetch the column type from. +* col: The column index. +* returns: The column type of the specified column. +*/ +DUCKDB_API duckdb_type duckdb_column_type(duckdb_result *result, idx_t col); - //! Get the table info of a specific table, or nullptr if it cannot be found - DUCKDB_API unique_ptr TableInfo(const string &schema_name, const string &table_name); - //! Appends a DataChunk to the specified table. Returns whether or not the append was successful. - DUCKDB_API void Append(TableDescription &description, ColumnDataCollection &collection); - //! Try to bind a relation in the current client context; either throws an exception or fills the result_columns - //! list with the set of returned columns - DUCKDB_API void TryBindRelation(Relation &relation, vector &result_columns); +/*! +Returns the logical column type of the specified column. - //! Execute a relation - DUCKDB_API unique_ptr Execute(const shared_ptr &relation); +The return type of this call should be destroyed with `duckdb_destroy_logical_type`. - //! Prepare a query - DUCKDB_API unique_ptr Prepare(const string &query); - //! Directly prepare a SQL statement - DUCKDB_API unique_ptr Prepare(unique_ptr statement); +Returns `NULL` if the column is out of range. - //! Create a pending query result from a prepared statement with the given name and set of parameters - //! It is possible that the prepared statement will be re-bound. This will generally happen if the catalog is - //! modified in between the prepared statement being bound and the prepared statement being run. - DUCKDB_API unique_ptr - PendingQuery(const string &query, shared_ptr &prepared, PendingQueryParameters parameters); +* result: The result object to fetch the column type from. +* col: The column index. +* returns: The logical column type of the specified column. +*/ +DUCKDB_API duckdb_logical_type duckdb_column_logical_type(duckdb_result *result, idx_t col); - //! Execute a prepared statement with the given name and set of parameters - //! It is possible that the prepared statement will be re-bound. This will generally happen if the catalog is - //! modified in between the prepared statement being bound and the prepared statement being run. - DUCKDB_API unique_ptr Execute(const string &query, shared_ptr &prepared, - vector &values, bool allow_stream_result = true); - DUCKDB_API unique_ptr Execute(const string &query, shared_ptr &prepared, - PendingQueryParameters parameters); +/*! +Returns the number of columns present in a the result object. - //! Gets current percentage of the query's progress, returns 0 in case the progress bar is disabled. - DUCKDB_API double GetProgress(); +* result: The result object. +* returns: The number of columns present in the result object. +*/ +DUCKDB_API idx_t duckdb_column_count(duckdb_result *result); - //! Register function in the temporary schema - DUCKDB_API void RegisterFunction(CreateFunctionInfo *info); +/*! +Returns the number of rows present in a the result object. - //! Parse statements from a query - DUCKDB_API vector> ParseStatements(const string &query); +* result: The result object. +* returns: The number of rows present in the result object. +*/ +DUCKDB_API idx_t duckdb_row_count(duckdb_result *result); + +/*! +Returns the number of rows changed by the query stored in the result. This is relevant only for INSERT/UPDATE/DELETE +queries. For other queries the rows_changed will be 0. + +* result: The result object. +* returns: The number of rows changed. +*/ +DUCKDB_API idx_t duckdb_rows_changed(duckdb_result *result); - //! Extract the logical plan of a query - DUCKDB_API unique_ptr ExtractPlan(const string &query); - DUCKDB_API void HandlePragmaStatements(vector> &statements); +/*! +**DEPRECATED**: Prefer using `duckdb_result_get_chunk` instead. - //! Runs a function with a valid transaction context, potentially starting a transaction if the context is in auto - //! commit mode. - DUCKDB_API void RunFunctionInTransaction(const std::function &fun, - bool requires_valid_transaction = true); - //! Same as RunFunctionInTransaction, but does not obtain a lock on the client context or check for validation - DUCKDB_API void RunFunctionInTransactionInternal(ClientContextLock &lock, const std::function &fun, - bool requires_valid_transaction = true); +Returns the data of a specific column of a result in columnar format. - //! Equivalent to CURRENT_SETTING(key) SQL function. - DUCKDB_API bool TryGetCurrentSetting(const std::string &key, Value &result); +The function returns a dense array which contains the result data. The exact type stored in the array depends on the +corresponding duckdb_type (as provided by `duckdb_column_type`). For the exact type by which the data should be +accessed, see the comments in [the types section](types) or the `DUCKDB_TYPE` enum. - //! Returns the parser options for this client context - DUCKDB_API ParserOptions GetParserOptions() const; +For example, for a column of type `DUCKDB_TYPE_INTEGER`, rows can be accessed in the following manner: +```c +int32_t *data = (int32_t *) duckdb_column_data(&result, 0); +printf("Data for row %d: %d\n", row, data[row]); +``` - DUCKDB_API unique_ptr Fetch(ClientContextLock &lock, StreamQueryResult &result); +* result: The result object to fetch the column data from. +* col: The column index. +* returns: The column data of the specified column. +*/ +DUCKDB_API void *duckdb_column_data(duckdb_result *result, idx_t col); - //! Whether or not the given result object (streaming query result or pending query result) is active - DUCKDB_API bool IsActiveResult(ClientContextLock &lock, BaseQueryResult *result); +/*! +**DEPRECATED**: Prefer using `duckdb_result_get_chunk` instead. - //! Returns the current executor - Executor &GetExecutor(); +Returns the nullmask of a specific column of a result in columnar format. The nullmask indicates for every row +whether or not the corresponding row is `NULL`. If a row is `NULL`, the values present in the array provided +by `duckdb_column_data` are undefined. - //! Returns the current query string (if any) - const string &GetCurrentQuery(); +```c +int32_t *data = (int32_t *) duckdb_column_data(&result, 0); +bool *nullmask = duckdb_nullmask_data(&result, 0); +if (nullmask[row]) { + printf("Data for row %d: NULL\n", row); +} else { + printf("Data for row %d: %d\n", row, data[row]); +} +``` - //! Fetch a list of table names that are required for a given query - DUCKDB_API unordered_set GetTableNames(const string &query); +* result: The result object to fetch the nullmask from. +* col: The column index. +* returns: The nullmask of the specified column. +*/ +DUCKDB_API bool *duckdb_nullmask_data(duckdb_result *result, idx_t col); - DUCKDB_API ClientProperties GetClientProperties() const; +/*! +Returns the error message contained within the result. The error is only set if `duckdb_query` returns `DuckDBError`. -private: - //! Parse statements and resolve pragmas from a query - bool ParseStatements(ClientContextLock &lock, const string &query, vector> &result, - PreservedError &error); - //! Issues a query to the database and returns a Pending Query Result - unique_ptr PendingQueryInternal(ClientContextLock &lock, unique_ptr statement, - PendingQueryParameters parameters, bool verify = true); - unique_ptr ExecutePendingQueryInternal(ClientContextLock &lock, PendingQueryResult &query); +The result of this function must not be freed. It will be cleaned up when `duckdb_destroy_result` is called. - //! Parse statements from a query - vector> ParseStatementsInternal(ClientContextLock &lock, const string &query); - //! Perform aggressive query verification of a SELECT statement. Only called when query_verification_enabled is - //! true. - PreservedError VerifyQuery(ClientContextLock &lock, const string &query, unique_ptr statement); +* result: The result object to fetch the error from. +* returns: The error of the result. +*/ +DUCKDB_API const char *duckdb_result_error(duckdb_result *result); - void InitialCleanup(ClientContextLock &lock); - //! Internal clean up, does not lock. Caller must hold the context_lock. - void CleanupInternal(ClientContextLock &lock, BaseQueryResult *result = nullptr, - bool invalidate_transaction = false); - unique_ptr PendingStatementOrPreparedStatement(ClientContextLock &lock, const string &query, - unique_ptr statement, - shared_ptr &prepared, - PendingQueryParameters parameters); - unique_ptr PendingPreparedStatement(ClientContextLock &lock, - shared_ptr statement_p, - PendingQueryParameters parameters); +//===--------------------------------------------------------------------===// +// Result Functions +//===--------------------------------------------------------------------===// - //! Internally prepare a SQL statement. Caller must hold the context_lock. - shared_ptr CreatePreparedStatement(ClientContextLock &lock, const string &query, - unique_ptr statement, - vector *values = nullptr); - unique_ptr PendingStatementInternal(ClientContextLock &lock, const string &query, - unique_ptr statement, - PendingQueryParameters parameters); - unique_ptr RunStatementInternal(ClientContextLock &lock, const string &query, - unique_ptr statement, bool allow_stream_result, - bool verify = true); - unique_ptr PrepareInternal(ClientContextLock &lock, unique_ptr statement); - void LogQueryInternal(ClientContextLock &lock, const string &query); +/*! +Fetches a data chunk from the duckdb_result. This function should be called repeatedly until the result is exhausted. - unique_ptr FetchResultInternal(ClientContextLock &lock, PendingQueryResult &pending); - unique_ptr FetchInternal(ClientContextLock &lock, Executor &executor, BaseQueryResult &result); +The result must be destroyed with `duckdb_destroy_data_chunk`. - unique_ptr LockContext(); +This function supersedes all `duckdb_value` functions, as well as the `duckdb_column_data` and `duckdb_nullmask_data` +functions. It results in significantly better performance, and should be preferred in newer code-bases. - void BeginTransactionInternal(ClientContextLock &lock, bool requires_valid_transaction); - void BeginQueryInternal(ClientContextLock &lock, const string &query); - PreservedError EndQueryInternal(ClientContextLock &lock, bool success, bool invalidate_transaction); +If this function is used, none of the other result functions can be used and vice versa (i.e. this function cannot be +mixed with the legacy result functions). - PendingExecutionResult ExecuteTaskInternal(ClientContextLock &lock, PendingQueryResult &result); +Use `duckdb_result_chunk_count` to figure out how many chunks there are in the result. - unique_ptr PendingStatementOrPreparedStatementInternal( - ClientContextLock &lock, const string &query, unique_ptr statement, - shared_ptr &prepared, PendingQueryParameters parameters); +* result: The result object to fetch the data chunk from. +* chunk_index: The chunk index to fetch from. +* returns: The resulting data chunk. Returns `NULL` if the chunk index is out of bounds. +*/ +DUCKDB_API duckdb_data_chunk duckdb_result_get_chunk(duckdb_result result, idx_t chunk_index); - unique_ptr PendingQueryPreparedInternal(ClientContextLock &lock, const string &query, - shared_ptr &prepared, - PendingQueryParameters parameters); +/*! +Returns the number of data chunks present in the result. -private: - //! Lock on using the ClientContext in parallel - mutex context_lock; - //! The currently active query context - unique_ptr active_query; - //! The current query progress - atomic query_progress; -}; +* result: The result object +* returns: The resulting data chunk. Returns `NULL` if the chunk index is out of bounds. +*/ +DUCKDB_API idx_t duckdb_result_chunk_count(duckdb_result result); -class ClientContextLock { -public: - explicit ClientContextLock(mutex &context_lock) : client_guard(context_lock) { - } +// Safe fetch functions +// These functions will perform conversions if necessary. +// On failure (e.g. if conversion cannot be performed or if the value is NULL) a default value is returned. +// Note that these functions are slow since they perform bounds checking and conversion +// For fast access of values prefer using `duckdb_result_get_chunk` - ~ClientContextLock() { - } +/*! + * returns: The boolean value at the specified location, or false if the value cannot be converted. + */ +DUCKDB_API bool duckdb_value_boolean(duckdb_result *result, idx_t col, idx_t row); -private: - lock_guard client_guard; -}; +/*! + * returns: The int8_t value at the specified location, or 0 if the value cannot be converted. + */ +DUCKDB_API int8_t duckdb_value_int8(duckdb_result *result, idx_t col, idx_t row); -class ClientContextWrapper { -public: - DUCKDB_API explicit ClientContextWrapper(const shared_ptr &context) - : client_context(context) { +/*! + * returns: The int16_t value at the specified location, or 0 if the value cannot be converted. + */ +DUCKDB_API int16_t duckdb_value_int16(duckdb_result *result, idx_t col, idx_t row); - }; - shared_ptr GetContext() { - auto actual_context = client_context.lock(); - if (!actual_context) { - throw ConnectionException("Connection has already been closed"); - } - return actual_context; - } +/*! + * returns: The int32_t value at the specified location, or 0 if the value cannot be converted. + */ +DUCKDB_API int32_t duckdb_value_int32(duckdb_result *result, idx_t col, idx_t row); -private: - std::weak_ptr client_context; -}; +/*! + * returns: The int64_t value at the specified location, or 0 if the value cannot be converted. + */ +DUCKDB_API int64_t duckdb_value_int64(duckdb_result *result, idx_t col, idx_t row); -} // namespace duckdb +/*! + * returns: The duckdb_hugeint value at the specified location, or 0 if the value cannot be converted. + */ +DUCKDB_API duckdb_hugeint duckdb_value_hugeint(duckdb_result *result, idx_t col, idx_t row); +/*! + * returns: The duckdb_decimal value at the specified location, or 0 if the value cannot be converted. + */ +DUCKDB_API duckdb_decimal duckdb_value_decimal(duckdb_result *result, idx_t col, idx_t row); +/*! + * returns: The uint8_t value at the specified location, or 0 if the value cannot be converted. + */ +DUCKDB_API uint8_t duckdb_value_uint8(duckdb_result *result, idx_t col, idx_t row); -#include +/*! + * returns: The uint16_t value at the specified location, or 0 if the value cannot be converted. + */ +DUCKDB_API uint16_t duckdb_value_uint16(duckdb_result *result, idx_t col, idx_t row); -namespace duckdb { -struct BoundStatement; +/*! + * returns: The uint32_t value at the specified location, or 0 if the value cannot be converted. + */ +DUCKDB_API uint32_t duckdb_value_uint32(duckdb_result *result, idx_t col, idx_t row); -class ClientContextWrapper; -class Binder; -class LogicalOperator; -class QueryNode; -class TableRef; +/*! + * returns: The uint64_t value at the specified location, or 0 if the value cannot be converted. + */ +DUCKDB_API uint64_t duckdb_value_uint64(duckdb_result *result, idx_t col, idx_t row); -class Relation : public std::enable_shared_from_this { -public: - DUCKDB_API Relation(const std::shared_ptr &context, RelationType type) - : context(context), type(type) { - } - DUCKDB_API Relation(ClientContextWrapper &context, RelationType type) : context(context.GetContext()), type(type) { - } - DUCKDB_API virtual ~Relation() { - } +/*! + * returns: The float value at the specified location, or 0 if the value cannot be converted. + */ +DUCKDB_API float duckdb_value_float(duckdb_result *result, idx_t col, idx_t row); - ClientContextWrapper context; +/*! + * returns: The double value at the specified location, or 0 if the value cannot be converted. + */ +DUCKDB_API double duckdb_value_double(duckdb_result *result, idx_t col, idx_t row); - RelationType type; +/*! + * returns: The duckdb_date value at the specified location, or 0 if the value cannot be converted. + */ +DUCKDB_API duckdb_date duckdb_value_date(duckdb_result *result, idx_t col, idx_t row); - shared_ptr extra_dependencies; +/*! + * returns: The duckdb_time value at the specified location, or 0 if the value cannot be converted. + */ +DUCKDB_API duckdb_time duckdb_value_time(duckdb_result *result, idx_t col, idx_t row); -public: - DUCKDB_API virtual const vector &Columns() = 0; - DUCKDB_API virtual unique_ptr GetQueryNode(); - DUCKDB_API virtual BoundStatement Bind(Binder &binder); - DUCKDB_API virtual string GetAlias(); +/*! + * returns: The duckdb_timestamp value at the specified location, or 0 if the value cannot be converted. + */ +DUCKDB_API duckdb_timestamp duckdb_value_timestamp(duckdb_result *result, idx_t col, idx_t row); - DUCKDB_API unique_ptr Execute(); - DUCKDB_API string ToString(); - DUCKDB_API virtual string ToString(idx_t depth) = 0; +/*! + * returns: The duckdb_interval value at the specified location, or 0 if the value cannot be converted. + */ +DUCKDB_API duckdb_interval duckdb_value_interval(duckdb_result *result, idx_t col, idx_t row); - DUCKDB_API void Print(); - DUCKDB_API void Head(idx_t limit = 10); +/*! +* DEPRECATED: use duckdb_value_string instead. This function does not work correctly if the string contains null bytes. +* returns: The text value at the specified location as a null-terminated string, or nullptr if the value cannot be +converted. The result must be freed with `duckdb_free`. +*/ +DUCKDB_API char *duckdb_value_varchar(duckdb_result *result, idx_t col, idx_t row); - DUCKDB_API shared_ptr CreateView(const string &name, bool replace = true, bool temporary = false); - DUCKDB_API shared_ptr CreateView(const string &schema_name, const string &name, bool replace = true, - bool temporary = false); - DUCKDB_API unique_ptr Query(const string &sql); - DUCKDB_API unique_ptr Query(const string &name, const string &sql); +/*!s +* returns: The string value at the specified location. +The result must be freed with `duckdb_free`. +*/ +DUCKDB_API duckdb_string duckdb_value_string(duckdb_result *result, idx_t col, idx_t row); - //! Explain the query plan of this relation - DUCKDB_API unique_ptr Explain(); +/*! +* DEPRECATED: use duckdb_value_string_internal instead. This function does not work correctly if the string contains +null bytes. +* returns: The char* value at the specified location. ONLY works on VARCHAR columns and does not auto-cast. +If the column is NOT a VARCHAR column this function will return NULL. - DUCKDB_API virtual unique_ptr GetTableRef(); - DUCKDB_API virtual bool IsReadOnly() { - return true; - } +The result must NOT be freed. +*/ +DUCKDB_API char *duckdb_value_varchar_internal(duckdb_result *result, idx_t col, idx_t row); -public: - // PROJECT - DUCKDB_API shared_ptr Project(const string &select_list); - DUCKDB_API shared_ptr Project(const string &expression, const string &alias); - DUCKDB_API shared_ptr Project(const string &select_list, const vector &aliases); - DUCKDB_API shared_ptr Project(const vector &expressions); - DUCKDB_API shared_ptr Project(const vector &expressions, const vector &aliases); +/*! +* DEPRECATED: use duckdb_value_string_internal instead. This function does not work correctly if the string contains +null bytes. +* returns: The char* value at the specified location. ONLY works on VARCHAR columns and does not auto-cast. +If the column is NOT a VARCHAR column this function will return NULL. - // FILTER - DUCKDB_API shared_ptr Filter(const string &expression); - DUCKDB_API shared_ptr Filter(const vector &expressions); +The result must NOT be freed. +*/ +DUCKDB_API duckdb_string duckdb_value_string_internal(duckdb_result *result, idx_t col, idx_t row); - // LIMIT - DUCKDB_API shared_ptr Limit(int64_t n, int64_t offset = 0); +/*! +* returns: The duckdb_blob value at the specified location. Returns a blob with blob.data set to nullptr if the +value cannot be converted. The resulting "blob.data" must be freed with `duckdb_free.` +*/ +DUCKDB_API duckdb_blob duckdb_value_blob(duckdb_result *result, idx_t col, idx_t row); - // ORDER - DUCKDB_API shared_ptr Order(const string &expression); - DUCKDB_API shared_ptr Order(const vector &expressions); +/*! + * returns: Returns true if the value at the specified index is NULL, and false otherwise. + */ +DUCKDB_API bool duckdb_value_is_null(duckdb_result *result, idx_t col, idx_t row); - // JOIN operation - DUCKDB_API shared_ptr Join(const shared_ptr &other, const string &condition, - JoinType type = JoinType::INNER); +//===--------------------------------------------------------------------===// +// Helpers +//===--------------------------------------------------------------------===// +/*! +Allocate `size` bytes of memory using the duckdb internal malloc function. Any memory allocated in this manner +should be freed using `duckdb_free`. - // CROSS PRODUCT operation - DUCKDB_API shared_ptr CrossProduct(const shared_ptr &other); +* size: The number of bytes to allocate. +* returns: A pointer to the allocated memory region. +*/ +DUCKDB_API void *duckdb_malloc(size_t size); - // SET operations - DUCKDB_API shared_ptr Union(const shared_ptr &other); - DUCKDB_API shared_ptr Except(const shared_ptr &other); - DUCKDB_API shared_ptr Intersect(const shared_ptr &other); +/*! +Free a value returned from `duckdb_malloc`, `duckdb_value_varchar` or `duckdb_value_blob`. - // DISTINCT operation - DUCKDB_API shared_ptr Distinct(); +* ptr: The memory region to de-allocate. +*/ +DUCKDB_API void duckdb_free(void *ptr); - // AGGREGATES - DUCKDB_API shared_ptr Aggregate(const string &aggregate_list); - DUCKDB_API shared_ptr Aggregate(const vector &aggregates); - DUCKDB_API shared_ptr Aggregate(const string &aggregate_list, const string &group_list); - DUCKDB_API shared_ptr Aggregate(const vector &aggregates, const vector &groups); +/*! +The internal vector size used by DuckDB. +This is the amount of tuples that will fit into a data chunk created by `duckdb_create_data_chunk`. - // ALIAS - DUCKDB_API shared_ptr Alias(const string &alias); +* returns: The vector size. +*/ +DUCKDB_API idx_t duckdb_vector_size(); - //! Insert the data from this relation into a table - DUCKDB_API void Insert(const string &table_name); - DUCKDB_API void Insert(const string &schema_name, const string &table_name); - //! Insert a row (i.e.,list of values) into a table - DUCKDB_API void Insert(const vector> &values); - //! Create a table and insert the data from this relation into that table - DUCKDB_API void Create(const string &table_name); - DUCKDB_API void Create(const string &schema_name, const string &table_name); +//===--------------------------------------------------------------------===// +// Date/Time/Timestamp Helpers +//===--------------------------------------------------------------------===// +/*! +Decompose a `duckdb_date` object into year, month and date (stored as `duckdb_date_struct`). - //! Write a relation to a CSV file - DUCKDB_API void WriteCSV(const string &csv_file); +* date: The date object, as obtained from a `DUCKDB_TYPE_DATE` column. +* returns: The `duckdb_date_struct` with the decomposed elements. +*/ +DUCKDB_API duckdb_date_struct duckdb_from_date(duckdb_date date); - //! Update a table, can only be used on a TableRelation - DUCKDB_API virtual void Update(const string &update, const string &condition = string()); - //! Delete from a table, can only be used on a TableRelation - DUCKDB_API virtual void Delete(const string &condition = string()); - //! Create a relation from calling a table in/out function on the input relation - //! Create a relation from calling a table in/out function on the input relation - DUCKDB_API shared_ptr TableFunction(const std::string &fname, const vector &values); - DUCKDB_API shared_ptr TableFunction(const std::string &fname, const vector &values, - const named_parameter_map_t &named_parameters); +/*! +Re-compose a `duckdb_date` from year, month and date (`duckdb_date_struct`). -public: - //! Whether or not the relation inherits column bindings from its child or not, only relevant for binding - DUCKDB_API virtual bool InheritsColumnBindings() { - return false; - } - DUCKDB_API virtual Relation *ChildRelation() { - return nullptr; - } - DUCKDB_API vector> GetAllDependencies(); +* date: The year, month and date stored in a `duckdb_date_struct`. +* returns: The `duckdb_date` element. +*/ +DUCKDB_API duckdb_date duckdb_to_date(duckdb_date_struct date); -protected: - DUCKDB_API string RenderWhitespace(idx_t depth); -}; +/*! +Decompose a `duckdb_time` object into hour, minute, second and microsecond (stored as `duckdb_time_struct`). -} // namespace duckdb +* time: The time object, as obtained from a `DUCKDB_TYPE_TIME` column. +* returns: The `duckdb_time_struct` with the decomposed elements. +*/ +DUCKDB_API duckdb_time_struct duckdb_from_time(duckdb_time time); +/*! +Re-compose a `duckdb_time` from hour, minute, second and microsecond (`duckdb_time_struct`). +* time: The hour, minute, second and microsecond in a `duckdb_time_struct`. +* returns: The `duckdb_time` element. +*/ +DUCKDB_API duckdb_time duckdb_to_time(duckdb_time_struct time); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/sql_statement.hpp -// -// -//===----------------------------------------------------------------------===// +/*! +Decompose a `duckdb_timestamp` object into a `duckdb_timestamp_struct`. +* ts: The ts object, as obtained from a `DUCKDB_TYPE_TIMESTAMP` column. +* returns: The `duckdb_timestamp_struct` with the decomposed elements. +*/ +DUCKDB_API duckdb_timestamp_struct duckdb_from_timestamp(duckdb_timestamp ts); +/*! +Re-compose a `duckdb_timestamp` from a duckdb_timestamp_struct. +* ts: The de-composed elements in a `duckdb_timestamp_struct`. +* returns: The `duckdb_timestamp` element. +*/ +DUCKDB_API duckdb_timestamp duckdb_to_timestamp(duckdb_timestamp_struct ts); +//===--------------------------------------------------------------------===// +// Hugeint Helpers +//===--------------------------------------------------------------------===// +/*! +Converts a duckdb_hugeint object (as obtained from a `DUCKDB_TYPE_HUGEINT` column) into a double. +* val: The hugeint value. +* returns: The converted `double` element. +*/ +DUCKDB_API double duckdb_hugeint_to_double(duckdb_hugeint val); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/printer.hpp -// -// -//===----------------------------------------------------------------------===// +/*! +Converts a double value to a duckdb_hugeint object. +If the conversion fails because the double value is too big the result will be 0. +* val: The double value. +* returns: The converted `duckdb_hugeint` element. +*/ +DUCKDB_API duckdb_hugeint duckdb_double_to_hugeint(double val); +/*! +Converts a double value to a duckdb_decimal object. +If the conversion fails because the double value is too big, or the width/scale are invalid the result will be 0. -namespace duckdb { +* val: The double value. +* returns: The converted `duckdb_decimal` element. +*/ +DUCKDB_API duckdb_decimal duckdb_double_to_decimal(double val, uint8_t width, uint8_t scale); -enum class OutputStream : uint8_t { STREAM_STDOUT = 1, STREAM_STDERR = 2 }; +//===--------------------------------------------------------------------===// +// Decimal Helpers +//===--------------------------------------------------------------------===// +/*! +Converts a duckdb_decimal object (as obtained from a `DUCKDB_TYPE_DECIMAL` column) into a double. -//! Printer is a static class that allows printing to logs or stdout/stderr -class Printer { -public: - //! Print the object to the stream - DUCKDB_API static void Print(OutputStream stream, const string &str); - //! Print the object to stderr - DUCKDB_API static void Print(const string &str); - //! Directly prints the string to stdout without a newline - DUCKDB_API static void RawPrint(OutputStream stream, const string &str); - //! Flush an output stream - DUCKDB_API static void Flush(OutputStream stream); - //! Whether or not we are printing to a terminal - DUCKDB_API static bool IsTerminal(OutputStream stream); - //! The terminal width - DUCKDB_API static idx_t TerminalWidth(); -}; -} // namespace duckdb +* val: The decimal value. +* returns: The converted `double` element. +*/ +DUCKDB_API double duckdb_decimal_to_double(duckdb_decimal val); +//===--------------------------------------------------------------------===// +// Prepared Statements +//===--------------------------------------------------------------------===// +// A prepared statement is a parameterized query that allows you to bind parameters to it. +// * This is useful to easily supply parameters to functions and avoid SQL injection attacks. +// * This is useful to speed up queries that you will execute several times with different parameters. +// Because the query will only be parsed, bound, optimized and planned once during the prepare stage, +// rather than once per execution. +// For example: +// SELECT * FROM tbl WHERE id=? +// Or a query with multiple parameters: +// SELECT * FROM tbl WHERE id=$1 OR name=$2 -namespace duckdb { +/*! +Create a prepared statement object from a query. -//! SQLStatement is the base class of any type of SQL statement. -class SQLStatement { -public: - explicit SQLStatement(StatementType type) : type(type) {}; - virtual ~SQLStatement() { - } +Note that after calling `duckdb_prepare`, the prepared statement should always be destroyed using +`duckdb_destroy_prepare`, even if the prepare fails. - //! The statement type - StatementType type; - //! The statement location within the query string - idx_t stmt_location = 0; - //! The statement length within the query string - idx_t stmt_length = 0; - //! The number of prepared statement parameters (if any) - idx_t n_param = 0; - //! The query text that corresponds to this SQL statement - string query; +If the prepare fails, `duckdb_prepare_error` can be called to obtain the reason why the prepare failed. -protected: - SQLStatement(const SQLStatement &other) = default; +* connection: The connection object +* query: The SQL query to prepare +* out_prepared_statement: The resulting prepared statement object +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_prepare(duckdb_connection connection, const char *query, + duckdb_prepared_statement *out_prepared_statement); -public: - virtual string ToString() const { - throw InternalException("ToString not supported for this type of SQLStatement: '%s'", - StatementTypeToString(type)); - } - //! Create a copy of this SelectStatement - virtual unique_ptr Copy() const = 0; -}; -} // namespace duckdb +/*! +Closes the prepared statement and de-allocates all memory allocated for the statement. +* prepared_statement: The prepared statement to destroy. +*/ +DUCKDB_API void duckdb_destroy_prepare(duckdb_prepared_statement *prepared_statement); -namespace duckdb { +/*! +Returns the error message associated with the given prepared statement. +If the prepared statement has no error message, this returns `nullptr` instead. -class ColumnDataCollection; -class ClientContext; +The error message should not be freed. It will be de-allocated when `duckdb_destroy_prepare` is called. -class DatabaseInstance; -class DuckDB; -class LogicalOperator; -class SelectStatement; +* prepared_statement: The prepared statement to obtain the error from. +* returns: The error message, or `nullptr` if there is none. +*/ +DUCKDB_API const char *duckdb_prepare_error(duckdb_prepared_statement prepared_statement); -typedef void (*warning_callback)(std::string); +/*! +Returns the number of parameters that can be provided to the given prepared statement. -//! A connection to a database. This represents a (client) connection that can -//! be used to query the database. -class Connection { -public: - DUCKDB_API explicit Connection(DuckDB &database); - DUCKDB_API explicit Connection(DatabaseInstance &database); - DUCKDB_API ~Connection(); +Returns 0 if the query was not successfully prepared. - shared_ptr context; - warning_callback warning_cb; +* prepared_statement: The prepared statement to obtain the number of parameters for. +*/ +DUCKDB_API idx_t duckdb_nparams(duckdb_prepared_statement prepared_statement); -public: - //! Returns query profiling information for the current query - DUCKDB_API string GetProfilingInformation(ProfilerPrintFormat format = ProfilerPrintFormat::QUERY_TREE); +/*! +Returns the parameter type for the parameter at the given index. - //! Interrupt execution of the current query - DUCKDB_API void Interrupt(); +Returns `DUCKDB_TYPE_INVALID` if the parameter index is out of range or the statement was not successfully prepared. - //! Enable query profiling - DUCKDB_API void EnableProfiling(); - //! Disable query profiling - DUCKDB_API void DisableProfiling(); +* prepared_statement: The prepared statement. +* param_idx: The parameter index. +* returns: The parameter type +*/ +DUCKDB_API duckdb_type duckdb_param_type(duckdb_prepared_statement prepared_statement, idx_t param_idx); - DUCKDB_API void SetWarningCallback(warning_callback); +/*! +Clear the params bind to the prepared statement. +*/ +DUCKDB_API duckdb_state duckdb_clear_bindings(duckdb_prepared_statement prepared_statement); - //! Enable aggressive verification/testing of queries, should only be used in testing - DUCKDB_API void EnableQueryVerification(); - DUCKDB_API void DisableQueryVerification(); - //! Force parallel execution, even for smaller tables. Should only be used in testing. - DUCKDB_API void ForceParallelism(); +/*! +Binds a bool value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_boolean(duckdb_prepared_statement prepared_statement, idx_t param_idx, bool val); - //! Issues a query to the database and returns a QueryResult. This result can be either a StreamQueryResult or a - //! MaterializedQueryResult. The result can be stepped through with calls to Fetch(). Note that there can only be - //! one active StreamQueryResult per Connection object. Calling SendQuery() will invalidate any previously existing - //! StreamQueryResult. - DUCKDB_API unique_ptr SendQuery(const string &query); - //! Issues a query to the database and materializes the result (if necessary). Always returns a - //! MaterializedQueryResult. - DUCKDB_API unique_ptr Query(const string &query); - //! Issues a query to the database and materializes the result (if necessary). Always returns a - //! MaterializedQueryResult. - DUCKDB_API unique_ptr Query(unique_ptr statement); - // prepared statements - template - unique_ptr Query(const string &query, Args... args) { - vector values; - return QueryParamsRecursive(query, values, args...); - } +/*! +Binds an int8_t value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_int8(duckdb_prepared_statement prepared_statement, idx_t param_idx, int8_t val); - //! Issues a query to the database and returns a Pending Query Result. Note that "query" may only contain - //! a single statement. - DUCKDB_API unique_ptr PendingQuery(const string &query, bool allow_stream_result = false); - //! Issues a query to the database and returns a Pending Query Result - DUCKDB_API unique_ptr PendingQuery(unique_ptr statement, - bool allow_stream_result = false); +/*! +Binds an int16_t value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_int16(duckdb_prepared_statement prepared_statement, idx_t param_idx, int16_t val); - //! Prepare the specified query, returning a prepared statement object - DUCKDB_API unique_ptr Prepare(const string &query); - //! Prepare the specified statement, returning a prepared statement object - DUCKDB_API unique_ptr Prepare(unique_ptr statement); +/*! +Binds an int32_t value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_int32(duckdb_prepared_statement prepared_statement, idx_t param_idx, int32_t val); - //! Get the table info of a specific table (in the default schema), or nullptr if it cannot be found - DUCKDB_API unique_ptr TableInfo(const string &table_name); - //! Get the table info of a specific table, or nullptr if it cannot be found - DUCKDB_API unique_ptr TableInfo(const string &schema_name, const string &table_name); +/*! +Binds an int64_t value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_int64(duckdb_prepared_statement prepared_statement, idx_t param_idx, int64_t val); - //! Extract a set of SQL statements from a specific query - DUCKDB_API vector> ExtractStatements(const string &query); - //! Extract the logical plan that corresponds to a query - DUCKDB_API unique_ptr ExtractPlan(const string &query); +/*! +Binds an duckdb_hugeint value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_hugeint(duckdb_prepared_statement prepared_statement, idx_t param_idx, + duckdb_hugeint val); +/*! +Binds a duckdb_decimal value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_decimal(duckdb_prepared_statement prepared_statement, idx_t param_idx, + duckdb_decimal val); - //! Appends a DataChunk to the specified table - DUCKDB_API void Append(TableDescription &description, DataChunk &chunk); - //! Appends a ColumnDataCollection to the specified table - DUCKDB_API void Append(TableDescription &description, ColumnDataCollection &collection); +/*! +Binds an uint8_t value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_uint8(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint8_t val); - //! Returns a relation that produces a table from this connection - DUCKDB_API shared_ptr Table(const string &tname); - DUCKDB_API shared_ptr Table(const string &schema_name, const string &table_name); - //! Returns a relation that produces a view from this connection - DUCKDB_API shared_ptr View(const string &tname); - DUCKDB_API shared_ptr View(const string &schema_name, const string &table_name); - //! Returns a relation that calls a specified table function - DUCKDB_API shared_ptr TableFunction(const string &tname); - DUCKDB_API shared_ptr TableFunction(const string &tname, const vector &values, - const named_parameter_map_t &named_parameters); - DUCKDB_API shared_ptr TableFunction(const string &tname, const vector &values); - //! Returns a relation that produces values - DUCKDB_API shared_ptr Values(const vector> &values); - DUCKDB_API shared_ptr Values(const vector> &values, const vector &column_names, - const string &alias = "values"); - DUCKDB_API shared_ptr Values(const string &values); - DUCKDB_API shared_ptr Values(const string &values, const vector &column_names, - const string &alias = "values"); - //! Reads CSV file - DUCKDB_API shared_ptr ReadCSV(const string &csv_file); - DUCKDB_API shared_ptr ReadCSV(const string &csv_file, const vector &columns); - //! Returns a relation from a query - DUCKDB_API shared_ptr RelationFromQuery(const string &query, const string &alias = "queryrelation", - const string &error = "Expected a single SELECT statement"); - DUCKDB_API shared_ptr RelationFromQuery(unique_ptr select_stmt, - const string &alias = "queryrelation"); +/*! +Binds an uint16_t value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_uint16(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint16_t val); - DUCKDB_API void BeginTransaction(); - DUCKDB_API void Commit(); - DUCKDB_API void Rollback(); - DUCKDB_API void SetAutoCommit(bool auto_commit); - DUCKDB_API bool IsAutoCommit(); - DUCKDB_API bool HasActiveTransaction(); +/*! +Binds an uint32_t value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_uint32(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint32_t val); - //! Fetch a list of table names that are required for a given query - DUCKDB_API unordered_set GetTableNames(const string &query); +/*! +Binds an uint64_t value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_uint64(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint64_t val); - template - void CreateScalarFunction(const string &name, TR (*udf_func)(Args...)) { - scalar_function_t function = UDFWrapper::CreateScalarFunction(name, udf_func); - UDFWrapper::RegisterFunction(name, function, *context); - } +/*! +Binds an float value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_float(duckdb_prepared_statement prepared_statement, idx_t param_idx, float val); - template - void CreateScalarFunction(const string &name, vector args, LogicalType ret_type, - TR (*udf_func)(Args...)) { - scalar_function_t function = - UDFWrapper::CreateScalarFunction(name, args, move(ret_type), udf_func); - UDFWrapper::RegisterFunction(name, args, ret_type, function, *context); - } +/*! +Binds an double value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_double(duckdb_prepared_statement prepared_statement, idx_t param_idx, double val); + +/*! +Binds a duckdb_date value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_date(duckdb_prepared_statement prepared_statement, idx_t param_idx, + duckdb_date val); - template - void CreateVectorizedFunction(const string &name, scalar_function_t udf_func, - LogicalType varargs = LogicalType::INVALID) { - UDFWrapper::RegisterFunction(name, udf_func, *context, move(varargs)); - } +/*! +Binds a duckdb_time value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_time(duckdb_prepared_statement prepared_statement, idx_t param_idx, + duckdb_time val); - DUCKDB_API void CreateVectorizedFunction(const string &name, vector args, LogicalType ret_type, - scalar_function_t udf_func, LogicalType varargs = LogicalType::INVALID) { - UDFWrapper::RegisterFunction(name, move(args), move(ret_type), udf_func, *context, move(varargs)); - } +/*! +Binds a duckdb_timestamp value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_timestamp(duckdb_prepared_statement prepared_statement, idx_t param_idx, + duckdb_timestamp val); - //------------------------------------- Aggreate Functions ----------------------------------------// - template - void CreateAggregateFunction(const string &name) { - AggregateFunction function = UDFWrapper::CreateAggregateFunction(name); - UDFWrapper::RegisterAggrFunction(function, *context); - } +/*! +Binds a duckdb_interval value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_interval(duckdb_prepared_statement prepared_statement, idx_t param_idx, + duckdb_interval val); - template - void CreateAggregateFunction(const string &name) { - AggregateFunction function = UDFWrapper::CreateAggregateFunction(name); - UDFWrapper::RegisterAggrFunction(function, *context); - } +/*! +Binds a null-terminated varchar value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_varchar(duckdb_prepared_statement prepared_statement, idx_t param_idx, + const char *val); - template - void CreateAggregateFunction(const string &name, LogicalType ret_type, LogicalType input_typeA) { - AggregateFunction function = - UDFWrapper::CreateAggregateFunction(name, ret_type, input_typeA); - UDFWrapper::RegisterAggrFunction(function, *context); - } +/*! +Binds a varchar value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_varchar_length(duckdb_prepared_statement prepared_statement, idx_t param_idx, + const char *val, idx_t length); - template - void CreateAggregateFunction(const string &name, LogicalType ret_type, LogicalType input_typeA, - LogicalType input_typeB) { - AggregateFunction function = - UDFWrapper::CreateAggregateFunction(name, ret_type, input_typeA, input_typeB); - UDFWrapper::RegisterAggrFunction(function, *context); - } +/*! +Binds a blob value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_blob(duckdb_prepared_statement prepared_statement, idx_t param_idx, + const void *data, idx_t length); - DUCKDB_API void CreateAggregateFunction(const string &name, vector arguments, LogicalType return_type, - aggregate_size_t state_size, aggregate_initialize_t initialize, - aggregate_update_t update, aggregate_combine_t combine, - aggregate_finalize_t finalize, - aggregate_simple_update_t simple_update = nullptr, - bind_aggregate_function_t bind = nullptr, - aggregate_destructor_t destructor = nullptr) { - AggregateFunction function = - UDFWrapper::CreateAggregateFunction(name, arguments, return_type, state_size, initialize, update, combine, - finalize, simple_update, bind, destructor); - UDFWrapper::RegisterAggrFunction(function, *context); - } +/*! +Binds a NULL value to the prepared statement at the specified index. +*/ +DUCKDB_API duckdb_state duckdb_bind_null(duckdb_prepared_statement prepared_statement, idx_t param_idx); -private: - unique_ptr QueryParamsRecursive(const string &query, vector &values); +/*! +Executes the prepared statement with the given bound parameters, and returns a materialized query result. - template - unique_ptr QueryParamsRecursive(const string &query, vector &values, T value, Args... args) { - values.push_back(Value::CreateValue(value)); - return QueryParamsRecursive(query, values, args...); - } -}; +This method can be called multiple times for each prepared statement, and the parameters can be modified +between calls to this function. -} // namespace duckdb +* prepared_statement: The prepared statement to execute. +* out_result: The query result. +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_execute_prepared(duckdb_prepared_statement prepared_statement, + duckdb_result *out_result); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/database.hpp -// -// -//===----------------------------------------------------------------------===// +/*! +Executes the prepared statement with the given bound parameters, and returns an arrow query result. + +* prepared_statement: The prepared statement to execute. +* out_result: The query result. +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_execute_prepared_arrow(duckdb_prepared_statement prepared_statement, + duckdb_arrow *out_result); +//===--------------------------------------------------------------------===// +// Extract Statements +//===--------------------------------------------------------------------===// +// A query string can be extracted into multiple SQL statements. Each statement can be prepared and executed separately. +/*! +Extract all statements from a query. +Note that after calling `duckdb_extract_statements`, the extracted statements should always be destroyed using +`duckdb_destroy_extracted`, even if no statements were extracted. +If the extract fails, `duckdb_extract_statements_error` can be called to obtain the reason why the extract failed. +* connection: The connection object +* query: The SQL query to extract +* out_extracted_statements: The resulting extracted statements object +* returns: The number of extracted statements or 0 on failure. +*/ +DUCKDB_API idx_t duckdb_extract_statements(duckdb_connection connection, const char *query, + duckdb_extracted_statements *out_extracted_statements); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/config.hpp -// -// -//===----------------------------------------------------------------------===// +/*! +Prepare an extracted statement. +Note that after calling `duckdb_prepare_extracted_statement`, the prepared statement should always be destroyed using +`duckdb_destroy_prepare`, even if the prepare fails. +If the prepare fails, `duckdb_prepare_error` can be called to obtain the reason why the prepare failed. +* connection: The connection object +* extracted_statements: The extracted statements object +* index: The index of the extracted statement to prepare +* out_prepared_statement: The resulting prepared statement object +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_prepare_extracted_statement(duckdb_connection connection, + duckdb_extracted_statements extracted_statements, + idx_t index, + duckdb_prepared_statement *out_prepared_statement); +/*! +Returns the error message contained within the extracted statements. +The result of this function must not be freed. It will be cleaned up when `duckdb_destroy_extracted` is called. +* result: The extracted statements to fetch the error from. +* returns: The error of the extracted statements. +*/ +DUCKDB_API const char *duckdb_extract_statements_error(duckdb_extracted_statements extracted_statements); +/*! +De-allocates all memory allocated for the extracted statements. +* extracted_statements: The extracted statements to destroy. +*/ +DUCKDB_API void duckdb_destroy_extracted(duckdb_extracted_statements *extracted_statements); +//===--------------------------------------------------------------------===// +// Pending Result Interface +//===--------------------------------------------------------------------===// +/*! +Executes the prepared statement with the given bound parameters, and returns a pending result. +The pending result represents an intermediate structure for a query that is not yet fully executed. +The pending result can be used to incrementally execute a query, returning control to the client between tasks. +Note that after calling `duckdb_pending_prepared`, the pending result should always be destroyed using +`duckdb_destroy_pending`, even if this function returns DuckDBError. +* prepared_statement: The prepared statement to execute. +* out_result: The pending query result. +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_pending_prepared(duckdb_prepared_statement prepared_statement, + duckdb_pending_result *out_result); +/*! +Closes the pending result and de-allocates all memory allocated for the result. +* pending_result: The pending result to destroy. +*/ +DUCKDB_API void duckdb_destroy_pending(duckdb_pending_result *pending_result); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/enums/optimizer_type.hpp -// -// -//===----------------------------------------------------------------------===// +/*! +Returns the error message contained within the pending result. +The result of this function must not be freed. It will be cleaned up when `duckdb_destroy_pending` is called. +* result: The pending result to fetch the error from. +* returns: The error of the pending result. +*/ +DUCKDB_API const char *duckdb_pending_error(duckdb_pending_result pending_result); +/*! +Executes a single task within the query, returning whether or not the query is ready. +If this returns DUCKDB_PENDING_RESULT_READY, the duckdb_execute_pending function can be called to obtain the result. +If this returns DUCKDB_PENDING_RESULT_NOT_READY, the duckdb_pending_execute_task function should be called again. +If this returns DUCKDB_PENDING_ERROR, an error occurred during execution. -namespace duckdb { +The error message can be obtained by calling duckdb_pending_error on the pending_result. -enum class OptimizerType : uint32_t { - INVALID = 0, - EXPRESSION_REWRITER, - FILTER_PULLUP, - FILTER_PUSHDOWN, - REGEX_RANGE, - IN_CLAUSE, - JOIN_ORDER, - DELIMINATOR, - UNUSED_COLUMNS, - STATISTICS_PROPAGATION, - COMMON_SUBEXPRESSIONS, - COMMON_AGGREGATE, - COLUMN_LIFETIME, - TOP_N, - REORDER_FILTER, - EXTENSION -}; +* pending_result: The pending result to execute a task within.. +* returns: The state of the pending result after the execution. +*/ +DUCKDB_API duckdb_pending_state duckdb_pending_execute_task(duckdb_pending_result pending_result); -string OptimizerTypeToString(OptimizerType type); -OptimizerType OptimizerTypeFromString(const string &str); +/*! +Fully execute a pending query result, returning the final query result. -} // namespace duckdb +If duckdb_pending_execute_task has been called until DUCKDB_PENDING_RESULT_READY was returned, this will return fast. +Otherwise, all remaining tasks must be executed first. +* pending_result: The pending result to execute. +* out_result: The result object. +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_execute_pending(duckdb_pending_result pending_result, duckdb_result *out_result); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/enums/set_scope.hpp -// -// -//===----------------------------------------------------------------------===// +//===--------------------------------------------------------------------===// +// Value Interface +//===--------------------------------------------------------------------===// +/*! +Destroys the value and de-allocates all memory allocated for that type. +* value: The value to destroy. +*/ +DUCKDB_API void duckdb_destroy_value(duckdb_value *value); +/*! +Creates a value from a null-terminated string +* value: The null-terminated string +* returns: The value. This must be destroyed with `duckdb_destroy_value`. +*/ +DUCKDB_API duckdb_value duckdb_create_varchar(const char *text); +/*! +Creates a value from a string -namespace duckdb { +* value: The text +* length: The length of the text +* returns: The value. This must be destroyed with `duckdb_destroy_value`. +*/ +DUCKDB_API duckdb_value duckdb_create_varchar_length(const char *text, idx_t length); -enum class SetScope : uint8_t { - AUTOMATIC = 0, - LOCAL = 1, /* unused */ - SESSION = 2, - GLOBAL = 3 -}; +/*! +Creates a value from an int64 -} // namespace duckdb +* value: The bigint value +* returns: The value. This must be destroyed with `duckdb_destroy_value`. +*/ +DUCKDB_API duckdb_value duckdb_create_int64(int64_t val); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/enums/window_aggregation_mode.hpp -// -// -//===----------------------------------------------------------------------===// +/*! +Obtains a string representation of the given value. +The result must be destroyed with `duckdb_free`. +* value: The value +* returns: The string value. This must be destroyed with `duckdb_free`. +*/ +DUCKDB_API char *duckdb_get_varchar(duckdb_value value); +/*! +Obtains an int64 of the given value. +* value: The value +* returns: The int64 value, or 0 if no conversion is possible +*/ +DUCKDB_API int64_t duckdb_get_int64(duckdb_value value); +//===--------------------------------------------------------------------===// +// Logical Type Interface +//===--------------------------------------------------------------------===// -namespace duckdb { +/*! +Creates a `duckdb_logical_type` from a standard primitive type. +The resulting type should be destroyed with `duckdb_destroy_logical_type`. -enum class WindowAggregationMode : uint32_t { - //! Use the window aggregate API if available - WINDOW = 0, - //! Don't use window, but use combine if available - COMBINE, - //! Don't use combine or window (compute each frame separately) - SEPARATE -}; +This should not be used with `DUCKDB_TYPE_DECIMAL`. -} // namespace duckdb +* type: The primitive type to create. +* returns: The logical type. +*/ +DUCKDB_API duckdb_logical_type duckdb_create_logical_type(duckdb_type type); +/*! +Creates a list type from its child type. +The resulting type should be destroyed with `duckdb_destroy_logical_type`. +* type: The child type of list type to create. +* returns: The logical type. +*/ +DUCKDB_API duckdb_logical_type duckdb_create_list_type(duckdb_logical_type type); +/*! +Creates a map type from its key type and value type. +The resulting type should be destroyed with `duckdb_destroy_logical_type`. +* type: The key type and value type of map type to create. +* returns: The logical type. +*/ +DUCKDB_API duckdb_logical_type duckdb_create_map_type(duckdb_logical_type key_type, duckdb_logical_type value_type); +/*! +Creates a UNION type from the passed types array +The resulting type should be destroyed with `duckdb_destroy_logical_type`. -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/function/cast/default_casts.hpp -// -// -//===----------------------------------------------------------------------===// +* types: The array of types that the union should consist of. +* type_amount: The size of the types array. +* returns: The logical type. +*/ +DUCKDB_API duckdb_logical_type duckdb_create_union_type(duckdb_logical_type member_types, const char **member_names, + idx_t member_count); +/*! +Creates a `duckdb_logical_type` of type decimal with the specified width and scale +The resulting type should be destroyed with `duckdb_destroy_logical_type`. +* width: The width of the decimal type +* scale: The scale of the decimal type +* returns: The logical type. +*/ +DUCKDB_API duckdb_logical_type duckdb_create_decimal_type(uint8_t width, uint8_t scale); +/*! +Retrieves the type class of a `duckdb_logical_type`. +* type: The logical type object +* returns: The type id +*/ +DUCKDB_API duckdb_type duckdb_get_type_id(duckdb_logical_type type); +/*! +Retrieves the width of a decimal type. -namespace duckdb { -class CastFunctionSet; +* type: The logical type object +* returns: The width of the decimal type +*/ +DUCKDB_API uint8_t duckdb_decimal_width(duckdb_logical_type type); -//! Extra data that can be attached to a bind function of a cast, and is available during binding -struct BindCastInfo { - DUCKDB_API virtual ~BindCastInfo(); -}; +/*! +Retrieves the scale of a decimal type. -//! Extra data that can be returned by the bind of a cast, and is available during execution of a cast -struct BoundCastData { - DUCKDB_API virtual ~BoundCastData(); +* type: The logical type object +* returns: The scale of the decimal type +*/ +DUCKDB_API uint8_t duckdb_decimal_scale(duckdb_logical_type type); - DUCKDB_API virtual unique_ptr Copy() const = 0; -}; +/*! +Retrieves the internal storage type of a decimal type. -struct CastParameters { - CastParameters() { - } - CastParameters(BoundCastData *cast_data, bool strict, string *error_message) - : cast_data(cast_data), strict(strict), error_message(error_message) { - } - CastParameters(CastParameters &parent, BoundCastData *cast_data = nullptr) - : cast_data(cast_data), strict(parent.strict), error_message(parent.error_message) { - } +* type: The logical type object +* returns: The internal type of the decimal type +*/ +DUCKDB_API duckdb_type duckdb_decimal_internal_type(duckdb_logical_type type); - //! The bound cast data (if any) - BoundCastData *cast_data = nullptr; - //! whether or not to enable strict casting - bool strict = false; - // out: error message in case cast has failed - string *error_message = nullptr; -}; +/*! +Retrieves the internal storage type of an enum type. -typedef bool (*cast_function_t)(Vector &source, Vector &result, idx_t count, CastParameters ¶meters); +* type: The logical type object +* returns: The internal type of the enum type +*/ +DUCKDB_API duckdb_type duckdb_enum_internal_type(duckdb_logical_type type); -struct BoundCastInfo { - DUCKDB_API - BoundCastInfo(cast_function_t function, - unique_ptr cast_data = nullptr); // NOLINT: allow explicit cast from cast_function_t +/*! +Retrieves the dictionary size of the enum type - cast_function_t function; - unique_ptr cast_data; +* type: The logical type object +* returns: The dictionary size of the enum type +*/ +DUCKDB_API uint32_t duckdb_enum_dictionary_size(duckdb_logical_type type); -public: - BoundCastInfo Copy() const; -}; +/*! +Retrieves the dictionary value at the specified position from the enum. -struct BindCastInput { - DUCKDB_API BindCastInput(CastFunctionSet &function_set, BindCastInfo *info, ClientContext *context); +The result must be freed with `duckdb_free` - CastFunctionSet &function_set; - BindCastInfo *info; - ClientContext *context; +* type: The logical type object +* index: The index in the dictionary +* returns: The string value of the enum type. Must be freed with `duckdb_free`. +*/ +DUCKDB_API char *duckdb_enum_dictionary_value(duckdb_logical_type type, idx_t index); -public: - DUCKDB_API BoundCastInfo GetCastFunction(const LogicalType &source, const LogicalType &target); -}; +/*! +Retrieves the child type of the given list type. -struct ListBoundCastData : public BoundCastData { - explicit ListBoundCastData(BoundCastInfo child_cast) : child_cast_info(move(child_cast)) { - } +The result must be freed with `duckdb_destroy_logical_type` - BoundCastInfo child_cast_info; - static unique_ptr BindListToListCast(BindCastInput &input, const LogicalType &source, - const LogicalType &target); +* type: The logical type object +* returns: The child type of the list type. Must be destroyed with `duckdb_destroy_logical_type`. +*/ +DUCKDB_API duckdb_logical_type duckdb_list_type_child_type(duckdb_logical_type type); -public: - unique_ptr Copy() const override { - return make_unique(child_cast_info.Copy()); - } -}; +/*! +Retrieves the key type of the given map type. -struct StructBoundCastData : public BoundCastData { - StructBoundCastData(vector child_casts, LogicalType target_p) - : child_cast_info(move(child_casts)), target(move(target_p)) { - } +The result must be freed with `duckdb_destroy_logical_type` - vector child_cast_info; - LogicalType target; +* type: The logical type object +* returns: The key type of the map type. Must be destroyed with `duckdb_destroy_logical_type`. +*/ +DUCKDB_API duckdb_logical_type duckdb_map_type_key_type(duckdb_logical_type type); - static unique_ptr BindStructToStructCast(BindCastInput &input, const LogicalType &source, - const LogicalType &target); +/*! +Retrieves the value type of the given map type. -public: - unique_ptr Copy() const override { - vector copy_info; - for (auto &info : child_cast_info) { - copy_info.push_back(info.Copy()); - } - return make_unique(move(copy_info), target); - } -}; +The result must be freed with `duckdb_destroy_logical_type` -struct DefaultCasts { - static BoundCastInfo GetDefaultCastFunction(BindCastInput &input, const LogicalType &source, - const LogicalType &target); +* type: The logical type object +* returns: The value type of the map type. Must be destroyed with `duckdb_destroy_logical_type`. +*/ +DUCKDB_API duckdb_logical_type duckdb_map_type_value_type(duckdb_logical_type type); - static bool NopCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters); - static bool TryVectorNullCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters); - static bool ReinterpretCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters); +/*! +Returns the number of children of a struct type. -private: - static BoundCastInfo BlobCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); - static BoundCastInfo DateCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); - static BoundCastInfo DecimalCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); - static BoundCastInfo EnumCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); - static BoundCastInfo IntervalCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); - static BoundCastInfo ListCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); - static BoundCastInfo NumericCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); - static BoundCastInfo MapCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); - static BoundCastInfo PointerCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); - static BoundCastInfo StringCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); - static BoundCastInfo StructCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); - static BoundCastInfo TimeCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); - static BoundCastInfo TimeTzCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); - static BoundCastInfo TimestampCastSwitch(BindCastInput &input, const LogicalType &source, - const LogicalType &target); - static BoundCastInfo TimestampTzCastSwitch(BindCastInput &input, const LogicalType &source, - const LogicalType &target); - static BoundCastInfo TimestampNsCastSwitch(BindCastInput &input, const LogicalType &source, - const LogicalType &target); - static BoundCastInfo TimestampMsCastSwitch(BindCastInput &input, const LogicalType &source, - const LogicalType &target); - static BoundCastInfo TimestampSecCastSwitch(BindCastInput &input, const LogicalType &source, - const LogicalType &target); - static BoundCastInfo UnionCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); - static BoundCastInfo UUIDCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); +* type: The logical type object +* returns: The number of children of a struct type. +*/ +DUCKDB_API idx_t duckdb_struct_type_child_count(duckdb_logical_type type); - static BoundCastInfo ImplicitToUnionCast(BindCastInput &input, const LogicalType &source, - const LogicalType &target); -}; +/*! +Retrieves the name of the struct child. -} // namespace duckdb +The result must be freed with `duckdb_free` -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/function/replacement_scan.hpp -// -// -//===----------------------------------------------------------------------===// +* type: The logical type object +* index: The child index +* returns: The name of the struct type. Must be freed with `duckdb_free`. +*/ +DUCKDB_API char *duckdb_struct_type_child_name(duckdb_logical_type type, idx_t index); +/*! +Retrieves the child type of the given struct type at the specified index. +The result must be freed with `duckdb_destroy_logical_type` +* type: The logical type object +* index: The child index +* returns: The child type of the struct type. Must be destroyed with `duckdb_destroy_logical_type`. +*/ +DUCKDB_API duckdb_logical_type duckdb_struct_type_child_type(duckdb_logical_type type, idx_t index); +/*! +Returns the number of members that the union type has. -namespace duckdb { +* type: The logical type (union) object +* returns: The number of members of a union type. +*/ +DUCKDB_API idx_t duckdb_union_type_member_count(duckdb_logical_type type); -class DatabaseInstance; -struct DBConfig; +/*! +Retrieves the name of the union member. -struct ReplacementOpenData { - virtual ~ReplacementOpenData() { - } -}; +The result must be freed with `duckdb_free` -struct ReplacementOpenStaticData { - virtual ~ReplacementOpenStaticData() { - } -}; +* type: The logical type object +* index: The child index +* returns: The name of the union member. Must be freed with `duckdb_free`. +*/ +DUCKDB_API char *duckdb_union_type_member_name(duckdb_logical_type type, idx_t index); -typedef unique_ptr (*replacement_open_pre_t)(DBConfig &config, - ReplacementOpenStaticData *static_data); -typedef void (*replacement_open_post_t)(DatabaseInstance &instance, ReplacementOpenData *open_data); +/*! +Retrieves the child type of the given union member at the specified index. -struct ReplacementOpen { - explicit ReplacementOpen(replacement_open_pre_t pre_func, replacement_open_post_t post_func) - : pre_func(pre_func), post_func(post_func), data(nullptr) { - } +The result must be freed with `duckdb_destroy_logical_type` - replacement_open_pre_t pre_func; - replacement_open_post_t post_func; +* type: The logical type object +* index: The child index +* returns: The child type of the union member. Must be destroyed with `duckdb_destroy_logical_type`. +*/ +DUCKDB_API duckdb_logical_type duckdb_union_type_member_type(duckdb_logical_type type, idx_t index); - unique_ptr data; +/*! +Destroys the logical type and de-allocates all memory allocated for that type. - shared_ptr static_data; -}; +* type: The logical type to destroy. +*/ +DUCKDB_API void duckdb_destroy_logical_type(duckdb_logical_type *type); -} // namespace duckdb +//===--------------------------------------------------------------------===// +// Data Chunk Interface +//===--------------------------------------------------------------------===// +/*! +Creates an empty DataChunk with the specified set of types. -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/function/replacement_scan.hpp -// -// -//===----------------------------------------------------------------------===// +* types: An array of types of the data chunk. +* column_count: The number of columns. +* returns: The data chunk. +*/ +DUCKDB_API duckdb_data_chunk duckdb_create_data_chunk(duckdb_logical_type *types, idx_t column_count); +/*! +Destroys the data chunk and de-allocates all memory allocated for that chunk. +* chunk: The data chunk to destroy. +*/ +DUCKDB_API void duckdb_destroy_data_chunk(duckdb_data_chunk *chunk); +/*! +Resets a data chunk, clearing the validity masks and setting the cardinality of the data chunk to 0. +* chunk: The data chunk to reset. +*/ +DUCKDB_API void duckdb_data_chunk_reset(duckdb_data_chunk chunk); -namespace duckdb { +/*! +Retrieves the number of columns in a data chunk. -class ClientContext; -class TableFunctionRef; +* chunk: The data chunk to get the data from +* returns: The number of columns in the data chunk +*/ +DUCKDB_API idx_t duckdb_data_chunk_get_column_count(duckdb_data_chunk chunk); -struct ReplacementScanData { - virtual ~ReplacementScanData() { - } -}; +/*! +Retrieves the vector at the specified column index in the data chunk. -typedef unique_ptr (*replacement_scan_t)(ClientContext &context, const string &table_name, - ReplacementScanData *data); +The pointer to the vector is valid for as long as the chunk is alive. +It does NOT need to be destroyed. -//! Replacement table scans are automatically attempted when a table name cannot be found in the schema -//! This allows you to do e.g. SELECT * FROM 'filename.csv', and automatically convert this into a CSV scan -struct ReplacementScan { - explicit ReplacementScan(replacement_scan_t function, unique_ptr data_p = nullptr) - : function(function), data(move(data_p)) { - } +* chunk: The data chunk to get the data from +* returns: The vector +*/ +DUCKDB_API duckdb_vector duckdb_data_chunk_get_vector(duckdb_data_chunk chunk, idx_t col_idx); - replacement_scan_t function; - unique_ptr data; -}; +/*! +Retrieves the current number of tuples in a data chunk. -} // namespace duckdb +* chunk: The data chunk to get the data from +* returns: The number of tuples in the data chunk +*/ +DUCKDB_API idx_t duckdb_data_chunk_get_size(duckdb_data_chunk chunk); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/optimizer/optimizer_extension.hpp -// -// -//===----------------------------------------------------------------------===// +/*! +Sets the current number of tuples in a data chunk. +* chunk: The data chunk to set the size in +* size: The number of tuples in the data chunk +*/ +DUCKDB_API void duckdb_data_chunk_set_size(duckdb_data_chunk chunk, idx_t size); +//===--------------------------------------------------------------------===// +// Vector Interface +//===--------------------------------------------------------------------===// +/*! +Retrieves the column type of the specified vector. +The result must be destroyed with `duckdb_destroy_logical_type`. +* vector: The vector get the data from +* returns: The type of the vector +*/ +DUCKDB_API duckdb_logical_type duckdb_vector_get_column_type(duckdb_vector vector); +/*! +Retrieves the data pointer of the vector. -namespace duckdb { +The data pointer can be used to read or write values from the vector. +How to read or write values depends on the type of the vector. -//! The OptimizerExtensionInfo holds static information relevant to the optimizer extension -struct OptimizerExtensionInfo { - DUCKDB_API virtual ~OptimizerExtensionInfo() { - } -}; +* vector: The vector to get the data from +* returns: The data pointer +*/ +DUCKDB_API void *duckdb_vector_get_data(duckdb_vector vector); -typedef void (*optimize_function_t)(ClientContext &context, OptimizerExtensionInfo *info, - unique_ptr &plan); +/*! +Retrieves the validity mask pointer of the specified vector. -class OptimizerExtension { -public: - //! The parse function of the parser extension. - //! Takes a query string as input and returns ParserExtensionParseData (on success) or an error - optimize_function_t optimize_function; +If all values are valid, this function MIGHT return NULL! - //! Additional parser info passed to the parse function - shared_ptr optimizer_info; -}; +The validity mask is a bitset that signifies null-ness within the data chunk. +It is a series of uint64_t values, where each uint64_t value contains validity for 64 tuples. +The bit is set to 1 if the value is valid (i.e. not NULL) or 0 if the value is invalid (i.e. NULL). -} // namespace duckdb +Validity of a specific value can be obtained like this: -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/parser_extension.hpp -// -// -//===----------------------------------------------------------------------===// +idx_t entry_idx = row_idx / 64; +idx_t idx_in_entry = row_idx % 64; +bool is_valid = validity_mask[entry_idx] & (1 << idx_in_entry); +Alternatively, the (slower) duckdb_validity_row_is_valid function can be used. +* vector: The vector to get the data from +* returns: The pointer to the validity mask, or NULL if no validity mask is present +*/ +DUCKDB_API uint64_t *duckdb_vector_get_validity(duckdb_vector vector); +/*! +Ensures the validity mask is writable by allocating it. +After this function is called, `duckdb_vector_get_validity` will ALWAYS return non-NULL. +This allows null values to be written to the vector, regardless of whether a validity mask was present before. +* vector: The vector to alter +*/ +DUCKDB_API void duckdb_vector_ensure_validity_writable(duckdb_vector vector); +/*! +Assigns a string element in the vector at the specified location. -namespace duckdb { +* vector: The vector to alter +* index: The row position in the vector to assign the string to +* str: The null-terminated string +*/ +DUCKDB_API void duckdb_vector_assign_string_element(duckdb_vector vector, idx_t index, const char *str); -//! The ParserExtensionInfo holds static information relevant to the parser extension -//! It is made available in the parse_function, and will be kept alive as long as the database system is kept alive -struct ParserExtensionInfo { - DUCKDB_API virtual ~ParserExtensionInfo() { - } -}; +/*! +Assigns a string element in the vector at the specified location. -//===--------------------------------------------------------------------===// -// Parse -//===--------------------------------------------------------------------===// -enum class ParserExtensionResultType : uint8_t { PARSE_SUCCESSFUL, DISPLAY_ORIGINAL_ERROR, DISPLAY_EXTENSION_ERROR }; +* vector: The vector to alter +* index: The row position in the vector to assign the string to +* str: The string +* str_len: The length of the string (in bytes) +*/ +DUCKDB_API void duckdb_vector_assign_string_element_len(duckdb_vector vector, idx_t index, const char *str, + idx_t str_len); -//! The ParserExtensionParseData holds the result of a successful parse step -//! It will be passed along to the subsequent plan function -struct ParserExtensionParseData { - DUCKDB_API virtual ~ParserExtensionParseData() { - } +/*! +Retrieves the child vector of a list vector. - virtual unique_ptr Copy() const = 0; -}; +The resulting vector is valid as long as the parent vector is valid. -struct ParserExtensionParseResult { - ParserExtensionParseResult() : type(ParserExtensionResultType::DISPLAY_ORIGINAL_ERROR) { - } - ParserExtensionParseResult(string error_p) - : type(ParserExtensionResultType::DISPLAY_EXTENSION_ERROR), error(move(error_p)) { - } - ParserExtensionParseResult(unique_ptr parse_data_p) - : type(ParserExtensionResultType::PARSE_SUCCESSFUL), parse_data(move(parse_data_p)) { - } +* vector: The vector +* returns: The child vector +*/ +DUCKDB_API duckdb_vector duckdb_list_vector_get_child(duckdb_vector vector); - //! Whether or not parsing was successful - ParserExtensionResultType type; - //! The parse data (if successful) - unique_ptr parse_data; - //! The error message (if unsuccessful) - string error; -}; +/*! +Returns the size of the child vector of the list -typedef ParserExtensionParseResult (*parse_function_t)(ParserExtensionInfo *info, const string &query); -//===--------------------------------------------------------------------===// -// Plan -//===--------------------------------------------------------------------===// -struct ParserExtensionPlanResult { - //! The table function to execute - TableFunction function; - //! Parameters to the function - vector parameters; - //! Whether or not the statement is read_only (i.e. can be executed in a read_only database) - bool read_only = false; - //! Whether or not the statement requires a valid transaction to be executed - bool requires_valid_transaction = true; - //! What type of result set the statement returns - StatementReturnType return_type = StatementReturnType::NOTHING; -}; +* vector: The vector +* returns: The size of the child list +*/ +DUCKDB_API idx_t duckdb_list_vector_get_size(duckdb_vector vector); -typedef ParserExtensionPlanResult (*plan_function_t)(ParserExtensionInfo *info, ClientContext &context, - unique_ptr parse_data); +/*! +Sets the total size of the underlying child-vector of a list vector. + +* vector: The list vector. +* size: The size of the child list. +* returns: The duckdb state. Returns DuckDBError if the vector is nullptr. +*/ +DUCKDB_API duckdb_state duckdb_list_vector_set_size(duckdb_vector vector, idx_t size); -//===--------------------------------------------------------------------===// -// ParserExtension -//===--------------------------------------------------------------------===// -class ParserExtension { -public: - //! The parse function of the parser extension. - //! Takes a query string as input and returns ParserExtensionParseData (on success) or an error - parse_function_t parse_function; +/*! +Sets the total capacity of the underlying child-vector of a list. - //! The plan function of the parser extension - //! Takes as input the result of the parse_function, and outputs various properties of the resulting plan - plan_function_t plan_function; +* vector: The list vector. +* required_capacity: the total capacity to reserve. +* return: The duckdb state. Returns DuckDBError if the vector is nullptr. +*/ +DUCKDB_API duckdb_state duckdb_list_vector_reserve(duckdb_vector vector, idx_t required_capacity); - //! Additional parser info passed to the parse function - shared_ptr parser_info; -}; +/*! +Retrieves the child vector of a struct vector. -} // namespace duckdb +The resulting vector is valid as long as the parent vector is valid. -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/operator_extension.hpp -// -// -//===----------------------------------------------------------------------===// +* vector: The vector +* index: The child index +* returns: The child vector +*/ +DUCKDB_API duckdb_vector duckdb_struct_vector_get_child(duckdb_vector vector, idx_t index); +//===--------------------------------------------------------------------===// +// Validity Mask Functions +//===--------------------------------------------------------------------===// +/*! +Returns whether or not a row is valid (i.e. not NULL) in the given validity mask. +* validity: The validity mask, as obtained through `duckdb_data_chunk_get_validity` +* row: The row index +* returns: true if the row is valid, false otherwise +*/ +DUCKDB_API bool duckdb_validity_row_is_valid(uint64_t *validity, idx_t row); +/*! +In a validity mask, sets a specific row to either valid or invalid. -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/execution/physical_plan_generator.hpp -// -// -//===----------------------------------------------------------------------===// +Note that `duckdb_data_chunk_ensure_validity_writable` should be called before calling `duckdb_data_chunk_get_validity`, +to ensure that there is a validity mask to write to. +* validity: The validity mask, as obtained through `duckdb_data_chunk_get_validity`. +* row: The row index +* valid: Whether or not to set the row to valid, or invalid +*/ +DUCKDB_API void duckdb_validity_set_row_validity(uint64_t *validity, idx_t row, bool valid); +/*! +In a validity mask, sets a specific row to invalid. +Equivalent to `duckdb_validity_set_row_validity` with valid set to false. +* validity: The validity mask +* row: The row index +*/ +DUCKDB_API void duckdb_validity_set_row_invalid(uint64_t *validity, idx_t row); +/*! +In a validity mask, sets a specific row to valid. +Equivalent to `duckdb_validity_set_row_validity` with valid set to true. -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/operator/logical_limit_percent.hpp -// -// -//===----------------------------------------------------------------------===// +* validity: The validity mask +* row: The row index +*/ +DUCKDB_API void duckdb_validity_set_row_valid(uint64_t *validity, idx_t row); +//===--------------------------------------------------------------------===// +// Table Functions +//===--------------------------------------------------------------------===// +typedef void *duckdb_table_function; +typedef void *duckdb_bind_info; +typedef void *duckdb_init_info; +typedef void *duckdb_function_info; +typedef void (*duckdb_table_function_bind_t)(duckdb_bind_info info); +typedef void (*duckdb_table_function_init_t)(duckdb_init_info info); +typedef void (*duckdb_table_function_t)(duckdb_function_info info, duckdb_data_chunk output); +typedef void (*duckdb_delete_callback_t)(void *data); +/*! +Creates a new empty table function. +The return value should be destroyed with `duckdb_destroy_table_function`. -namespace duckdb { +* returns: The table function object. +*/ +DUCKDB_API duckdb_table_function duckdb_create_table_function(); -//! LogicalLimitPercent represents a LIMIT PERCENT clause -class LogicalLimitPercent : public LogicalOperator { -public: - LogicalLimitPercent(double limit_percent, int64_t offset_val, unique_ptr limit, - unique_ptr offset) - : LogicalOperator(LogicalOperatorType::LOGICAL_LIMIT_PERCENT), limit_percent(limit_percent), - offset_val(offset_val), limit(move(limit)), offset(move(offset)) { - } +/*! +Destroys the given table function object. - //! Limit percent and offset values in case they are constants, used in optimizations. - double limit_percent; - int64_t offset_val; - //! The maximum amount of elements to emit - unique_ptr limit; - //! The offset from the start to begin emitting elements - unique_ptr offset; +* table_function: The table function to destroy +*/ +DUCKDB_API void duckdb_destroy_table_function(duckdb_table_function *table_function); -public: - vector GetColumnBindings() override { - return children[0]->GetColumnBindings(); - } +/*! +Sets the name of the given table function. - void Serialize(FieldWriter &writer) const override; - static unique_ptr Deserialize(LogicalDeserializationState &state, FieldReader &reader); - idx_t EstimateCardinality(ClientContext &context) override; +* table_function: The table function +* name: The name of the table function +*/ +DUCKDB_API void duckdb_table_function_set_name(duckdb_table_function table_function, const char *name); -protected: - void ResolveTypes() override { - types = children[0]->types; - } -}; -} // namespace duckdb +/*! +Adds a parameter to the table function. +* table_function: The table function +* type: The type of the parameter to add. +*/ +DUCKDB_API void duckdb_table_function_add_parameter(duckdb_table_function table_function, duckdb_logical_type type); +/*! +Assigns extra information to the table function that can be fetched during binding, etc. +* table_function: The table function +* extra_info: The extra information +* destroy: The callback that will be called to destroy the bind data (if any) +*/ +DUCKDB_API void duckdb_table_function_set_extra_info(duckdb_table_function table_function, void *extra_info, + duckdb_delete_callback_t destroy); -namespace duckdb { -class ClientContext; -class ColumnDataCollection; +/*! +Sets the bind function of the table function -//! The physical plan generator generates a physical execution plan from a -//! logical query plan -class PhysicalPlanGenerator { -public: - explicit PhysicalPlanGenerator(ClientContext &context); - ~PhysicalPlanGenerator(); +* table_function: The table function +* bind: The bind function +*/ +DUCKDB_API void duckdb_table_function_set_bind(duckdb_table_function table_function, duckdb_table_function_bind_t bind); - unordered_set dependencies; - //! Recursive CTEs require at least one ChunkScan, referencing the working_table. - //! This data structure is used to establish it. - unordered_map> recursive_cte_tables; +/*! +Sets the init function of the table function -public: - //! Creates a plan from the logical operator. This involves resolving column bindings and generating physical - //! operator nodes. - unique_ptr CreatePlan(unique_ptr logical); +* table_function: The table function +* init: The init function +*/ +DUCKDB_API void duckdb_table_function_set_init(duckdb_table_function table_function, duckdb_table_function_init_t init); - //! Whether or not we can (or should) use a batch-index based operator for executing the given sink - static bool UseBatchIndex(ClientContext &context, PhysicalOperator &plan); - //! Whether or not we should preserve insertion order for executing the given sink - static bool PreserveInsertionOrder(ClientContext &context, PhysicalOperator &plan); +/*! +Sets the thread-local init function of the table function -protected: - unique_ptr CreatePlan(LogicalOperator &op); +* table_function: The table function +* init: The init function +*/ +DUCKDB_API void duckdb_table_function_set_local_init(duckdb_table_function table_function, + duckdb_table_function_init_t init); - unique_ptr CreatePlan(LogicalAggregate &op); - unique_ptr CreatePlan(LogicalAnyJoin &op); - unique_ptr CreatePlan(LogicalColumnDataGet &op); - unique_ptr CreatePlan(LogicalComparisonJoin &op); - unique_ptr CreatePlan(LogicalCreate &op); - unique_ptr CreatePlan(LogicalCreateTable &op); - unique_ptr CreatePlan(LogicalCreateIndex &op); - unique_ptr CreatePlan(LogicalCrossProduct &op); - unique_ptr CreatePlan(LogicalDelete &op); - unique_ptr CreatePlan(LogicalDelimGet &op); - unique_ptr CreatePlan(LogicalDelimJoin &op); - unique_ptr CreatePlan(LogicalDistinct &op); - unique_ptr CreatePlan(LogicalDummyScan &expr); - unique_ptr CreatePlan(LogicalEmptyResult &op); - unique_ptr CreatePlan(LogicalExpressionGet &op); - unique_ptr CreatePlan(LogicalExport &op); - unique_ptr CreatePlan(LogicalFilter &op); - unique_ptr CreatePlan(LogicalGet &op); - unique_ptr CreatePlan(LogicalLimit &op); - unique_ptr CreatePlan(LogicalLimitPercent &op); - unique_ptr CreatePlan(LogicalOrder &op); - unique_ptr CreatePlan(LogicalTopN &op); - unique_ptr CreatePlan(LogicalProjection &op); - unique_ptr CreatePlan(LogicalInsert &op); - unique_ptr CreatePlan(LogicalCopyToFile &op); - unique_ptr CreatePlan(LogicalExplain &op); - unique_ptr CreatePlan(LogicalSetOperation &op); - unique_ptr CreatePlan(LogicalUpdate &op); - unique_ptr CreatePlan(LogicalPrepare &expr); - unique_ptr CreatePlan(LogicalWindow &expr); - unique_ptr CreatePlan(LogicalExecute &op); - unique_ptr CreatePlan(LogicalPragma &op); - unique_ptr CreatePlan(LogicalSample &op); - unique_ptr CreatePlan(LogicalSet &op); - unique_ptr CreatePlan(LogicalShow &op); - unique_ptr CreatePlan(LogicalSimple &op); - unique_ptr CreatePlan(LogicalUnnest &op); - unique_ptr CreatePlan(LogicalRecursiveCTE &op); - unique_ptr CreatePlan(LogicalCTERef &op); +/*! +Sets the main function of the table function - unique_ptr CreateDistinctOn(unique_ptr child, - vector> distinct_targets); +* table_function: The table function +* function: The function +*/ +DUCKDB_API void duckdb_table_function_set_function(duckdb_table_function table_function, + duckdb_table_function_t function); - unique_ptr ExtractAggregateExpressions(unique_ptr child, - vector> &expressions, - vector> &groups); +/*! +Sets whether or not the given table function supports projection pushdown. -private: - bool PreserveInsertionOrder(PhysicalOperator &plan); - bool UseBatchIndex(PhysicalOperator &plan); +If this is set to true, the system will provide a list of all required columns in the `init` stage through +the `duckdb_init_get_column_count` and `duckdb_init_get_column_index` functions. +If this is set to false (the default), the system will expect all columns to be projected. -private: - ClientContext &context; -}; -} // namespace duckdb +* table_function: The table function +* pushdown: True if the table function supports projection pushdown, false otherwise. +*/ +DUCKDB_API void duckdb_table_function_supports_projection_pushdown(duckdb_table_function table_function, bool pushdown); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/binder.hpp -// -// -//===----------------------------------------------------------------------===// +/*! +Register the table function object within the given connection. +The function requires at least a name, a bind function, an init function and a main function. +If the function is incomplete or a function with this name already exists DuckDBError is returned. +* con: The connection to register it in. +* function: The function pointer +* returns: Whether or not the registration was successful. +*/ +DUCKDB_API duckdb_state duckdb_register_table_function(duckdb_connection con, duckdb_table_function function); +//===--------------------------------------------------------------------===// +// Table Function Bind +//===--------------------------------------------------------------------===// +/*! +Retrieves the extra info of the function as set in `duckdb_table_function_set_extra_info` -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/tokens.hpp -// -// -//===----------------------------------------------------------------------===// +* info: The info object +* returns: The extra info +*/ +DUCKDB_API void *duckdb_bind_get_extra_info(duckdb_bind_info info); +/*! +Adds a result column to the output of the table function. +* info: The info object +* name: The name of the column +* type: The logical type of the column +*/ +DUCKDB_API void duckdb_bind_add_result_column(duckdb_bind_info info, const char *name, duckdb_logical_type type); -namespace duckdb { +/*! +Retrieves the number of regular (non-named) parameters to the function. -//===--------------------------------------------------------------------===// -// Statements -//===--------------------------------------------------------------------===// -class SQLStatement; +* info: The info object +* returns: The number of parameters +*/ +DUCKDB_API idx_t duckdb_bind_get_parameter_count(duckdb_bind_info info); -class AlterStatement; -class CallStatement; -class CopyStatement; -class CreateStatement; -class DeleteStatement; -class DropStatement; -class ExtensionStatement; -class InsertStatement; -class SelectStatement; -class TransactionStatement; -class UpdateStatement; -class PrepareStatement; -class ExecuteStatement; -class PragmaStatement; -class ShowStatement; -class ExplainStatement; -class ExportStatement; -class VacuumStatement; -class RelationStatement; -class SetStatement; -class LoadStatement; -class LogicalPlanStatement; +/*! +Retrieves the parameter at the given index. -//===--------------------------------------------------------------------===// -// Query Node -//===--------------------------------------------------------------------===// -class QueryNode; -class SelectNode; -class SetOperationNode; -class RecursiveCTENode; +The result must be destroyed with `duckdb_destroy_value`. -//===--------------------------------------------------------------------===// -// Expressions -//===--------------------------------------------------------------------===// -class ParsedExpression; +* info: The info object +* index: The index of the parameter to get +* returns: The value of the parameter. Must be destroyed with `duckdb_destroy_value`. +*/ +DUCKDB_API duckdb_value duckdb_bind_get_parameter(duckdb_bind_info info, idx_t index); -class BetweenExpression; -class CaseExpression; -class CastExpression; -class CollateExpression; -class ColumnRefExpression; -class ComparisonExpression; -class ConjunctionExpression; -class ConstantExpression; -class DefaultExpression; -class FunctionExpression; -class LambdaExpression; -class OperatorExpression; -class ParameterExpression; -class PositionalReferenceExpression; -class StarExpression; -class SubqueryExpression; -class WindowExpression; +/*! +Sets the user-provided bind data in the bind object. This object can be retrieved again during execution. -//===--------------------------------------------------------------------===// -// Constraints -//===--------------------------------------------------------------------===// -class Constraint; +* info: The info object +* extra_data: The bind data object. +* destroy: The callback that will be called to destroy the bind data (if any) +*/ +DUCKDB_API void duckdb_bind_set_bind_data(duckdb_bind_info info, void *bind_data, duckdb_delete_callback_t destroy); -class NotNullConstraint; -class CheckConstraint; -class UniqueConstraint; -class ForeignKeyConstraint; +/*! +Sets the cardinality estimate for the table function, used for optimization. -//===--------------------------------------------------------------------===// -// TableRefs -//===--------------------------------------------------------------------===// -class TableRef; +* info: The bind data object. +* is_exact: Whether or not the cardinality estimate is exact, or an approximation +*/ +DUCKDB_API void duckdb_bind_set_cardinality(duckdb_bind_info info, idx_t cardinality, bool is_exact); -class BaseTableRef; -class CrossProductRef; -class JoinRef; -class SubqueryRef; -class TableFunctionRef; -class EmptyTableRef; -class ExpressionListRef; +/*! +Report that an error has occurred while calling bind. + +* info: The info object +* error: The error message +*/ +DUCKDB_API void duckdb_bind_set_error(duckdb_bind_info info, const char *error); //===--------------------------------------------------------------------===// -// Other +// Table Function Init //===--------------------------------------------------------------------===// -struct SampleOptions; -} // namespace duckdb +/*! +Retrieves the extra info of the function as set in `duckdb_table_function_set_extra_info` -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/bind_context.hpp -// -// -//===----------------------------------------------------------------------===// +* info: The info object +* returns: The extra info +*/ +DUCKDB_API void *duckdb_init_get_extra_info(duckdb_init_info info); +/*! +Gets the bind data set by `duckdb_bind_set_bind_data` during the bind. +Note that the bind data should be considered as read-only. +For tracking state, use the init data instead. +* info: The info object +* returns: The bind data object +*/ +DUCKDB_API void *duckdb_init_get_bind_data(duckdb_init_info info); +/*! +Sets the user-provided init data in the init object. This object can be retrieved again during execution. -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/catalog/catalog_entry/table_function_catalog_entry.hpp -// -// -//===----------------------------------------------------------------------===// +* info: The info object +* extra_data: The init data object. +* destroy: The callback that will be called to destroy the init data (if any) +*/ +DUCKDB_API void duckdb_init_set_init_data(duckdb_init_info info, void *init_data, duckdb_delete_callback_t destroy); +/*! +Returns the number of projected columns. +This function must be used if projection pushdown is enabled to figure out which columns to emit. +* info: The info object +* returns: The number of projected columns. +*/ +DUCKDB_API idx_t duckdb_init_get_column_count(duckdb_init_info info); +/*! +Returns the column index of the projected column at the specified position. +This function must be used if projection pushdown is enabled to figure out which columns to emit. -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/function/function_set.hpp -// -// -//===----------------------------------------------------------------------===// +* info: The info object +* column_index: The index at which to get the projected column index, from 0..duckdb_init_get_column_count(info) +* returns: The column index of the projected column. +*/ +DUCKDB_API idx_t duckdb_init_get_column_index(duckdb_init_info info, idx_t column_index); +/*! +Sets how many threads can process this table function in parallel (default: 1) +* info: The info object +* max_threads: The maximum amount of threads that can process this table function +*/ +DUCKDB_API void duckdb_init_set_max_threads(duckdb_init_info info, idx_t max_threads); +/*! +Report that an error has occurred while calling init. +* info: The info object +* error: The error message +*/ +DUCKDB_API void duckdb_init_set_error(duckdb_init_info info, const char *error); +//===--------------------------------------------------------------------===// +// Table Function +//===--------------------------------------------------------------------===// -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/function/pragma_function.hpp -// -// -//===----------------------------------------------------------------------===// +/*! +Retrieves the extra info of the function as set in `duckdb_table_function_set_extra_info` +* info: The info object +* returns: The extra info +*/ +DUCKDB_API void *duckdb_function_get_extra_info(duckdb_function_info info); +/*! +Gets the bind data set by `duckdb_bind_set_bind_data` during the bind. +Note that the bind data should be considered as read-only. +For tracking state, use the init data instead. +* info: The info object +* returns: The bind data object +*/ +DUCKDB_API void *duckdb_function_get_bind_data(duckdb_function_info info); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/parsed_data/pragma_info.hpp -// -// -//===----------------------------------------------------------------------===// +/*! +Gets the init data set by `duckdb_init_set_init_data` during the init. +* info: The info object +* returns: The init data object +*/ +DUCKDB_API void *duckdb_function_get_init_data(duckdb_function_info info); +/*! +Gets the thread-local init data set by `duckdb_init_set_init_data` during the local_init. +* info: The info object +* returns: The init data object +*/ +DUCKDB_API void *duckdb_function_get_local_init_data(duckdb_function_info info); +/*! +Report that an error has occurred while executing the function. +* info: The info object +* error: The error message +*/ +DUCKDB_API void duckdb_function_set_error(duckdb_function_info info, const char *error); +//===--------------------------------------------------------------------===// +// Replacement Scans +//===--------------------------------------------------------------------===// +typedef void *duckdb_replacement_scan_info; +typedef void (*duckdb_replacement_callback_t)(duckdb_replacement_scan_info info, const char *table_name, void *data); -namespace duckdb { +/*! +Add a replacement scan definition to the specified database -enum class PragmaType : uint8_t { PRAGMA_STATEMENT, PRAGMA_CALL }; +* db: The database object to add the replacement scan to +* replacement: The replacement scan callback +* extra_data: Extra data that is passed back into the specified callback +* delete_callback: The delete callback to call on the extra data, if any +*/ +DUCKDB_API void duckdb_add_replacement_scan(duckdb_database db, duckdb_replacement_callback_t replacement, + void *extra_data, duckdb_delete_callback_t delete_callback); -struct PragmaInfo : public ParseInfo { - //! Name of the PRAGMA statement - string name; - //! Parameter list (if any) - vector parameters; - //! Named parameter list (if any) - named_parameter_map_t named_parameters; +/*! +Sets the replacement function name to use. If this function is called in the replacement callback, + the replacement scan is performed. If it is not called, the replacement callback is not performed. -public: - unique_ptr Copy() const { - auto result = make_unique(); - result->name = name; - result->parameters = parameters; - result->named_parameters = named_parameters; - return result; - } -}; +* info: The info object +* function_name: The function name to substitute. +*/ +DUCKDB_API void duckdb_replacement_scan_set_function_name(duckdb_replacement_scan_info info, const char *function_name); -} // namespace duckdb +/*! +Adds a parameter to the replacement scan function. +* info: The info object +* parameter: The parameter to add. +*/ +DUCKDB_API void duckdb_replacement_scan_add_parameter(duckdb_replacement_scan_info info, duckdb_value parameter); +/*! +Report that an error has occurred while executing the replacement scan. -namespace duckdb { -class ClientContext; +* info: The info object +* error: The error message +*/ +DUCKDB_API void duckdb_replacement_scan_set_error(duckdb_replacement_scan_info info, const char *error); -//! Return a substitute query to execute instead of this pragma statement -typedef string (*pragma_query_t)(ClientContext &context, const FunctionParameters ¶meters); -//! Execute the main pragma function -typedef void (*pragma_function_t)(ClientContext &context, const FunctionParameters ¶meters); +//===--------------------------------------------------------------------===// +// Appender +//===--------------------------------------------------------------------===// -//! Pragma functions are invoked by calling PRAGMA x -//! Pragma functions come in three types: -//! * Call: function call, e.g. PRAGMA table_info('tbl') -//! -> call statements can take multiple parameters -//! * Statement: statement without parameters, e.g. PRAGMA show_tables -//! -> this is similar to a call pragma but without parameters -//! Pragma functions can either return a new query to execute (pragma_query_t) -//! or they can -class PragmaFunction : public SimpleNamedParameterFunction { -public: - // Call - DUCKDB_API static PragmaFunction PragmaCall(const string &name, pragma_query_t query, vector arguments, - LogicalType varargs = LogicalType::INVALID); - DUCKDB_API static PragmaFunction PragmaCall(const string &name, pragma_function_t function, - vector arguments, - LogicalType varargs = LogicalType::INVALID); - // Statement - DUCKDB_API static PragmaFunction PragmaStatement(const string &name, pragma_query_t query); - DUCKDB_API static PragmaFunction PragmaStatement(const string &name, pragma_function_t function); +// Appenders are the most efficient way of loading data into DuckDB from within the C interface, and are recommended for +// fast data loading. The appender is much faster than using prepared statements or individual `INSERT INTO` statements. - DUCKDB_API string ToString() override; +// Appends are made in row-wise format. For every column, a `duckdb_append_[type]` call should be made, after which +// the row should be finished by calling `duckdb_appender_end_row`. After all rows have been appended, +// `duckdb_appender_destroy` should be used to finalize the appender and clean up the resulting memory. -public: - PragmaType type; +// Note that `duckdb_appender_destroy` should always be called on the resulting appender, even if the function returns +// `DuckDBError`. - pragma_query_t query; - pragma_function_t function; - named_parameter_type_map_t named_parameters; +/*! +Creates an appender object. -private: - PragmaFunction(string name, PragmaType pragma_type, pragma_query_t query, pragma_function_t function, - vector arguments, LogicalType varargs); -}; +* connection: The connection context to create the appender in. +* schema: The schema of the table to append to, or `nullptr` for the default schema. +* table: The table name to append to. +* out_appender: The resulting appender object. +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_appender_create(duckdb_connection connection, const char *schema, const char *table, + duckdb_appender *out_appender); -} // namespace duckdb +/*! +Returns the error message associated with the given appender. +If the appender has no error message, this returns `nullptr` instead. +The error message should not be freed. It will be de-allocated when `duckdb_appender_destroy` is called. -namespace duckdb { +* appender: The appender to get the error from. +* returns: The error message, or `nullptr` if there is none. +*/ +DUCKDB_API const char *duckdb_appender_error(duckdb_appender appender); -template -class FunctionSet { -public: - explicit FunctionSet(string name) : name(name) { - } +/*! +Flush the appender to the table, forcing the cache of the appender to be cleared and the data to be appended to the +base table. - //! The name of the function set - string name; - //! The set of functions. - vector functions; +This should generally not be used unless you know what you are doing. Instead, call `duckdb_appender_destroy` when you +are done with the appender. -public: - void AddFunction(T function) { - functions.push_back(move(function)); - } - idx_t Size() { - return functions.size(); - } - T GetFunctionByOffset(idx_t offset) { - return functions[offset]; - } - T &GetFunctionReferenceByOffset(idx_t offset) { - return functions[offset]; - } - bool MergeFunctionSet(FunctionSet new_functions) { - D_ASSERT(!new_functions.functions.empty()); - bool need_rewrite_entry = false; - for (auto &new_func : new_functions.functions) { - bool can_add = true; - for (auto &func : functions) { - if (new_func.Equal(func)) { - can_add = false; - break; - } - } - if (can_add) { - functions.push_back(new_func); - need_rewrite_entry = true; - } - } - return need_rewrite_entry; - } -}; +* appender: The appender to flush. +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_appender_flush(duckdb_appender appender); -class ScalarFunctionSet : public FunctionSet { -public: - DUCKDB_API explicit ScalarFunctionSet(string name); +/*! +Close the appender, flushing all intermediate state in the appender to the table and closing it for further appends. - DUCKDB_API ScalarFunction GetFunctionByArguments(ClientContext &context, const vector &arguments); -}; +This is generally not necessary. Call `duckdb_appender_destroy` instead. -class AggregateFunctionSet : public FunctionSet { -public: - DUCKDB_API explicit AggregateFunctionSet(string name); +* appender: The appender to flush and close. +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_appender_close(duckdb_appender appender); - DUCKDB_API AggregateFunction GetFunctionByArguments(ClientContext &context, const vector &arguments); -}; +/*! +Close the appender and destroy it. Flushing all intermediate state in the appender to the table, and de-allocating +all memory associated with the appender. -class TableFunctionSet : public FunctionSet { -public: - DUCKDB_API explicit TableFunctionSet(string name); +* appender: The appender to flush, close and destroy. +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_appender_destroy(duckdb_appender *appender); - TableFunction GetFunctionByArguments(ClientContext &context, const vector &arguments); -}; +/*! +A nop function, provided for backwards compatibility reasons. Does nothing. Only `duckdb_appender_end_row` is required. +*/ +DUCKDB_API duckdb_state duckdb_appender_begin_row(duckdb_appender appender); -class PragmaFunctionSet : public FunctionSet { -public: - explicit PragmaFunctionSet(string name) : FunctionSet(move(name)) { - } -}; +/*! +Finish the current row of appends. After end_row is called, the next row can be appended. -} // namespace duckdb +* appender: The appender. +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_appender_end_row(duckdb_appender appender); +/*! +Append a bool value to the appender. +*/ +DUCKDB_API duckdb_state duckdb_append_bool(duckdb_appender appender, bool value); -namespace duckdb { +/*! +Append an int8_t value to the appender. +*/ +DUCKDB_API duckdb_state duckdb_append_int8(duckdb_appender appender, int8_t value); +/*! +Append an int16_t value to the appender. +*/ +DUCKDB_API duckdb_state duckdb_append_int16(duckdb_appender appender, int16_t value); +/*! +Append an int32_t value to the appender. +*/ +DUCKDB_API duckdb_state duckdb_append_int32(duckdb_appender appender, int32_t value); +/*! +Append an int64_t value to the appender. +*/ +DUCKDB_API duckdb_state duckdb_append_int64(duckdb_appender appender, int64_t value); +/*! +Append a duckdb_hugeint value to the appender. +*/ +DUCKDB_API duckdb_state duckdb_append_hugeint(duckdb_appender appender, duckdb_hugeint value); -class Catalog; -class Constraint; +/*! +Append a uint8_t value to the appender. +*/ +DUCKDB_API duckdb_state duckdb_append_uint8(duckdb_appender appender, uint8_t value); +/*! +Append a uint16_t value to the appender. +*/ +DUCKDB_API duckdb_state duckdb_append_uint16(duckdb_appender appender, uint16_t value); +/*! +Append a uint32_t value to the appender. +*/ +DUCKDB_API duckdb_state duckdb_append_uint32(duckdb_appender appender, uint32_t value); +/*! +Append a uint64_t value to the appender. +*/ +DUCKDB_API duckdb_state duckdb_append_uint64(duckdb_appender appender, uint64_t value); -struct CreateTableFunctionInfo; +/*! +Append a float value to the appender. +*/ +DUCKDB_API duckdb_state duckdb_append_float(duckdb_appender appender, float value); +/*! +Append a double value to the appender. +*/ +DUCKDB_API duckdb_state duckdb_append_double(duckdb_appender appender, double value); -//! A table function in the catalog -class TableFunctionCatalogEntry : public StandardEntry { -public: - TableFunctionCatalogEntry(Catalog *catalog, SchemaCatalogEntry *schema, CreateTableFunctionInfo *info); +/*! +Append a duckdb_date value to the appender. +*/ +DUCKDB_API duckdb_state duckdb_append_date(duckdb_appender appender, duckdb_date value); +/*! +Append a duckdb_time value to the appender. +*/ +DUCKDB_API duckdb_state duckdb_append_time(duckdb_appender appender, duckdb_time value); +/*! +Append a duckdb_timestamp value to the appender. +*/ +DUCKDB_API duckdb_state duckdb_append_timestamp(duckdb_appender appender, duckdb_timestamp value); +/*! +Append a duckdb_interval value to the appender. +*/ +DUCKDB_API duckdb_state duckdb_append_interval(duckdb_appender appender, duckdb_interval value); - //! The table function - TableFunctionSet functions; -}; -} // namespace duckdb +/*! +Append a varchar value to the appender. +*/ +DUCKDB_API duckdb_state duckdb_append_varchar(duckdb_appender appender, const char *val); +/*! +Append a varchar value to the appender. +*/ +DUCKDB_API duckdb_state duckdb_append_varchar_length(duckdb_appender appender, const char *val, idx_t length); +/*! +Append a blob value to the appender. +*/ +DUCKDB_API duckdb_state duckdb_append_blob(duckdb_appender appender, const void *data, idx_t length); +/*! +Append a NULL value to the appender (of any type). +*/ +DUCKDB_API duckdb_state duckdb_append_null(duckdb_appender appender); +/*! +Appends a pre-filled data chunk to the specified appender. +The types of the data chunk must exactly match the types of the table, no casting is performed. +If the types do not match or the appender is in an invalid state, DuckDBError is returned. +If the append is successful, DuckDBSuccess is returned. +* appender: The appender to append to. +* chunk: The data chunk to append. +* returns: The return state. +*/ +DUCKDB_API duckdb_state duckdb_append_data_chunk(duckdb_appender appender, duckdb_data_chunk chunk); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/expression/columnref_expression.hpp -// -// -//===----------------------------------------------------------------------===// +//===--------------------------------------------------------------------===// +// Arrow Interface +//===--------------------------------------------------------------------===// +/*! +Executes a SQL query within a connection and stores the full (materialized) result in an arrow structure. +If the query fails to execute, DuckDBError is returned and the error message can be retrieved by calling +`duckdb_query_arrow_error`. +Note that after running `duckdb_query_arrow`, `duckdb_destroy_arrow` must be called on the result object even if the +query fails, otherwise the error stored within the result will not be freed correctly. +* connection: The connection to perform the query in. +* query: The SQL query to run. +* out_result: The query result. +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_query_arrow(duckdb_connection connection, const char *query, duckdb_arrow *out_result); +/*! +Fetch the internal arrow schema from the arrow result. +* result: The result to fetch the schema from. +* out_schema: The output schema. +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_query_arrow_schema(duckdb_arrow result, duckdb_arrow_schema *out_schema); +/*! +Fetch an internal arrow array from the arrow result. -namespace duckdb { +This function can be called multiple time to get next chunks, which will free the previous out_array. +So consume the out_array before calling this function again. -//! Represents a reference to a column from either the FROM clause or from an -//! alias -class ColumnRefExpression : public ParsedExpression { -public: - //! Specify both the column and table name - ColumnRefExpression(string column_name, string table_name); - //! Only specify the column name, the table name will be derived later - explicit ColumnRefExpression(string column_name); - //! Specify a set of names - explicit ColumnRefExpression(vector column_names); +* result: The result to fetch the array from. +* out_array: The output array. +* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +*/ +DUCKDB_API duckdb_state duckdb_query_arrow_array(duckdb_arrow result, duckdb_arrow_array *out_array); - //! The stack of names in order of which they appear (column_names[0].column_names[1].column_names[2]....) - vector column_names; +/*! +Returns the number of columns present in a the arrow result object. -public: - bool IsQualified() const; - const string &GetColumnName() const; - const string &GetTableName() const; - bool IsScalar() const override { - return false; - } +* result: The result object. +* returns: The number of columns present in the result object. +*/ +DUCKDB_API idx_t duckdb_arrow_column_count(duckdb_arrow result); - string GetName() const override; - string ToString() const override; +/*! +Returns the number of rows present in a the arrow result object. - static bool Equals(const ColumnRefExpression *a, const ColumnRefExpression *b); - hash_t Hash() const override; +* result: The result object. +* returns: The number of rows present in the result object. +*/ +DUCKDB_API idx_t duckdb_arrow_row_count(duckdb_arrow result); - unique_ptr Copy() const override; +/*! +Returns the number of rows changed by the query stored in the arrow result. This is relevant only for +INSERT/UPDATE/DELETE queries. For other queries the rows_changed will be 0. - void Serialize(FieldWriter &writer) const override; - static unique_ptr Deserialize(ExpressionType type, FieldReader &source); -}; -} // namespace duckdb +* result: The result object. +* returns: The number of rows changed. +*/ +DUCKDB_API idx_t duckdb_arrow_rows_changed(duckdb_arrow result); +/*! +Returns the error message contained within the result. The error is only set if `duckdb_query_arrow` returns +`DuckDBError`. -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/qualified_name_set.hpp -// -// -//===----------------------------------------------------------------------===// +The error message should not be freed. It will be de-allocated when `duckdb_destroy_arrow` is called. +* result: The result object to fetch the nullmask from. +* returns: The error of the result. +*/ +DUCKDB_API const char *duckdb_query_arrow_error(duckdb_arrow result); +/*! +Closes the result and de-allocates all memory allocated for the arrow result. +* result: The result to destroy. +*/ +DUCKDB_API void duckdb_destroy_arrow(duckdb_arrow *result); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/types/hash.hpp -// -// -//===----------------------------------------------------------------------===// +//===--------------------------------------------------------------------===// +// Threading Information +//===--------------------------------------------------------------------===// +typedef void *duckdb_task_state; +/*! +Execute DuckDB tasks on this thread. +Will return after `max_tasks` have been executed, or if there are no more tasks present. +* database: The database object to execute tasks for +* max_tasks: The maximum amount of tasks to execute +*/ +DUCKDB_API void duckdb_execute_tasks(duckdb_database database, idx_t max_tasks); +/*! +Creates a task state that can be used with duckdb_execute_tasks_state to execute tasks until + duckdb_finish_execution is called on the state. +duckdb_destroy_state should be called on the result in order to free memory. -namespace duckdb { +* database: The database object to create the task state for +* returns: The task state that can be used with duckdb_execute_tasks_state. +*/ +DUCKDB_API duckdb_task_state duckdb_create_task_state(duckdb_database database); -struct string_t; -struct interval_t; +/*! +Execute DuckDB tasks on this thread. -// efficient hash function that maximizes the avalanche effect and minimizes -// bias -// see: https://nullprogram.com/blog/2018/07/31/ +The thread will keep on executing tasks forever, until duckdb_finish_execution is called on the state. +Multiple threads can share the same duckdb_task_state. -inline hash_t murmurhash64(uint64_t x) { - x ^= x >> 32; - x *= 0xd6e8feb86659fd93U; - x ^= x >> 32; - x *= 0xd6e8feb86659fd93U; - x ^= x >> 32; - return x; -} +* state: The task state of the executor +*/ +DUCKDB_API void duckdb_execute_tasks_state(duckdb_task_state state); -inline hash_t murmurhash32(uint32_t x) { - return murmurhash64(x); -} +/*! +Execute DuckDB tasks on this thread. -template -hash_t Hash(T value) { - return murmurhash32(value); -} +The thread will keep on executing tasks until either duckdb_finish_execution is called on the state, +max_tasks tasks have been executed or there are no more tasks to be executed. -//! Combine two hashes by XORing them -inline hash_t CombineHash(hash_t left, hash_t right) { - return left ^ right; -} +Multiple threads can share the same duckdb_task_state. -template <> -DUCKDB_API hash_t Hash(uint64_t val); -template <> -DUCKDB_API hash_t Hash(int64_t val); -template <> -DUCKDB_API hash_t Hash(hugeint_t val); -template <> -DUCKDB_API hash_t Hash(float val); -template <> -DUCKDB_API hash_t Hash(double val); -template <> -DUCKDB_API hash_t Hash(const char *val); -template <> -DUCKDB_API hash_t Hash(char *val); -template <> -DUCKDB_API hash_t Hash(string_t val); -template <> -DUCKDB_API hash_t Hash(interval_t val); -DUCKDB_API hash_t Hash(const char *val, size_t size); -DUCKDB_API hash_t Hash(uint8_t *val, size_t size); +* state: The task state of the executor +* max_tasks: The maximum amount of tasks to execute +* returns: The amount of tasks that have actually been executed +*/ +DUCKDB_API idx_t duckdb_execute_n_tasks_state(duckdb_task_state state, idx_t max_tasks); -} // namespace duckdb +/*! +Finish execution on a specific task. +* state: The task state to finish execution +*/ +DUCKDB_API void duckdb_finish_execution(duckdb_task_state state); +/*! +Check if the provided duckdb_task_state has finished execution -namespace duckdb { +* state: The task state to inspect +* returns: Whether or not duckdb_finish_execution has been called on the task state +*/ +DUCKDB_API bool duckdb_task_state_is_finished(duckdb_task_state state); -struct QualifiedColumnHashFunction { - uint64_t operator()(const QualifiedColumnName &a) const { - std::hash str_hasher; - return str_hasher(a.schema) ^ str_hasher(a.table) ^ str_hasher(a.column); - } -}; +/*! +Destroys the task state returned from duckdb_create_task_state. -struct QualifiedColumnEquality { - bool operator()(const QualifiedColumnName &a, const QualifiedColumnName &b) const { - return a.schema == b.schema && a.table == b.table && a.column == b.column; - } -}; +Note that this should not be called while there is an active duckdb_execute_tasks_state running +on the task state. -using qualified_column_set_t = unordered_set; +* state: The task state to clean up +*/ +DUCKDB_API void duckdb_destroy_task_state(duckdb_task_state state); + +/*! +Returns true if execution of the current query is finished. + +* con: The connection on which to check +*/ +DUCKDB_API bool duckdb_execution_is_finished(duckdb_connection con); + +#ifdef __cplusplus +} +#endif -} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/planner/expression_binder.hpp +// duckdb/common/profiler.hpp // // //===----------------------------------------------------------------------===// @@ -17878,495 +18145,638 @@ using qualified_column_set_t = unordered_set +class BaseProfiler { +public: + //! Starts the timer + void Start() { + finished = false; + start = Tick(); + } + //! Finishes timing + void End() { + end = Tick(); + finished = true; + } + + //! Returns the elapsed time in seconds. If End() has been called, returns + //! the total elapsed time. Otherwise returns how far along the timer is + //! right now. + double Elapsed() const { + auto _end = finished ? end : Tick(); + return std::chrono::duration_cast>(_end - start).count(); + } + +private: + time_point Tick() const { + return T::now(); + } + time_point start; + time_point end; + bool finished = false; +}; + +using Profiler = BaseProfiler; + +} // namespace duckdb + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/parser/expression/bound_expression.hpp +// duckdb/common/progress_bar/progress_bar_display.hpp // // //===----------------------------------------------------------------------===// +namespace duckdb { +class ProgressBarDisplay { +public: + ProgressBarDisplay() { + } + virtual ~ProgressBarDisplay() { + } +public: + virtual void Update(double percentage) = 0; + virtual void Finish() = 0; +}; +} // namespace duckdb namespace duckdb { -//! BoundExpression is an intermediate dummy class used by the binder. It is a ParsedExpression but holds an Expression. -//! It represents a successfully bound expression. It is used in the Binder to prevent re-binding of already bound parts -//! when dealing with subqueries. -class BoundExpression : public ParsedExpression { -public: - BoundExpression(unique_ptr expr); - - unique_ptr expr; +typedef unique_ptr (*progress_bar_display_create_func_t)(); +class ProgressBar { public: - string ToString() const override; + static unique_ptr DefaultProgressBarDisplay(); - bool Equals(const BaseExpression *other) const override; - hash_t Hash() const override; + explicit ProgressBar( + Executor &executor, idx_t show_progress_after, + progress_bar_display_create_func_t create_display_func = ProgressBar::DefaultProgressBarDisplay); - unique_ptr Copy() const override; + //! Starts the thread + void Start(); + //! Updates the progress bar and prints it to the screen + void Update(bool final); + //! Gets current percentage + double GetCurrentPercentage(); - void Serialize(FieldWriter &writer) const override; -}; + void PrintProgressInternal(int percentage); + void PrintProgress(int percentage); + void FinishProgressBarPrint(); + bool ShouldPrint(bool final) const; + bool PrintEnabled() const; +private: + //! The executor + Executor &executor; + //! The profiler used to measure the time since the progress bar was started + Profiler profiler; + //! The time in ms after which to start displaying the progress bar + idx_t show_progress_after; + //! The current progress percentage + double current_percentage; + //! The display used to print the progress + unique_ptr display; + //! Whether or not profiling is supported for the current query + bool supported = true; + //! Whether the bar has already finished + bool finished = false; +}; } // namespace duckdb +namespace duckdb { +class ClientContext; +class PhysicalResultCollector; +class PreparedStatementData; +typedef std::function(ClientContext &context, PreparedStatementData &data)> + get_result_collector_t; +struct ClientConfig { + //! The home directory used by the system (if any) + string home_directory; + //! If the query profiler is enabled or not. + bool enable_profiler = false; + //! If detailed query profiling is enabled + bool enable_detailed_profiling = false; + //! The format to print query profiling information in (default: query_tree), if enabled. + ProfilerPrintFormat profiler_print_format = ProfilerPrintFormat::QUERY_TREE; + //! The file to save query profiling information to, instead of printing it to the console + //! (empty = print to console) + string profiler_save_location; + //! Allows suppressing profiler output, even if enabled. We turn on the profiler on all test runs but don't want + //! to output anything + bool emit_profiler_output = true; -namespace duckdb { + //! If the progress bar is enabled or not. + bool enable_progress_bar = false; + //! If the print of the progress bar is enabled + bool print_progress_bar = true; + //! The wait time before showing the progress bar + int wait_time = 2000; -class Binder; -class ClientContext; -class QueryNode; + //! Preserve identifier case while parsing. + //! If false, all unquoted identifiers are lower-cased (e.g. "MyTable" -> "mytable"). + bool preserve_identifier_case = true; + //! The maximum expression depth limit in the parser + idx_t max_expression_depth = 1000; -class ScalarFunctionCatalogEntry; -class AggregateFunctionCatalogEntry; -class ScalarMacroCatalogEntry; -class CatalogEntry; -class SimpleFunction; + //! Whether or not aggressive query verification is enabled + bool query_verification_enabled = false; + //! Whether or not verification of external operators is enabled, used for testing + bool verify_external = false; + //! Whether or not we should verify the serializer + bool verify_serializer = false; + //! Enable the running of optimizers + bool enable_optimizer = true; + //! Force parallelism of small tables, used for testing + bool verify_parallelism = false; + //! Force index join independent of table cardinality, used for testing + bool force_index_join = false; + //! Force out-of-core computation for operators that support it, used for testing + bool force_external = false; + //! Force disable cross product generation when hyper graph isn't connected, used for testing + bool force_no_cross_product = false; + //! If this context should also try to use the available replacement scans + //! True by default + bool use_replacement_scans = true; + //! Maximum bits allowed for using a perfect hash table (i.e. the perfect HT can hold up to 2^perfect_ht_threshold + //! elements) + idx_t perfect_ht_threshold = 12; -struct DummyBinding; + //! Callback to create a progress bar display + progress_bar_display_create_func_t display_create_func = nullptr; -struct BoundColumnReferenceInfo { - string name; - idx_t query_location; -}; + //! Override for the default extension repository + string custom_extension_repo = ""; -struct BindResult { - BindResult() { - } - explicit BindResult(string error) : error(error) { - } - explicit BindResult(unique_ptr expr) : expression(move(expr)) { - } + //! The explain output type used when none is specified (default: PHYSICAL_ONLY) + ExplainOutputType explain_output_type = ExplainOutputType::PHYSICAL_ONLY; - bool HasError() { - return !error.empty(); - } + //! Generic options + case_insensitive_map_t set_variables; - unique_ptr expression; - string error; -}; + //! Function that is used to create the result collector for a materialized result + //! Defaults to PhysicalMaterializedCollector + get_result_collector_t result_collector = nullptr; -class ExpressionBinder { public: - ExpressionBinder(Binder &binder, ClientContext &context, bool replace_binder = false); - virtual ~ExpressionBinder(); - - //! The target type that should result from the binder. If the result is not of this type, a cast to this type will - //! be added. Defaults to INVALID. - LogicalType target_type; + static ClientConfig &GetConfig(ClientContext &context); + static const ClientConfig &GetConfig(const ClientContext &context); - DummyBinding *macro_binding; - vector *lambda_bindings = nullptr; + static string ExtractTimezoneFromConfig(ClientConfig &config); -public: - unique_ptr Bind(unique_ptr &expr, LogicalType *result_type = nullptr, - bool root_expression = true); + string ExtractTimezone() const; - //! Returns whether or not any columns have been bound by the expression binder - bool HasBoundColumns() { - return !bound_columns.empty(); - } - const vector &GetBoundColumns() { - return bound_columns; + bool AnyVerification() { + return query_verification_enabled || verify_external || verify_serializer; } +}; - string Bind(unique_ptr *expr, idx_t depth, bool root_expression = false); +} // namespace duckdb - unique_ptr CreateStructExtract(unique_ptr base, string field_name); - unique_ptr CreateStructPack(ColumnRefExpression &colref); - BindResult BindQualifiedColumnName(ColumnRefExpression &colref, const string &table_name); - unique_ptr QualifyColumnName(const string &column_name, string &error_message); - unique_ptr QualifyColumnName(ColumnRefExpression &colref, string &error_message); - // Bind table names to ColumnRefExpressions - void QualifyColumnNames(unique_ptr &expr); - static void QualifyColumnNames(Binder &binder, unique_ptr &expr); - static unique_ptr PushCollation(ClientContext &context, unique_ptr source, - const string &collation, bool equality_only = false); - static void TestCollation(ClientContext &context, const string &collation); +namespace duckdb { +class Appender; +class Catalog; +class CatalogSearchPath; +class ColumnDataCollection; +class DatabaseInstance; +class FileOpener; +class LogicalOperator; +class PreparedStatementData; +class Relation; +class BufferedFileWriter; +class QueryProfiler; +class ClientContextLock; +struct CreateScalarFunctionInfo; +class ScalarFunctionCatalogEntry; +struct ActiveQueryContext; +struct ParserOptions; +struct ClientData; - bool BindCorrelatedColumns(unique_ptr &expr); +struct PendingQueryParameters { + //! Prepared statement parameters (if any) + vector *parameters = nullptr; + //! Whether or not a stream result should be allowed + bool allow_stream_result = false; +}; - void BindChild(unique_ptr &expr, idx_t depth, string &error); - static void ExtractCorrelatedExpressions(Binder &binder, Expression &expr); +//! ClientContextState is virtual base class for ClientContext-local (or Query-Local, using QueryEnd callback) state +//! e.g. caches that need to live as long as a ClientContext or Query. +class ClientContextState { +public: + virtual ~ClientContextState() {}; + virtual void QueryEnd() = 0; +}; + +//! The ClientContext holds information relevant to the current client session +//! during execution +class ClientContext : public std::enable_shared_from_this { + friend class PendingQueryResult; + friend class StreamQueryResult; + friend class DuckTransactionManager; + +public: + DUCKDB_API explicit ClientContext(shared_ptr db); + DUCKDB_API ~ClientContext(); + + //! The database that this client is connected to + shared_ptr db; + //! Whether or not the query is interrupted + atomic interrupted; + //! External Objects (e.g., Python objects) that views depend of + unordered_map>> external_dependencies; + //! Set of optional states (e.g. Caches) that can be held by the ClientContext + unordered_map> registered_state; + //! The client configuration + ClientConfig config; + //! The set of client-specific data + unique_ptr client_data; + //! Data for the currently running transaction + TransactionContext transaction; - static bool ContainsNullType(const LogicalType &type); - static LogicalType ExchangeNullType(const LogicalType &type); - static bool ContainsType(const LogicalType &type, LogicalTypeId target); - static LogicalType ExchangeType(const LogicalType &type, LogicalTypeId target, LogicalType new_type); +public: + DUCKDB_API MetaTransaction &ActiveTransaction() { + return transaction.ActiveTransaction(); + } - //! Bind the given expresion. Unlike Bind(), this does *not* mute the given ParsedExpression. - //! Exposed to be used from sub-binders that aren't subclasses of ExpressionBinder. - virtual BindResult BindExpression(unique_ptr *expr_ptr, idx_t depth, - bool root_expression = false); + //! Interrupt execution of a query + DUCKDB_API void Interrupt(); + //! Enable query profiling + DUCKDB_API void EnableProfiling(); + //! Disable query profiling + DUCKDB_API void DisableProfiling(); - void ReplaceMacroParametersRecursive(unique_ptr &expr); + //! Issue a query, returning a QueryResult. The QueryResult can be either a StreamQueryResult or a + //! MaterializedQueryResult. The StreamQueryResult will only be returned in the case of a successful SELECT + //! statement. + DUCKDB_API unique_ptr Query(const string &query, bool allow_stream_result); + DUCKDB_API unique_ptr Query(unique_ptr statement, bool allow_stream_result); -protected: - BindResult BindExpression(BetweenExpression &expr, idx_t depth); - BindResult BindExpression(CaseExpression &expr, idx_t depth); - BindResult BindExpression(CollateExpression &expr, idx_t depth); - BindResult BindExpression(CastExpression &expr, idx_t depth); - BindResult BindExpression(ColumnRefExpression &expr, idx_t depth); - BindResult BindExpression(ComparisonExpression &expr, idx_t depth); - BindResult BindExpression(ConjunctionExpression &expr, idx_t depth); - BindResult BindExpression(ConstantExpression &expr, idx_t depth); - BindResult BindExpression(FunctionExpression &expr, idx_t depth, unique_ptr *expr_ptr); - BindResult BindExpression(LambdaExpression &expr, idx_t depth, const bool is_lambda, - const LogicalType &list_child_type); - BindResult BindExpression(OperatorExpression &expr, idx_t depth); - BindResult BindExpression(ParameterExpression &expr, idx_t depth); - BindResult BindExpression(PositionalReferenceExpression &ref, idx_t depth); - BindResult BindExpression(SubqueryExpression &expr, idx_t depth); + //! Issues a query to the database and returns a Pending Query Result. Note that "query" may only contain + //! a single statement. + DUCKDB_API unique_ptr PendingQuery(const string &query, bool allow_stream_result); + //! Issues a query to the database and returns a Pending Query Result + DUCKDB_API unique_ptr PendingQuery(unique_ptr statement, + bool allow_stream_result); - void TransformCapturedLambdaColumn(unique_ptr &original, unique_ptr &replacement, - vector> &captures, LogicalType &list_child_type, - string &alias); - void CaptureLambdaColumns(vector> &captures, LogicalType &list_child_type, - unique_ptr &expr, string &alias); + //! Destroy the client context + DUCKDB_API void Destroy(); -protected: - virtual BindResult BindGroupingFunction(OperatorExpression &op, idx_t depth); - virtual BindResult BindFunction(FunctionExpression &expr, ScalarFunctionCatalogEntry *function, idx_t depth); - virtual BindResult BindLambdaFunction(FunctionExpression &expr, ScalarFunctionCatalogEntry *function, idx_t depth); - virtual BindResult BindAggregate(FunctionExpression &expr, AggregateFunctionCatalogEntry *function, idx_t depth); - virtual BindResult BindUnnest(FunctionExpression &expr, idx_t depth); - virtual BindResult BindMacro(FunctionExpression &expr, ScalarMacroCatalogEntry *macro, idx_t depth, - unique_ptr *expr_ptr); + //! Get the table info of a specific table, or nullptr if it cannot be found + DUCKDB_API unique_ptr TableInfo(const string &schema_name, const string &table_name); + //! Appends a DataChunk to the specified table. Returns whether or not the append was successful. + DUCKDB_API void Append(TableDescription &description, ColumnDataCollection &collection); + //! Try to bind a relation in the current client context; either throws an exception or fills the result_columns + //! list with the set of returned columns + DUCKDB_API void TryBindRelation(Relation &relation, vector &result_columns); - virtual string UnsupportedAggregateMessage(); - virtual string UnsupportedUnnestMessage(); + //! Execute a relation + DUCKDB_API unique_ptr PendingQuery(const shared_ptr &relation, + bool allow_stream_result); + DUCKDB_API unique_ptr Execute(const shared_ptr &relation); - Binder &binder; - ClientContext &context; - ExpressionBinder *stored_binder; - vector bound_columns; -}; + //! Prepare a query + DUCKDB_API unique_ptr Prepare(const string &query); + //! Directly prepare a SQL statement + DUCKDB_API unique_ptr Prepare(unique_ptr statement); -} // namespace duckdb + //! Create a pending query result from a prepared statement with the given name and set of parameters + //! It is possible that the prepared statement will be re-bound. This will generally happen if the catalog is + //! modified in between the prepared statement being bound and the prepared statement being run. + DUCKDB_API unique_ptr + PendingQuery(const string &query, shared_ptr &prepared, PendingQueryParameters parameters); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/table_binding.hpp -// -// -//===----------------------------------------------------------------------===// + //! Execute a prepared statement with the given name and set of parameters + //! It is possible that the prepared statement will be re-bound. This will generally happen if the catalog is + //! modified in between the prepared statement being bound and the prepared statement being run. + DUCKDB_API unique_ptr Execute(const string &query, shared_ptr &prepared, + vector &values, bool allow_stream_result = true); + DUCKDB_API unique_ptr Execute(const string &query, shared_ptr &prepared, + PendingQueryParameters parameters); + //! Gets current percentage of the query's progress, returns 0 in case the progress bar is disabled. + DUCKDB_API double GetProgress(); + //! Register function in the temporary schema + DUCKDB_API void RegisterFunction(CreateFunctionInfo *info); + //! Parse statements from a query + DUCKDB_API vector> ParseStatements(const string &query); + //! Extract the logical plan of a query + DUCKDB_API unique_ptr ExtractPlan(const string &query); + DUCKDB_API void HandlePragmaStatements(vector> &statements); + //! Runs a function with a valid transaction context, potentially starting a transaction if the context is in auto + //! commit mode. + DUCKDB_API void RunFunctionInTransaction(const std::function &fun, + bool requires_valid_transaction = true); + //! Same as RunFunctionInTransaction, but does not obtain a lock on the client context or check for validation + DUCKDB_API void RunFunctionInTransactionInternal(ClientContextLock &lock, const std::function &fun, + bool requires_valid_transaction = true); + //! Equivalent to CURRENT_SETTING(key) SQL function. + DUCKDB_API bool TryGetCurrentSetting(const std::string &key, Value &result); + //! Returns the parser options for this client context + DUCKDB_API ParserOptions GetParserOptions() const; + DUCKDB_API unique_ptr Fetch(ClientContextLock &lock, StreamQueryResult &result); + //! Whether or not the given result object (streaming query result or pending query result) is active + DUCKDB_API bool IsActiveResult(ClientContextLock &lock, BaseQueryResult *result); -namespace duckdb { -class BindContext; -class BoundQueryNode; -class ColumnRefExpression; -class SubqueryRef; -class LogicalGet; -class TableCatalogEntry; -class TableFunctionCatalogEntry; -class BoundTableFunction; -class StandardEntry; + //! Returns the current executor + Executor &GetExecutor(); -enum class BindingType { BASE, TABLE, DUMMY, CATALOG_ENTRY }; + //! Returns the current query string (if any) + const string &GetCurrentQuery(); -//! A Binding represents a binding to a table, table-producing function or subquery with a specified table index. -struct Binding { - Binding(BindingType binding_type, const string &alias, vector types, vector names, - idx_t index); - virtual ~Binding() = default; + //! Fetch a list of table names that are required for a given query + DUCKDB_API unordered_set GetTableNames(const string &query); - //! The type of Binding - BindingType binding_type; - //! The alias of the binding - string alias; - //! The table index of the binding - idx_t index; - vector types; - //! Column names of the subquery - vector names; - //! Name -> index for the names - case_insensitive_map_t name_map; + DUCKDB_API ClientProperties GetClientProperties() const; -public: - bool TryGetBindingIndex(const string &column_name, column_t &column_index); - column_t GetBindingIndex(const string &column_name); - bool HasMatchingBinding(const string &column_name); - virtual string ColumnNotFoundError(const string &column_name) const; - virtual BindResult Bind(ColumnRefExpression &colref, idx_t depth); - virtual StandardEntry *GetStandardEntry(); -}; + //! Returns true if execution of the current query is finished + DUCKDB_API bool ExecutionIsFinished(); -struct EntryBinding : public Binding { -public: - EntryBinding(const string &alias, vector types, vector names, idx_t index, - StandardEntry &entry); - StandardEntry &entry; +private: + //! Parse statements and resolve pragmas from a query + bool ParseStatements(ClientContextLock &lock, const string &query, vector> &result, + PreservedError &error); + //! Issues a query to the database and returns a Pending Query Result + unique_ptr PendingQueryInternal(ClientContextLock &lock, unique_ptr statement, + PendingQueryParameters parameters, bool verify = true); + unique_ptr ExecutePendingQueryInternal(ClientContextLock &lock, PendingQueryResult &query); -public: - StandardEntry *GetStandardEntry() override; -}; + //! Parse statements from a query + vector> ParseStatementsInternal(ClientContextLock &lock, const string &query); + //! Perform aggressive query verification of a SELECT statement. Only called when query_verification_enabled is + //! true. + PreservedError VerifyQuery(ClientContextLock &lock, const string &query, unique_ptr statement); -//! TableBinding is exactly like the Binding, except it keeps track of which columns were bound in the linked LogicalGet -//! node for projection pushdown purposes. -struct TableBinding : public Binding { - TableBinding(const string &alias, vector types, vector names, - vector &bound_column_ids, StandardEntry *entry, idx_t index, bool add_row_id = false); + void InitialCleanup(ClientContextLock &lock); + //! Internal clean up, does not lock. Caller must hold the context_lock. + void CleanupInternal(ClientContextLock &lock, BaseQueryResult *result = nullptr, + bool invalidate_transaction = false); + unique_ptr PendingStatementOrPreparedStatement(ClientContextLock &lock, const string &query, + unique_ptr statement, + shared_ptr &prepared, + PendingQueryParameters parameters); + unique_ptr PendingPreparedStatement(ClientContextLock &lock, + shared_ptr statement_p, + PendingQueryParameters parameters); - //! A reference to the set of bound column ids - vector &bound_column_ids; - //! The underlying catalog entry (if any) - StandardEntry *entry; + //! Internally prepare a SQL statement. Caller must hold the context_lock. + shared_ptr CreatePreparedStatement(ClientContextLock &lock, const string &query, + unique_ptr statement, + vector *values = nullptr); + unique_ptr PendingStatementInternal(ClientContextLock &lock, const string &query, + unique_ptr statement, + PendingQueryParameters parameters); + unique_ptr RunStatementInternal(ClientContextLock &lock, const string &query, + unique_ptr statement, bool allow_stream_result, + bool verify = true); + unique_ptr PrepareInternal(ClientContextLock &lock, unique_ptr statement); + void LogQueryInternal(ClientContextLock &lock, const string &query); -public: - unique_ptr ExpandGeneratedColumn(const string &column_name); - BindResult Bind(ColumnRefExpression &colref, idx_t depth) override; - StandardEntry *GetStandardEntry() override; - string ColumnNotFoundError(const string &column_name) const override; -}; + unique_ptr FetchResultInternal(ClientContextLock &lock, PendingQueryResult &pending); + unique_ptr FetchInternal(ClientContextLock &lock, Executor &executor, BaseQueryResult &result); -//! DummyBinding is like the Binding, except the alias and index are set by default. Used for binding lambdas and macro -//! parameters. -struct DummyBinding : public Binding { - // NOTE: changing this string conflicts with the storage version - static constexpr const char *DUMMY_NAME = "0_macro_parameters"; + unique_ptr LockContext(); -public: - DummyBinding(vector types_p, vector names_p, string dummy_name_p); + void BeginTransactionInternal(ClientContextLock &lock, bool requires_valid_transaction); + void BeginQueryInternal(ClientContextLock &lock, const string &query); + PreservedError EndQueryInternal(ClientContextLock &lock, bool success, bool invalidate_transaction); - //! Arguments - vector> *arguments; - //! The name of the dummy binding - string dummy_name; + PendingExecutionResult ExecuteTaskInternal(ClientContextLock &lock, PendingQueryResult &result); -public: - BindResult Bind(ColumnRefExpression &colref, idx_t depth) override; + unique_ptr PendingStatementOrPreparedStatementInternal( + ClientContextLock &lock, const string &query, unique_ptr statement, + shared_ptr &prepared, PendingQueryParameters parameters); - //! Given the parameter colref, returns a copy of the argument that was supplied for this parameter - unique_ptr ParamToArg(ColumnRefExpression &colref); -}; + unique_ptr PendingQueryPreparedInternal(ClientContextLock &lock, const string &query, + shared_ptr &prepared, + PendingQueryParameters parameters); -} // namespace duckdb + unique_ptr PendingQueryInternal(ClientContextLock &, const shared_ptr &relation, + bool allow_stream_result); +private: + //! Lock on using the ClientContext in parallel + mutex context_lock; + //! The currently active query context + unique_ptr active_query; + //! The current query progress + atomic query_progress; +}; -namespace duckdb { -class Binder; -class LogicalGet; -class BoundQueryNode; +class ClientContextLock { +public: + explicit ClientContextLock(mutex &context_lock) : client_guard(context_lock) { + } -class StarExpression; + ~ClientContextLock() { + } -struct UsingColumnSet { - string primary_binding; - unordered_set bindings; +private: + lock_guard client_guard; }; -//! The BindContext object keeps track of all the tables and columns that are -//! encountered during the binding process. -class BindContext { +class ClientContextWrapper { public: - //! Keep track of recursive CTE references - case_insensitive_map_t> cte_references; + DUCKDB_API explicit ClientContextWrapper(const shared_ptr &context) + : client_context(context) { -public: - //! Given a column name, find the matching table it belongs to. Throws an - //! exception if no table has a column of the given name. - string GetMatchingBinding(const string &column_name); - //! Like GetMatchingBinding, but instead of throwing an error if multiple tables have the same binding it will - //! return a list of all the matching ones - unordered_set GetMatchingBindings(const string &column_name); - //! Like GetMatchingBindings, but returns the top 3 most similar bindings (in levenshtein distance) instead of the - //! matching ones - vector GetSimilarBindings(const string &column_name); + }; + shared_ptr GetContext() { + auto actual_context = client_context.lock(); + if (!actual_context) { + throw ConnectionException("Connection has already been closed"); + } + return actual_context; + } - Binding *GetCTEBinding(const string &ctename); - //! Binds a column expression to the base table. Returns the bound expression - //! or throws an exception if the column could not be bound. - BindResult BindColumn(ColumnRefExpression &colref, idx_t depth); - string BindColumn(PositionalReferenceExpression &ref, string &table_name, string &column_name); - BindResult BindColumn(PositionalReferenceExpression &ref, idx_t depth); +private: + std::weak_ptr client_context; +}; - unique_ptr ExpandGeneratedColumn(const string &table_name, const string &column_name); +} // namespace duckdb - unique_ptr CreateColumnReference(const string &table_name, const string &column_name); - unique_ptr CreateColumnReference(const string &schema_name, const string &table_name, - const string &column_name); - //! Generate column expressions for all columns that are present in the - //! referenced tables. This is used to resolve the * expression in a - //! selection list. - void GenerateAllColumnExpressions(StarExpression &expr, vector> &new_select_list); - //! Check if the given (binding, column_name) is in the exclusion/replacement lists. - //! Returns true if it is in one of these lists, and should therefore be skipped. - bool CheckExclusionList(StarExpression &expr, Binding *binding, const string &column_name, - vector> &new_select_list, - case_insensitive_set_t &excluded_columns); - const vector> &GetBindingsList() { - return bindings_list; - } +#include - //! Adds a base table with the given alias to the BindContext. - void AddBaseTable(idx_t index, const string &alias, const vector &names, const vector &types, - vector &bound_column_ids, StandardEntry *entry); - //! Adds a call to a table function with the given alias to the BindContext. - void AddTableFunction(idx_t index, const string &alias, const vector &names, - const vector &types, vector &bound_column_ids, StandardEntry *entry); - //! Adds a table view with a given alias to the BindContext. - void AddView(idx_t index, const string &alias, SubqueryRef &ref, BoundQueryNode &subquery, ViewCatalogEntry *view); - //! Adds a subquery with a given alias to the BindContext. - void AddSubquery(idx_t index, const string &alias, SubqueryRef &ref, BoundQueryNode &subquery); - //! Adds a subquery with a given alias to the BindContext. - void AddSubquery(idx_t index, const string &alias, TableFunctionRef &ref, BoundQueryNode &subquery); - //! Adds a binding to a catalog entry with a given alias to the BindContext. - void AddEntryBinding(idx_t index, const string &alias, const vector &names, - const vector &types, StandardEntry *entry); - //! Adds a base table with the given alias to the BindContext. - void AddGenericBinding(idx_t index, const string &alias, const vector &names, - const vector &types); +namespace duckdb { +struct BoundStatement; - //! Adds a base table with the given alias to the CTE BindContext. - //! We need this to correctly bind recursive CTEs with multiple references. - void AddCTEBinding(idx_t index, const string &alias, const vector &names, const vector &types); +class ClientContextWrapper; +class Binder; +class LogicalOperator; +class QueryNode; +class TableRef; - //! Add an implicit join condition (e.g. USING (x)) - void AddUsingBinding(const string &column_name, UsingColumnSet *set); +class Relation : public std::enable_shared_from_this { +public: + DUCKDB_API Relation(const std::shared_ptr &context, RelationType type) + : context(context), type(type) { + } + DUCKDB_API Relation(ClientContextWrapper &context, RelationType type) : context(context.GetContext()), type(type) { + } + DUCKDB_API virtual ~Relation() { + } - void AddUsingBindingSet(unique_ptr set); + ClientContextWrapper context; - //! Returns any using column set for the given column name, or nullptr if there is none. On conflict (multiple using - //! column sets with the same name) throw an exception. - UsingColumnSet *GetUsingBinding(const string &column_name); - //! Returns any using column set for the given column name, or nullptr if there is none - UsingColumnSet *GetUsingBinding(const string &column_name, const string &binding_name); - //! Erase a using binding from the set of using bindings - void RemoveUsingBinding(const string &column_name, UsingColumnSet *set); - //! Finds the using bindings for a given column. Returns true if any exists, false otherwise. - bool FindUsingBinding(const string &column_name, unordered_set **using_columns); - //! Transfer a using binding from one bind context to this bind context - void TransferUsingBinding(BindContext ¤t_context, UsingColumnSet *current_set, UsingColumnSet *new_set, - const string &binding, const string &using_column); + RelationType type; - //! Fetch the actual column name from the given binding, or throws if none exists - //! This can be different from "column_name" because of case insensitivity - //! (e.g. "column_name" might return "COLUMN_NAME") - string GetActualColumnName(const string &binding, const string &column_name); + shared_ptr extra_dependencies; - case_insensitive_map_t> GetCTEBindings() { - return cte_bindings; - } - void SetCTEBindings(case_insensitive_map_t> bindings) { - cte_bindings = bindings; - } +public: + DUCKDB_API virtual const vector &Columns() = 0; + DUCKDB_API virtual unique_ptr GetQueryNode(); + DUCKDB_API virtual BoundStatement Bind(Binder &binder); + DUCKDB_API virtual string GetAlias(); - //! Alias a set of column names for the specified table, using the original names if there are not enough aliases - //! specified. - static vector AliasColumnNames(const string &table_name, const vector &names, - const vector &column_aliases); + DUCKDB_API unique_ptr ExecuteOrThrow(); + DUCKDB_API unique_ptr Execute(); + DUCKDB_API string ToString(); + DUCKDB_API virtual string ToString(idx_t depth) = 0; - //! Add all the bindings from a BindContext to this BindContext. The other BindContext is destroyed in the process. - void AddContext(BindContext other); + DUCKDB_API void Print(); + DUCKDB_API void Head(idx_t limit = 10); - //! Gets a binding of the specified name. Returns a nullptr and sets the out_error if the binding could not be - //! found. - Binding *GetBinding(const string &name, string &out_error); + DUCKDB_API shared_ptr CreateView(const string &name, bool replace = true, bool temporary = false); + DUCKDB_API shared_ptr CreateView(const string &schema_name, const string &name, bool replace = true, + bool temporary = false); + DUCKDB_API unique_ptr Query(const string &sql); + DUCKDB_API unique_ptr Query(const string &name, const string &sql); -private: - void AddBinding(const string &alias, unique_ptr binding); + //! Explain the query plan of this relation + DUCKDB_API unique_ptr Explain(); -private: - //! The set of bindings - case_insensitive_map_t> bindings; - //! The list of bindings in insertion order - vector> bindings_list; - //! The set of columns used in USING join conditions - case_insensitive_map_t> using_columns; - //! Using column sets - vector> using_column_sets; + DUCKDB_API virtual unique_ptr GetTableRef(); + DUCKDB_API virtual bool IsReadOnly() { + return true; + } - //! The set of CTE bindings - case_insensitive_map_t> cte_bindings; -}; -} // namespace duckdb +public: + // PROJECT + DUCKDB_API shared_ptr Project(const string &select_list); + DUCKDB_API shared_ptr Project(const string &expression, const string &alias); + DUCKDB_API shared_ptr Project(const string &select_list, const vector &aliases); + DUCKDB_API shared_ptr Project(const vector &expressions); + DUCKDB_API shared_ptr Project(const vector &expressions, const vector &aliases); + // FILTER + DUCKDB_API shared_ptr Filter(const string &expression); + DUCKDB_API shared_ptr Filter(const vector &expressions); -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/planner/expression/bound_columnref_expression.hpp -// -// -//===----------------------------------------------------------------------===// + // LIMIT + DUCKDB_API shared_ptr Limit(int64_t n, int64_t offset = 0); + // ORDER + DUCKDB_API shared_ptr Order(const string &expression); + DUCKDB_API shared_ptr Order(const vector &expressions); + // JOIN operation + DUCKDB_API shared_ptr Join(const shared_ptr &other, const string &condition, + JoinType type = JoinType::INNER); + // CROSS PRODUCT operation + DUCKDB_API shared_ptr CrossProduct(const shared_ptr &other); + // SET operations + DUCKDB_API shared_ptr Union(const shared_ptr &other); + DUCKDB_API shared_ptr Except(const shared_ptr &other); + DUCKDB_API shared_ptr Intersect(const shared_ptr &other); + // DISTINCT operation + DUCKDB_API shared_ptr Distinct(); -namespace duckdb { + // AGGREGATES + DUCKDB_API shared_ptr Aggregate(const string &aggregate_list); + DUCKDB_API shared_ptr Aggregate(const vector &aggregates); + DUCKDB_API shared_ptr Aggregate(const string &aggregate_list, const string &group_list); + DUCKDB_API shared_ptr Aggregate(const vector &aggregates, const vector &groups); -class FieldReader; -class FieldWriter; + // ALIAS + DUCKDB_API shared_ptr Alias(const string &alias); -//! A BoundColumnRef expression represents a ColumnRef expression that was bound to an actual table and column index. It -//! is not yet executable, however. The ColumnBindingResolver transforms the BoundColumnRefExpressions into -//! BoundExpressions, which refer to indexes into the physical chunks that pass through the executor. -class BoundColumnRefExpression : public Expression { -public: - BoundColumnRefExpression(LogicalType type, ColumnBinding binding, idx_t depth = 0); - BoundColumnRefExpression(string alias, LogicalType type, ColumnBinding binding, idx_t depth = 0); + //! Insert the data from this relation into a table + DUCKDB_API shared_ptr InsertRel(const string &schema_name, const string &table_name); + DUCKDB_API void Insert(const string &table_name); + DUCKDB_API void Insert(const string &schema_name, const string &table_name); + //! Insert a row (i.e.,list of values) into a table + DUCKDB_API void Insert(const vector> &values); + //! Create a table and insert the data from this relation into that table + DUCKDB_API shared_ptr CreateRel(const string &schema_name, const string &table_name); + DUCKDB_API void Create(const string &table_name); + DUCKDB_API void Create(const string &schema_name, const string &table_name); - //! Column index set by the binder, used to generate the final BoundExpression - ColumnBinding binding; - //! The subquery depth (i.e. depth 0 = current query, depth 1 = parent query, depth 2 = parent of parent, etc...). - //! This is only non-zero for correlated expressions inside subqueries. - idx_t depth; + //! Write a relation to a CSV file + DUCKDB_API shared_ptr + WriteCSVRel(const string &csv_file, + case_insensitive_map_t> options = case_insensitive_map_t>()); + DUCKDB_API void WriteCSV(const string &csv_file, + case_insensitive_map_t> options = case_insensitive_map_t>()); + //! Write a relation to a Parquet file + DUCKDB_API shared_ptr + WriteParquetRel(const string &parquet_file, + case_insensitive_map_t> options = case_insensitive_map_t>()); + DUCKDB_API void + WriteParquet(const string &parquet_file, + case_insensitive_map_t> options = case_insensitive_map_t>()); + + //! Update a table, can only be used on a TableRelation + DUCKDB_API virtual void Update(const string &update, const string &condition = string()); + //! Delete from a table, can only be used on a TableRelation + DUCKDB_API virtual void Delete(const string &condition = string()); + //! Create a relation from calling a table in/out function on the input relation + //! Create a relation from calling a table in/out function on the input relation + DUCKDB_API shared_ptr TableFunction(const std::string &fname, const vector &values); + DUCKDB_API shared_ptr TableFunction(const std::string &fname, const vector &values, + const named_parameter_map_t &named_parameters); public: - bool IsScalar() const override { + //! Whether or not the relation inherits column bindings from its child or not, only relevant for binding + DUCKDB_API virtual bool InheritsColumnBindings() { return false; } - bool IsFoldable() const override { - return false; + DUCKDB_API virtual Relation *ChildRelation() { + return nullptr; } + DUCKDB_API vector> GetAllDependencies(); - string ToString() const override; - - bool Equals(const BaseExpression *other) const override; - hash_t Hash() const override; - - unique_ptr Copy() override; - - void Serialize(FieldWriter &writer) const override; - static unique_ptr Deserialize(ExpressionDeserializationState &state, FieldReader &reader); +protected: + DUCKDB_API string RenderWhitespace(idx_t depth); }; -} // namespace duckdb +} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/parser/query_node.hpp +// duckdb/parser/sql_statement.hpp // // //===----------------------------------------------------------------------===// @@ -18376,21 +18786,10 @@ class BoundColumnRefExpression : public Expression { - -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/common_table_expression_info.hpp -// -// -//===----------------------------------------------------------------------===// - - - //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/parser/statement/select_statement.hpp +// duckdb/common/printer.hpp // // //===----------------------------------------------------------------------===// @@ -18399,754 +18798,713 @@ class BoundColumnRefExpression : public Expression { +namespace duckdb { +enum class OutputStream : uint8_t { STREAM_STDOUT = 1, STREAM_STDERR = 2 }; -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/tableref.hpp -// -// -//===----------------------------------------------------------------------===// +//! Printer is a static class that allows printing to logs or stdout/stderr +class Printer { +public: + //! Print the object to the stream + DUCKDB_API static void Print(OutputStream stream, const string &str); + //! Print the object to stderr + DUCKDB_API static void Print(const string &str); + //! Directly prints the string to stdout without a newline + DUCKDB_API static void RawPrint(OutputStream stream, const string &str); + //! Flush an output stream + DUCKDB_API static void Flush(OutputStream stream); + //! Whether or not we are printing to a terminal + DUCKDB_API static bool IsTerminal(OutputStream stream); + //! The terminal width + DUCKDB_API static idx_t TerminalWidth(); +}; +} // namespace duckdb +namespace duckdb { -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/common/enums/tableref_type.hpp -// -// -//===----------------------------------------------------------------------===// +//! SQLStatement is the base class of any type of SQL statement. +class SQLStatement { +public: + explicit SQLStatement(StatementType type) : type(type) {}; + virtual ~SQLStatement() { + } + //! The statement type + StatementType type; + //! The statement location within the query string + idx_t stmt_location = 0; + //! The statement length within the query string + idx_t stmt_length = 0; + //! The number of prepared statement parameters (if any) + idx_t n_param = 0; + //! The map of named parameter to param index (if n_param and any named) + case_insensitive_map_t named_param_map; + //! The query text that corresponds to this SQL statement + string query; +protected: + SQLStatement(const SQLStatement &other) = default; +public: + virtual string ToString() const { + throw InternalException("ToString not supported for this type of SQLStatement: '%s'", + StatementTypeToString(type)); + } + //! Create a copy of this SelectStatement + virtual unique_ptr Copy() const = 0; +}; +} // namespace duckdb namespace duckdb { -//===--------------------------------------------------------------------===// -// Table Reference Types -//===--------------------------------------------------------------------===// -enum class TableReferenceType : uint8_t { - INVALID = 0, // invalid table reference type - BASE_TABLE = 1, // base table reference - SUBQUERY = 2, // output of a subquery - JOIN = 3, // output of join - CROSS_PRODUCT = 4, // out of cartesian product - TABLE_FUNCTION = 5, // table producing function - EXPRESSION_LIST = 6, // expression list - CTE = 7, // Recursive CTE - EMPTY = 8 // placeholder for empty FROM -}; +class ColumnDataCollection; +class ClientContext; -} // namespace duckdb +class DatabaseInstance; +class DuckDB; +class LogicalOperator; +class SelectStatement; +struct BufferedCSVReaderOptions; -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/parser/parsed_data/sample_options.hpp -// -// -//===----------------------------------------------------------------------===// +typedef void (*warning_callback)(std::string); +//! A connection to a database. This represents a (client) connection that can +//! be used to query the database. +class Connection { +public: + DUCKDB_API explicit Connection(DuckDB &database); + DUCKDB_API explicit Connection(DatabaseInstance &database); + DUCKDB_API ~Connection(); + shared_ptr context; + warning_callback warning_cb; +public: + //! Returns query profiling information for the current query + DUCKDB_API string GetProfilingInformation(ProfilerPrintFormat format = ProfilerPrintFormat::QUERY_TREE); + //! Interrupt execution of the current query + DUCKDB_API void Interrupt(); + //! Enable query profiling + DUCKDB_API void EnableProfiling(); + //! Disable query profiling + DUCKDB_API void DisableProfiling(); + DUCKDB_API void SetWarningCallback(warning_callback); + //! Enable aggressive verification/testing of queries, should only be used in testing + DUCKDB_API void EnableQueryVerification(); + DUCKDB_API void DisableQueryVerification(); + //! Force parallel execution, even for smaller tables. Should only be used in testing. + DUCKDB_API void ForceParallelism(); -namespace duckdb { + //! Issues a query to the database and returns a QueryResult. This result can be either a StreamQueryResult or a + //! MaterializedQueryResult. The result can be stepped through with calls to Fetch(). Note that there can only be + //! one active StreamQueryResult per Connection object. Calling SendQuery() will invalidate any previously existing + //! StreamQueryResult. + DUCKDB_API unique_ptr SendQuery(const string &query); + //! Issues a query to the database and materializes the result (if necessary). Always returns a + //! MaterializedQueryResult. + DUCKDB_API unique_ptr Query(const string &query); + //! Issues a query to the database and materializes the result (if necessary). Always returns a + //! MaterializedQueryResult. + DUCKDB_API unique_ptr Query(unique_ptr statement); + // prepared statements + template + unique_ptr Query(const string &query, Args... args) { + vector values; + return QueryParamsRecursive(query, values, args...); + } -enum class SampleMethod : uint8_t { SYSTEM_SAMPLE = 0, BERNOULLI_SAMPLE = 1, RESERVOIR_SAMPLE = 2 }; + //! Issues a query to the database and returns a Pending Query Result. Note that "query" may only contain + //! a single statement. + DUCKDB_API unique_ptr PendingQuery(const string &query, bool allow_stream_result = false); + //! Issues a query to the database and returns a Pending Query Result + DUCKDB_API unique_ptr PendingQuery(unique_ptr statement, + bool allow_stream_result = false); -string SampleMethodToString(SampleMethod method); + //! Prepare the specified query, returning a prepared statement object + DUCKDB_API unique_ptr Prepare(const string &query); + //! Prepare the specified statement, returning a prepared statement object + DUCKDB_API unique_ptr Prepare(unique_ptr statement); -struct SampleOptions { - Value sample_size; - bool is_percentage; - SampleMethod method; - int64_t seed = -1; + //! Get the table info of a specific table (in the default schema), or nullptr if it cannot be found + DUCKDB_API unique_ptr TableInfo(const string &table_name); + //! Get the table info of a specific table, or nullptr if it cannot be found + DUCKDB_API unique_ptr TableInfo(const string &schema_name, const string &table_name); - unique_ptr Copy(); - void Serialize(Serializer &serializer); - static unique_ptr Deserialize(Deserializer &source); - static bool Equals(SampleOptions *a, SampleOptions *b); -}; + //! Extract a set of SQL statements from a specific query + DUCKDB_API vector> ExtractStatements(const string &query); + //! Extract the logical plan that corresponds to a query + DUCKDB_API unique_ptr ExtractPlan(const string &query); -} // namespace duckdb + //! Appends a DataChunk to the specified table + DUCKDB_API void Append(TableDescription &description, DataChunk &chunk); + //! Appends a ColumnDataCollection to the specified table + DUCKDB_API void Append(TableDescription &description, ColumnDataCollection &collection); + //! Returns a relation that produces a table from this connection + DUCKDB_API shared_ptr Table(const string &tname); + DUCKDB_API shared_ptr Table(const string &schema_name, const string &table_name); + //! Returns a relation that produces a view from this connection + DUCKDB_API shared_ptr View(const string &tname); + DUCKDB_API shared_ptr View(const string &schema_name, const string &table_name); + //! Returns a relation that calls a specified table function + DUCKDB_API shared_ptr TableFunction(const string &tname); + DUCKDB_API shared_ptr TableFunction(const string &tname, const vector &values, + const named_parameter_map_t &named_parameters); + DUCKDB_API shared_ptr TableFunction(const string &tname, const vector &values); + //! Returns a relation that produces values + DUCKDB_API shared_ptr Values(const vector> &values); + DUCKDB_API shared_ptr Values(const vector> &values, const vector &column_names, + const string &alias = "values"); + DUCKDB_API shared_ptr Values(const string &values); + DUCKDB_API shared_ptr Values(const string &values, const vector &column_names, + const string &alias = "values"); -namespace duckdb { -class Deserializer; -class Serializer; + //! Reads CSV file + DUCKDB_API shared_ptr ReadCSV(const string &csv_file); + DUCKDB_API shared_ptr ReadCSV(const string &csv_file, BufferedCSVReaderOptions &options); + DUCKDB_API shared_ptr ReadCSV(const string &csv_file, const vector &columns); -//! Represents a generic expression that returns a table. -class TableRef { -public: - explicit TableRef(TableReferenceType type) : type(type) { - } - virtual ~TableRef() { - } + //! Reads Parquet file + DUCKDB_API shared_ptr ReadParquet(const string &parquet_file, bool binary_as_string); + //! Returns a relation from a query + DUCKDB_API shared_ptr RelationFromQuery(const string &query, const string &alias = "queryrelation", + const string &error = "Expected a single SELECT statement"); + DUCKDB_API shared_ptr RelationFromQuery(unique_ptr select_stmt, + const string &alias = "queryrelation"); - TableReferenceType type; - string alias; - //! Sample options (if any) - unique_ptr sample; - //! The location in the query (if any) - idx_t query_location = DConstants::INVALID_INDEX; + //! Returns a substrait BLOB from a valid query + DUCKDB_API string GetSubstrait(const string &query); + //! Returns a Query Result from a substrait blob + DUCKDB_API unique_ptr FromSubstrait(const string &proto); + //! Returns a substrait BLOB from a valid query + DUCKDB_API string GetSubstraitJSON(const string &query); + //! Returns a Query Result from a substrait JSON + DUCKDB_API unique_ptr FromSubstraitJSON(const string &json); + DUCKDB_API void BeginTransaction(); + DUCKDB_API void Commit(); + DUCKDB_API void Rollback(); + DUCKDB_API void SetAutoCommit(bool auto_commit); + DUCKDB_API bool IsAutoCommit(); + DUCKDB_API bool HasActiveTransaction(); -public: - //! Convert the object to a string - virtual string ToString() const = 0; - string BaseToString(string result) const; - string BaseToString(string result, const vector &column_name_alias) const; - void Print(); + //! Fetch a list of table names that are required for a given query + DUCKDB_API unordered_set GetTableNames(const string &query); - virtual bool Equals(const TableRef *other) const; + template + void CreateScalarFunction(const string &name, TR (*udf_func)(Args...)) { + scalar_function_t function = UDFWrapper::CreateScalarFunction(name, udf_func); + UDFWrapper::RegisterFunction(name, function, *context); + } - virtual unique_ptr Copy() = 0; + template + void CreateScalarFunction(const string &name, vector args, LogicalType ret_type, + TR (*udf_func)(Args...)) { + scalar_function_t function = + UDFWrapper::CreateScalarFunction(name, args, std::move(ret_type), udf_func); + UDFWrapper::RegisterFunction(name, args, ret_type, function, *context); + } - //! Serializes a TableRef to a stand-alone binary blob - DUCKDB_API void Serialize(Serializer &serializer) const; - //! Serializes a TableRef to a stand-alone binary blob - DUCKDB_API virtual void Serialize(FieldWriter &writer) const = 0; - //! Deserializes a blob back into a TableRef - DUCKDB_API static unique_ptr Deserialize(Deserializer &source); + template + void CreateVectorizedFunction(const string &name, scalar_function_t udf_func, + LogicalType varargs = LogicalType::INVALID) { + UDFWrapper::RegisterFunction(name, udf_func, *context, std::move(varargs)); + } - //! Copy the properties of this table ref to the target - void CopyProperties(TableRef &target) const; -}; -} // namespace duckdb + DUCKDB_API void CreateVectorizedFunction(const string &name, vector args, LogicalType ret_type, + scalar_function_t udf_func, LogicalType varargs = LogicalType::INVALID) { + UDFWrapper::RegisterFunction(name, std::move(args), std::move(ret_type), udf_func, *context, + std::move(varargs)); + } + //------------------------------------- Aggreate Functions ----------------------------------------// + template + void CreateAggregateFunction(const string &name) { + AggregateFunction function = UDFWrapper::CreateAggregateFunction(name); + UDFWrapper::RegisterAggrFunction(function, *context); + } -namespace duckdb { + template + void CreateAggregateFunction(const string &name) { + AggregateFunction function = UDFWrapper::CreateAggregateFunction(name); + UDFWrapper::RegisterAggrFunction(function, *context); + } -class QueryNode; + template + void CreateAggregateFunction(const string &name, LogicalType ret_type, LogicalType input_typeA) { + AggregateFunction function = + UDFWrapper::CreateAggregateFunction(name, ret_type, input_typeA); + UDFWrapper::RegisterAggrFunction(function, *context); + } -//! SelectStatement is a typical SELECT clause -class SelectStatement : public SQLStatement { -public: - SelectStatement() : SQLStatement(StatementType::SELECT_STATEMENT) { + template + void CreateAggregateFunction(const string &name, LogicalType ret_type, LogicalType input_typeA, + LogicalType input_typeB) { + AggregateFunction function = + UDFWrapper::CreateAggregateFunction(name, ret_type, input_typeA, input_typeB); + UDFWrapper::RegisterAggrFunction(function, *context); } - //! The main query node - unique_ptr node; + DUCKDB_API void CreateAggregateFunction(const string &name, vector arguments, LogicalType return_type, + aggregate_size_t state_size, aggregate_initialize_t initialize, + aggregate_update_t update, aggregate_combine_t combine, + aggregate_finalize_t finalize, + aggregate_simple_update_t simple_update = nullptr, + bind_aggregate_function_t bind = nullptr, + aggregate_destructor_t destructor = nullptr) { + AggregateFunction function = + UDFWrapper::CreateAggregateFunction(name, arguments, return_type, state_size, initialize, update, combine, + finalize, simple_update, bind, destructor); + UDFWrapper::RegisterAggrFunction(function, *context); + } -protected: - SelectStatement(const SelectStatement &other); +private: + unique_ptr QueryParamsRecursive(const string &query, vector &values); -public: - //! Convert the SELECT statement to a string - string ToString() const override; - //! Create a copy of this SelectStatement - unique_ptr Copy() const override; - //! Serializes a SelectStatement to a stand-alone binary blob - void Serialize(Serializer &serializer) const; - //! Deserializes a blob back into a SelectStatement, returns nullptr if - //! deserialization is not possible - static unique_ptr Deserialize(Deserializer &source); - //! Whether or not the statements are equivalent - bool Equals(const SQLStatement *other) const; + template + unique_ptr QueryParamsRecursive(const string &query, vector &values, T value, Args... args) { + values.push_back(Value::CreateValue(value)); + return QueryParamsRecursive(query, values, args...); + } }; -} // namespace duckdb +} // namespace duckdb -namespace duckdb { - -class SelectStatement; +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/database.hpp +// +// +//===----------------------------------------------------------------------===// -struct CommonTableExpressionInfo { - vector aliases; - unique_ptr query; -}; -} // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/config.hpp +// +// +//===----------------------------------------------------------------------===// -namespace duckdb { -enum QueryNodeType : uint8_t { - SELECT_NODE = 1, - SET_OPERATION_NODE = 2, - BOUND_SUBQUERY_NODE = 3, - RECURSIVE_CTE_NODE = 4 -}; -struct CommonTableExpressionInfo; +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/access_mode.hpp +// +// +//===----------------------------------------------------------------------===// -class CommonTableExpressionMap { -public: - CommonTableExpressionMap(); - unordered_map> map; -public: - string ToString() const; - CommonTableExpressionMap Copy() const; -}; -class QueryNode { -public: - explicit QueryNode(QueryNodeType type) : type(type) { - } - virtual ~QueryNode() { - } - //! The type of the query node, either SetOperation or Select - QueryNodeType type; - //! The set of result modifiers associated with this query node - vector> modifiers; - //! CTEs (used by SelectNode and SetOperationNode) - CommonTableExpressionMap cte_map; +namespace duckdb { - virtual const vector> &GetSelectList() const = 0; +enum class AccessMode : uint8_t { UNDEFINED = 0, AUTOMATIC = 1, READ_ONLY = 2, READ_WRITE = 3 }; -public: - //! Convert the query node to a string - virtual string ToString() const = 0; +} // namespace duckdb - virtual bool Equals(const QueryNode *other) const; - //! Create a copy of this QueryNode - virtual unique_ptr Copy() const = 0; - //! Serializes a QueryNode to a stand-alone binary blob - DUCKDB_API void Serialize(Serializer &serializer) const; - //! Serializes a QueryNode to a stand-alone binary blob - DUCKDB_API virtual void Serialize(FieldWriter &writer) const = 0; - //! Deserializes a blob back into a QueryNode - DUCKDB_API static unique_ptr Deserialize(Deserializer &source); - string ResultModifiersToString() const; - //! Adds a distinct modifier to the query node - void AddDistinct(); -protected: - //! Copy base QueryNode properties from another expression to this one, - //! used in Copy method - void CopyProperties(QueryNode &other) const; -}; +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/optimizer_type.hpp +// +// +//===----------------------------------------------------------------------===// -} // namespace duckdb namespace duckdb { -class BoundResultModifier; -class BoundSelectNode; -class ClientContext; -class ExpressionBinder; -class LimitModifier; -class OrderBinder; -class TableCatalogEntry; -class ViewCatalogEntry; -class TableMacroCatalogEntry; - -struct CreateInfo; -struct BoundCreateTableInfo; -struct BoundCreateFunctionInfo; -struct CommonTableExpressionInfo; -struct BoundParameterMap; -enum class BindingMode : uint8_t { STANDARD_BINDING, EXTRACT_NAMES }; +enum class OptimizerType : uint32_t { + INVALID = 0, + EXPRESSION_REWRITER, + FILTER_PULLUP, + FILTER_PUSHDOWN, + REGEX_RANGE, + IN_CLAUSE, + JOIN_ORDER, + DELIMINATOR, + UNNEST_REWRITER, + UNUSED_COLUMNS, + STATISTICS_PROPAGATION, + COMMON_SUBEXPRESSIONS, + COMMON_AGGREGATE, + COLUMN_LIFETIME, + TOP_N, + REORDER_FILTER, + EXTENSION +}; -struct CorrelatedColumnInfo { - ColumnBinding binding; - LogicalType type; - string name; - idx_t depth; +string OptimizerTypeToString(OptimizerType type); +OptimizerType OptimizerTypeFromString(const string &str); - CorrelatedColumnInfo(ColumnBinding binding, LogicalType type_p, string name_p, idx_t depth) - : binding(binding), type(move(type_p)), name(move(name_p)), depth(depth) { - } - explicit CorrelatedColumnInfo(BoundColumnRefExpression &expr) - : CorrelatedColumnInfo(expr.binding, expr.return_type, expr.GetName(), expr.depth) { - } +} // namespace duckdb - bool operator==(const CorrelatedColumnInfo &rhs) const { - return binding == rhs.binding; - } -}; -//! Bind the parsed query tree to the actual columns present in the catalog. -/*! - The binder is responsible for binding tables and columns to actual physical - tables and columns in the catalog. In the process, it also resolves types of - all expressions. -*/ -class Binder : public std::enable_shared_from_this { - friend class ExpressionBinder; - friend class SelectBinder; - friend class RecursiveSubqueryPlanner; +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/set_scope.hpp +// +// +//===----------------------------------------------------------------------===// -public: - static shared_ptr CreateBinder(ClientContext &context, Binder *parent = nullptr, bool inherit_ctes = true); - //! The client context - ClientContext &context; - //! A mapping of names to common table expressions - case_insensitive_map_t CTE_bindings; - //! The CTEs that have already been bound - unordered_set bound_ctes; - //! The bind context - BindContext bind_context; - //! The set of correlated columns bound by this binder (FIXME: this should probably be an unordered_set and not a - //! vector) - vector correlated_columns; - //! The set of parameter expressions bound by this binder - BoundParameterMap *parameters; - //! Statement properties - StatementProperties properties; - //! The alias for the currently processing subquery, if it exists - string alias; - //! Macro parameter bindings (if any) - DummyBinding *macro_binding = nullptr; - //! The intermediate lambda bindings to bind nested lambdas (if any) - vector *lambda_bindings = nullptr; -public: - BoundStatement Bind(SQLStatement &statement); - BoundStatement Bind(QueryNode &node); - unique_ptr BindCreateTableInfo(unique_ptr info); - void BindCreateViewInfo(CreateViewInfo &base); - SchemaCatalogEntry *BindSchema(CreateInfo &info); - SchemaCatalogEntry *BindCreateFunctionInfo(CreateInfo &info); - //! Check usage, and cast named parameters to their types - static void BindNamedParameters(named_parameter_type_map_t &types, named_parameter_map_t &values, - QueryErrorContext &error_context, string &func_name); +namespace duckdb { - unique_ptr Bind(TableRef &ref); - unique_ptr CreatePlan(BoundTableRef &ref); +enum class SetScope : uint8_t { + AUTOMATIC = 0, + LOCAL = 1, /* unused */ + SESSION = 2, + GLOBAL = 3 +}; - //! Generates an unused index for a table - idx_t GenerateTableIndex(); +} // namespace duckdb - //! Add a common table expression to the binder - void AddCTE(const string &name, CommonTableExpressionInfo *cte); - //! Find a common table expression by name; returns nullptr if none exists - CommonTableExpressionInfo *FindCTE(const string &name, bool skip = false); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/window_aggregation_mode.hpp +// +// +//===----------------------------------------------------------------------===// - bool CTEIsAlreadyBound(CommonTableExpressionInfo *cte); - //! Add the view to the set of currently bound views - used for detecting recursive view definitions - void AddBoundView(ViewCatalogEntry *view); - void PushExpressionBinder(ExpressionBinder *binder); - void PopExpressionBinder(); - void SetActiveBinder(ExpressionBinder *binder); - ExpressionBinder *GetActiveBinder(); - bool HasActiveBinder(); - vector &GetActiveBinders(); - void MergeCorrelatedColumns(vector &other); - //! Add a correlated column to this binder (if it does not exist) - void AddCorrelatedColumn(const CorrelatedColumnInfo &info); +namespace duckdb { - string FormatError(ParsedExpression &expr_context, const string &message); - string FormatError(TableRef &ref_context, const string &message); +enum class WindowAggregationMode : uint32_t { + //! Use the window aggregate API if available + WINDOW = 0, + //! Don't use window, but use combine if available + COMBINE, + //! Don't use combine or window (compute each frame separately) + SEPARATE +}; - string FormatErrorRecursive(idx_t query_location, const string &message, vector &values); - template - string FormatErrorRecursive(idx_t query_location, const string &msg, vector &values, T param, - Args... params) { - values.push_back(ExceptionFormatValue::CreateFormatValue(param)); - return FormatErrorRecursive(query_location, msg, values, params...); - } +} // namespace duckdb - template - string FormatError(idx_t query_location, const string &msg, Args... params) { - vector values; - return FormatErrorRecursive(query_location, msg, values, params...); - } - static void BindLogicalType(ClientContext &context, LogicalType &type, const string &schema = ""); - bool HasMatchingBinding(const string &table_name, const string &column_name, string &error_message); - bool HasMatchingBinding(const string &schema_name, const string &table_name, const string &column_name, - string &error_message); - void SetBindingMode(BindingMode mode); - BindingMode GetBindingMode(); - void AddTableName(string table_name); - const unordered_set &GetTableNames(); - void SetCanContainNulls(bool can_contain_nulls); -private: - //! The parent binder (if any) - shared_ptr parent; - //! The vector of active binders - vector active_binders; - //! The count of bound_tables - idx_t bound_tables; - //! Whether or not the binder has any unplanned subqueries that still need to be planned - bool has_unplanned_subqueries = false; - //! Whether or not subqueries should be planned already - bool plan_subquery = true; - //! Whether CTEs should reference the parent binder (if it exists) - bool inherit_ctes = true; - //! Whether or not the binder can contain NULLs as the root of expressions - bool can_contain_nulls = false; - //! The root statement of the query that is currently being parsed - SQLStatement *root_statement = nullptr; - //! Binding mode - BindingMode mode = BindingMode::STANDARD_BINDING; - //! Table names extracted for BindingMode::EXTRACT_NAMES - unordered_set table_names; - //! The set of bound views - unordered_set bound_views; +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/storage/compression/bitpacking.hpp +// +// +//===----------------------------------------------------------------------===// -private: - //! Bind the expressions of generated columns to check for errors - void BindGeneratedColumns(BoundCreateTableInfo &info); - //! Bind the default values of the columns of a table - void BindDefaultValues(ColumnList &columns, vector> &bound_defaults); - //! Bind a limit value (LIMIT or OFFSET) - unique_ptr BindDelimiter(ClientContext &context, OrderBinder &order_binder, - unique_ptr delimiter, const LogicalType &type, - Value &delimiter_value); - //! Move correlated expressions from the child binder to this binder - void MoveCorrelatedExpressions(Binder &other); - BoundStatement Bind(SelectStatement &stmt); - BoundStatement Bind(InsertStatement &stmt); - BoundStatement Bind(CopyStatement &stmt); - BoundStatement Bind(DeleteStatement &stmt); - BoundStatement Bind(UpdateStatement &stmt); - BoundStatement Bind(CreateStatement &stmt); - BoundStatement Bind(DropStatement &stmt); - BoundStatement Bind(AlterStatement &stmt); - BoundStatement Bind(PrepareStatement &stmt); - BoundStatement Bind(ExecuteStatement &stmt); - BoundStatement Bind(TransactionStatement &stmt); - BoundStatement Bind(PragmaStatement &stmt); - BoundStatement Bind(ExplainStatement &stmt); - BoundStatement Bind(VacuumStatement &stmt); - BoundStatement Bind(RelationStatement &stmt); - BoundStatement Bind(ShowStatement &stmt); - BoundStatement Bind(CallStatement &stmt); - BoundStatement Bind(ExportStatement &stmt); - BoundStatement Bind(ExtensionStatement &stmt); - BoundStatement Bind(SetStatement &stmt); - BoundStatement Bind(LoadStatement &stmt); - BoundStatement Bind(LogicalPlanStatement &stmt); - BoundStatement BindReturning(vector> returning_list, TableCatalogEntry *table, - idx_t update_table_index, unique_ptr child_operator, - BoundStatement result); - unique_ptr BindTableMacro(FunctionExpression &function, TableMacroCatalogEntry *macro_func, idx_t depth); +namespace duckdb { - unique_ptr BindNode(SelectNode &node); - unique_ptr BindNode(SetOperationNode &node); - unique_ptr BindNode(RecursiveCTENode &node); - unique_ptr BindNode(QueryNode &node); +enum class BitpackingMode : uint8_t { + AUTO, - unique_ptr VisitQueryNode(BoundQueryNode &node, unique_ptr root); - unique_ptr CreatePlan(BoundRecursiveCTENode &node); - unique_ptr CreatePlan(BoundSelectNode &statement); - unique_ptr CreatePlan(BoundSetOperationNode &node); - unique_ptr CreatePlan(BoundQueryNode &node); + CONSTANT, + CONSTANT_DELTA, + DELTA_FOR, + FOR +}; - unique_ptr Bind(BaseTableRef &ref); - unique_ptr Bind(CrossProductRef &ref); - unique_ptr Bind(JoinRef &ref); - unique_ptr Bind(SubqueryRef &ref, CommonTableExpressionInfo *cte = nullptr); - unique_ptr Bind(TableFunctionRef &ref); - unique_ptr Bind(EmptyTableRef &ref); - unique_ptr Bind(ExpressionListRef &ref); +BitpackingMode BitpackingModeFromString(const string &str); +string BitpackingModeToString(const BitpackingMode &mode); - bool BindTableFunctionParameters(TableFunctionCatalogEntry &table_function, - vector> &expressions, vector &arguments, - vector ¶meters, named_parameter_map_t &named_parameters, - unique_ptr &subquery, string &error); - bool BindTableInTableOutFunction(vector> &expressions, - unique_ptr &subquery, string &error); - unique_ptr BindTableFunction(TableFunction &function, vector parameters); - unique_ptr - BindTableFunctionInternal(TableFunction &table_function, const string &function_name, vector parameters, - named_parameter_map_t named_parameters, vector input_table_types, - vector input_table_names, const vector &column_name_alias, - unique_ptr external_dependency); +} // namespace duckdb - unique_ptr CreatePlan(BoundBaseTableRef &ref); - unique_ptr CreatePlan(BoundCrossProductRef &ref); - unique_ptr CreatePlan(BoundJoinRef &ref); - unique_ptr CreatePlan(BoundSubqueryRef &ref); - unique_ptr CreatePlan(BoundTableFunction &ref); - unique_ptr CreatePlan(BoundEmptyTableRef &ref); - unique_ptr CreatePlan(BoundExpressionListRef &ref); - unique_ptr CreatePlan(BoundCTERef &ref); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/function/cast/default_casts.hpp +// +// +//===----------------------------------------------------------------------===// - BoundStatement BindCopyTo(CopyStatement &stmt); - BoundStatement BindCopyFrom(CopyStatement &stmt); - void BindModifiers(OrderBinder &order_binder, QueryNode &statement, BoundQueryNode &result); - void BindModifierTypes(BoundQueryNode &result, const vector &sql_types, idx_t projection_index); - BoundStatement BindSummarize(ShowStatement &stmt); - unique_ptr BindLimit(OrderBinder &order_binder, LimitModifier &limit_mod); - unique_ptr BindLimitPercent(OrderBinder &order_binder, LimitPercentModifier &limit_mod); - unique_ptr BindOrderExpression(OrderBinder &order_binder, unique_ptr expr); - unique_ptr PlanFilter(unique_ptr condition, unique_ptr root); - void PlanSubqueries(unique_ptr *expr, unique_ptr *root); - unique_ptr PlanSubquery(BoundSubqueryExpression &expr, unique_ptr &root); - unique_ptr CastLogicalOperatorToTypes(vector &source_types, - vector &target_types, - unique_ptr op); +namespace duckdb { - string FindBinding(const string &using_column, const string &join_side); - bool TryFindBinding(const string &using_column, const string &join_side, string &result); +class CastFunctionSet; +struct FunctionLocalState; - void AddUsingBindingSet(unique_ptr set); - string RetrieveUsingBinding(Binder ¤t_binder, UsingColumnSet *current_set, const string &column_name, - const string &join_side, UsingColumnSet *new_set); +//! Extra data that can be attached to a bind function of a cast, and is available during binding +struct BindCastInfo { + DUCKDB_API virtual ~BindCastInfo(); +}; + +//! Extra data that can be returned by the bind of a cast, and is available during execution of a cast +struct BoundCastData { + DUCKDB_API virtual ~BoundCastData(); + + DUCKDB_API virtual unique_ptr Copy() const = 0; +}; + +struct CastParameters { + CastParameters() { + } + CastParameters(BoundCastData *cast_data, bool strict, string *error_message, FunctionLocalState *local_state) + : cast_data(cast_data), strict(strict), error_message(error_message), local_state(local_state) { + } + CastParameters(CastParameters &parent, BoundCastData *cast_data = nullptr) + : cast_data(cast_data), strict(parent.strict), error_message(parent.error_message) { + } + + //! The bound cast data (if any) + BoundCastData *cast_data = nullptr; + //! whether or not to enable strict casting + bool strict = false; + // out: error message in case cast has failed + string *error_message = nullptr; + //! Local state + FunctionLocalState *local_state = nullptr; +}; - void AddCTEMap(CommonTableExpressionMap &cte_map); +typedef bool (*cast_function_t)(Vector &source, Vector &result, idx_t count, CastParameters ¶meters); +typedef unique_ptr (*init_cast_local_state_t)(ClientContext &context); - void ExpandStarExpressions(vector> &select_list, - vector> &new_select_list); - void ExpandStarExpression(unique_ptr expr, vector> &new_select_list); - bool FindStarExpression(ParsedExpression &expr, StarExpression **star); - void ReplaceStarExpression(unique_ptr &expr, unique_ptr &replacement); +struct BoundCastInfo { + DUCKDB_API + BoundCastInfo( + cast_function_t function, unique_ptr cast_data = nullptr, + init_cast_local_state_t init_local_state = nullptr); // NOLINT: allow explicit cast from cast_function_t + cast_function_t function; + init_cast_local_state_t init_local_state; + unique_ptr cast_data; public: - // This should really be a private constructor, but make_shared does not allow it... - // If you are thinking about calling this, you should probably call Binder::CreateBinder - Binder(bool I_know_what_I_am_doing, ClientContext &context, shared_ptr parent, bool inherit_ctes); + BoundCastInfo Copy() const; }; -} // namespace duckdb +struct BindCastInput { + DUCKDB_API BindCastInput(CastFunctionSet &function_set, BindCastInfo *info, ClientContext *context); + CastFunctionSet &function_set; + BindCastInfo *info; + ClientContext *context; -namespace duckdb { +public: + DUCKDB_API BoundCastInfo GetCastFunction(const LogicalType &source, const LogicalType &target); +}; -//! The OperatorExtensionInfo holds static information relevant to the operator extension -struct OperatorExtensionInfo { - DUCKDB_API virtual ~OperatorExtensionInfo() { +struct ListBoundCastData : public BoundCastData { + explicit ListBoundCastData(BoundCastInfo child_cast) : child_cast_info(std::move(child_cast)) { + } + + BoundCastInfo child_cast_info; + static unique_ptr BindListToListCast(BindCastInput &input, const LogicalType &source, + const LogicalType &target); + +public: + unique_ptr Copy() const override { + return make_unique(child_cast_info.Copy()); } }; -typedef BoundStatement (*bind_function_t)(ClientContext &context, Binder &binder, OperatorExtensionInfo *info, - SQLStatement &statement); +struct ListCast { + static bool ListToListCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters); +}; -// forward declaration to avoid circular reference -struct LogicalExtensionOperator; +struct StructBoundCastData : public BoundCastData { + StructBoundCastData(vector child_casts, LogicalType target_p) + : child_cast_info(std::move(child_casts)), target(std::move(target_p)) { + } + + vector child_cast_info; + LogicalType target; + + static unique_ptr BindStructToStructCast(BindCastInput &input, const LogicalType &source, + const LogicalType &target); -class OperatorExtension { public: - bind_function_t Bind; + unique_ptr Copy() const override { + vector copy_info; + for (auto &info : child_cast_info) { + copy_info.push_back(info.Copy()); + } + return make_unique(std::move(copy_info), target); + } +}; - //! Additional info passed to the CreatePlan & Bind functions - shared_ptr operator_info; +struct MapBoundCastData : public BoundCastData { + MapBoundCastData(BoundCastInfo key_cast, BoundCastInfo value_cast) + : key_cast(std::move(key_cast)), value_cast(std::move(value_cast)) { + } - virtual std::string GetName() = 0; - virtual std::unique_ptr Deserialize(LogicalDeserializationState &state, - FieldReader &reader) = 0; + BoundCastInfo key_cast; + BoundCastInfo value_cast; - DUCKDB_API virtual ~OperatorExtension() { + static unique_ptr BindMapToMapCast(BindCastInput &input, const LogicalType &source, + const LogicalType &target); + +public: + unique_ptr Copy() const override { + return make_unique(key_cast.Copy(), value_cast.Copy()); } }; -} // namespace duckdb +struct DefaultCasts { + DUCKDB_API static BoundCastInfo GetDefaultCastFunction(BindCastInput &input, const LogicalType &source, + const LogicalType &target); + DUCKDB_API static bool NopCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters); + DUCKDB_API static bool TryVectorNullCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters); + DUCKDB_API static bool ReinterpretCast(Vector &source, Vector &result, idx_t count, CastParameters ¶meters); -namespace duckdb { -class CastFunctionSet; -class ClientContext; -class ErrorManager; -class CompressionFunction; -class TableFunctionRef; +private: + static BoundCastInfo BlobCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); + static BoundCastInfo BitCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); + static BoundCastInfo DateCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); + static BoundCastInfo DecimalCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); + static BoundCastInfo EnumCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); + static BoundCastInfo IntervalCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); + static BoundCastInfo ListCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); + static BoundCastInfo NumericCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); + static BoundCastInfo MapCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); + static BoundCastInfo PointerCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); + static BoundCastInfo StringCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); + static BoundCastInfo StructCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); + static BoundCastInfo TimeCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); + static BoundCastInfo TimeTzCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); + static BoundCastInfo TimestampCastSwitch(BindCastInput &input, const LogicalType &source, + const LogicalType &target); + static BoundCastInfo TimestampTzCastSwitch(BindCastInput &input, const LogicalType &source, + const LogicalType &target); + static BoundCastInfo TimestampNsCastSwitch(BindCastInput &input, const LogicalType &source, + const LogicalType &target); + static BoundCastInfo TimestampMsCastSwitch(BindCastInput &input, const LogicalType &source, + const LogicalType &target); + static BoundCastInfo TimestampSecCastSwitch(BindCastInput &input, const LogicalType &source, + const LogicalType &target); + static BoundCastInfo UnionCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); + static BoundCastInfo UUIDCastSwitch(BindCastInput &input, const LogicalType &source, const LogicalType &target); -struct CompressionFunctionSet; -struct DBConfig; + static BoundCastInfo ImplicitToUnionCast(BindCastInput &input, const LogicalType &source, + const LogicalType &target); +}; -enum class AccessMode : uint8_t { UNDEFINED = 0, AUTOMATIC = 1, READ_ONLY = 2, READ_WRITE = 3 }; +} // namespace duckdb -enum class CheckpointAbort : uint8_t { - NO_ABORT = 0, - DEBUG_ABORT_BEFORE_TRUNCATE = 1, - DEBUG_ABORT_BEFORE_HEADER = 2, - DEBUG_ABORT_AFTER_FREE_LIST_WRITE = 3 -}; +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/function/replacement_scan.hpp +// +// +//===----------------------------------------------------------------------===// -typedef void (*set_global_function_t)(DatabaseInstance *db, DBConfig &config, const Value ¶meter); -typedef void (*set_local_function_t)(ClientContext &context, const Value ¶meter); -typedef Value (*get_setting_function_t)(ClientContext &context); -struct ConfigurationOption { - const char *name; - const char *description; - LogicalTypeId parameter_type; - set_global_function_t set_global; - set_local_function_t set_local; - get_setting_function_t get_setting; -}; -typedef void (*set_option_callback_t)(ClientContext &context, SetScope scope, Value ¶meter); -struct ExtensionOption { - ExtensionOption(string description_p, LogicalType type_p, set_option_callback_t set_function_p) - : description(move(description_p)), type(move(type_p)), set_function(set_function_p) { - } - string description; - LogicalType type; - set_option_callback_t set_function; -}; +namespace duckdb { -struct DBConfigOptions { - //! Database file path. May be empty for in-memory mode - string database_path; - //! Access mode of the database (AUTOMATIC, READ_ONLY or READ_WRITE) - AccessMode access_mode = AccessMode::AUTOMATIC; - //! Checkpoint when WAL reaches this size (default: 16MB) - idx_t checkpoint_wal_size = 1 << 24; - //! Whether or not to use Direct IO, bypassing operating system buffers - bool use_direct_io = false; - //! Whether extensions should be loaded on start-up - bool load_extensions = true; - //! The maximum memory used by the database system (in bytes). Default: 80% of System available memory - idx_t maximum_memory = (idx_t)-1; - //! The maximum amount of CPU threads used by the database system. Default: all available. - idx_t maximum_threads = (idx_t)-1; - //! The number of external threads that work on DuckDB tasks. Default: none. - idx_t external_threads = 0; - //! Whether or not to create and use a temporary directory to store intermediates that do not fit in memory - bool use_temporary_directory = true; - //! Directory to store temporary structures that do not fit in memory - string temporary_directory; - //! The collation type of the database - string collation = string(); - //! The order type used when none is specified (default: ASC) - OrderType default_order_type = OrderType::ASCENDING; - //! Null ordering used when none is specified (default: NULLS FIRST) - OrderByNullType default_null_order = OrderByNullType::NULLS_FIRST; - //! enable COPY and related commands - bool enable_external_access = true; - //! Whether or not object cache is used - bool object_cache_enable = false; - //! Force checkpoint when CHECKPOINT is called or on shutdown, even if no changes have been made - bool force_checkpoint = false; - //! Run a checkpoint on successful shutdown and delete the WAL, to leave only a single database file behind - bool checkpoint_on_shutdown = true; - //! Debug flag that decides when a checkpoing should be aborted. Only used for testing purposes. - CheckpointAbort checkpoint_abort = CheckpointAbort::NO_ABORT; - //! Initialize the database with the standard set of DuckDB functions - //! You should probably not touch this unless you know what you are doing - bool initialize_default_database = true; - //! The set of disabled optimizers (default empty) - set disabled_optimizers; - //! Force a specific compression method to be used when checkpointing (if available) - CompressionType force_compression = CompressionType::COMPRESSION_AUTO; - //! Debug setting for window aggregation mode: (window, combine, separate) - WindowAggregationMode window_mode = WindowAggregationMode::WINDOW; - //! Whether or not preserving insertion order should be preserved - bool preserve_insertion_order = true; - //! Database configuration variables as controlled by SET - case_insensitive_map_t set_variables; - //! Whether unsigned extensions should be loaded - bool allow_unsigned_extensions = false; - //! Enable emitting FSST Vectors - bool enable_fsst_vectors = false; - //! Experimental parallel CSV reader - bool experimental_parallel_csv_reader = false; +class ClientContext; +class TableRef; - bool operator==(const DBConfigOptions &other) const; +struct ReplacementScanData { + virtual ~ReplacementScanData() { + } }; -struct DBConfig { - friend class DatabaseInstance; - friend class StorageManager; - -public: - DUCKDB_API DBConfig(); - DUCKDB_API DBConfig(std::unordered_map &config_dict, bool read_only); - DUCKDB_API ~DBConfig(); +typedef unique_ptr (*replacement_scan_t)(ClientContext &context, const string &table_name, + ReplacementScanData *data); - mutex config_lock; - //! Replacement table scans are automatically attempted when a table name cannot be found in the schema - vector replacement_scans; +//! Replacement table scans are automatically attempted when a table name cannot be found in the schema +//! This allows you to do e.g. SELECT * FROM 'filename.csv', and automatically convert this into a CSV scan +struct ReplacementScan { + explicit ReplacementScan(replacement_scan_t function, unique_ptr data_p = nullptr) + : function(function), data(std::move(data_p)) { + } - //! Replacement open handlers are callbacks that run pre and post database initialization - vector replacement_opens; + replacement_scan_t function; + unique_ptr data; +}; - //! Extra parameters that can be SET for loaded extensions - case_insensitive_map_t extension_parameters; - //! The FileSystem to use, can be overwritten to allow for injecting custom file systems for testing purposes (e.g. - //! RamFS or something similar) - unique_ptr file_system; - //! The allocator used by the system - unique_ptr allocator; - //! Database configuration options - DBConfigOptions options; - //! Extensions made to the parser - vector parser_extensions; - //! Extensions made to the optimizer - vector optimizer_extensions; - //! Error manager - unique_ptr error_manager; - //! A reference to the (shared) default allocator (Allocator::DefaultAllocator) - shared_ptr default_allocator; - //! Extensions made to binder - vector> operator_extensions; +} // namespace duckdb -public: - DUCKDB_API static DBConfig &GetConfig(ClientContext &context); - DUCKDB_API static DBConfig &GetConfig(DatabaseInstance &db); - DUCKDB_API static const DBConfig &GetConfig(const ClientContext &context); - DUCKDB_API static const DBConfig &GetConfig(const DatabaseInstance &db); - DUCKDB_API static vector GetOptions(); - DUCKDB_API static idx_t GetOptionCount(); - DUCKDB_API static vector GetOptionNames(); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/function/create_database_extension.hpp +// +// +//===----------------------------------------------------------------------===// - DUCKDB_API void AddExtensionOption(string name, string description, LogicalType parameter, - set_option_callback_t function = nullptr); - //! Fetch an option by index. Returns a pointer to the option, or nullptr if out of range - DUCKDB_API static ConfigurationOption *GetOptionByIndex(idx_t index); - //! Fetch an option by name. Returns a pointer to the option, or nullptr if none exists. - DUCKDB_API static ConfigurationOption *GetOptionByName(const string &name); - DUCKDB_API void SetOption(const ConfigurationOption &option, const Value &value); - DUCKDB_API void SetOption(DatabaseInstance *db, const ConfigurationOption &option, const Value &value); - DUCKDB_API void SetOption(const string &name, Value value); - DUCKDB_API static idx_t ParseMemoryLimit(const string &arg); - //! Return the list of possible compression functions for the specific physical type - DUCKDB_API vector GetCompressionFunctions(PhysicalType data_type); - //! Return the compression function for the specified compression type/physical type combo - DUCKDB_API CompressionFunction *GetCompressionFunction(CompressionType type, PhysicalType data_type); - bool operator==(const DBConfig &other); - bool operator!=(const DBConfig &other); +namespace duckdb { - DUCKDB_API CastFunctionSet &GetCastFunctions(); +class ClientContext; +class TableFunctionRef; -private: - unique_ptr compression_functions; - unique_ptr cast_functions; +struct CreateDatabaseExtensionData { + virtual ~CreateDatabaseExtensionData() { + } +}; + +typedef unique_ptr (*create_database_t)(ClientContext &context, const string &extension_name, + const string &database_name, const string &source_path, + CreateDatabaseExtensionData *data); + +struct CreateDatabaseExtension { + explicit CreateDatabaseExtension(create_database_t function, + unique_ptr data_p = nullptr) + : function(function), data(std::move(data_p)) { + } + + create_database_t function; + unique_ptr data; }; } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/optimizer/optimizer_extension.hpp +// +// +//===----------------------------------------------------------------------===// + + //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/extension.hpp +// duckdb/planner/logical_operator.hpp // // //===----------------------------------------------------------------------===// @@ -19156,2347 +19514,2436 @@ struct DBConfig { + + + + + + +#include +#include + namespace duckdb { -class DuckDB; -//! The Extension class is the base class used to define extensions -class Extension { +class FieldWriter; +class FieldReader; + +//! The current version of the plan serialization format. Exposed via by @Serializer & @Deserializer +//! to be used by various Operator to know what format to read and write. +extern const uint64_t PLAN_SERIALIZATION_VERSION; + +//! LogicalOperator is the base class of the logical operators present in the +//! logical query tree +class LogicalOperator { public: - DUCKDB_API virtual ~Extension(); + explicit LogicalOperator(LogicalOperatorType type); + LogicalOperator(LogicalOperatorType type, vector> expressions); + virtual ~LogicalOperator(); - DUCKDB_API virtual void Load(DuckDB &db) = 0; - DUCKDB_API virtual std::string Name() = 0; -}; + //! The type of the logical operator + LogicalOperatorType type; + //! The set of children of the operator + vector> children; + //! The set of expressions contained within the operator, if any + vector> expressions; + //! The types returned by this logical operator. Set by calling LogicalOperator::ResolveTypes. + vector types; + //! Estimated Cardinality + idx_t estimated_cardinality; + bool has_estimated_cardinality; + + unique_ptr estimated_props; + +public: + virtual vector GetColumnBindings(); + static vector GenerateColumnBindings(idx_t table_idx, idx_t column_count); + static vector MapTypes(const vector &types, const vector &projection_map); + static vector MapBindings(const vector &types, const vector &projection_map); + + //! Resolve the types of the logical operator and its children + void ResolveOperatorTypes(); + + virtual string GetName() const; + virtual string ParamsToString() const; + virtual string ToString() const; + DUCKDB_API void Print(); + //! Debug method: verify that the integrity of expressions & child nodes are maintained + virtual void Verify(ClientContext &context); + + void AddChild(unique_ptr child); + virtual idx_t EstimateCardinality(ClientContext &context); + + //! Serializes a LogicalOperator to a stand-alone binary blob + void Serialize(Serializer &serializer) const; + //! Serializes an LogicalOperator to a stand-alone binary blob + virtual void Serialize(FieldWriter &writer) const = 0; + + static unique_ptr Deserialize(Deserializer &deserializer, PlanDeserializationState &state); + + virtual unique_ptr Copy(ClientContext &context) const; + + virtual bool RequireOptimizer() const { + return true; + } + + //! Returns the set of table indexes of this operator + virtual vector GetTableIndex() const; +protected: + //! Resolve types for this specific operator + virtual void ResolveTypes() = 0; +}; } // namespace duckdb namespace duckdb { -class StorageManager; -class Catalog; -class TransactionManager; -class ConnectionManager; -class FileSystem; -class TaskScheduler; -class ObjectCache; -class DatabaseInstance : public std::enable_shared_from_this { - friend class DuckDB; +//! The OptimizerExtensionInfo holds static information relevant to the optimizer extension +struct OptimizerExtensionInfo { + DUCKDB_API virtual ~OptimizerExtensionInfo() { + } +}; +typedef void (*optimize_function_t)(ClientContext &context, OptimizerExtensionInfo *info, + unique_ptr &plan); + +class OptimizerExtension { public: - DUCKDB_API DatabaseInstance(); - DUCKDB_API ~DatabaseInstance(); + //! The parse function of the parser extension. + //! Takes a query string as input and returns ParserExtensionParseData (on success) or an error + optimize_function_t optimize_function; - DBConfig config; + //! Additional parser info passed to the parse function + shared_ptr optimizer_info; +}; -public: - DUCKDB_API StorageManager &GetStorageManager(); - DUCKDB_API Catalog &GetCatalog(); - DUCKDB_API FileSystem &GetFileSystem(); - DUCKDB_API TransactionManager &GetTransactionManager(); - DUCKDB_API TaskScheduler &GetScheduler(); - DUCKDB_API ObjectCache &GetObjectCache(); - DUCKDB_API ConnectionManager &GetConnectionManager(); - DUCKDB_API ValidChecker &GetValidChecker(); - DUCKDB_API void SetExtensionLoaded(const std::string &extension_name); +} // namespace duckdb - idx_t NumberOfThreads(); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/parser_extension.hpp +// +// +//===----------------------------------------------------------------------===// - DUCKDB_API static DatabaseInstance &GetDatabase(ClientContext &context); - DUCKDB_API const unordered_set &LoadedExtensions(); - DUCKDB_API bool TryGetCurrentSetting(const std::string &key, Value &result); -private: - void Initialize(const char *path, DBConfig *config); - void Configure(DBConfig &config); -private: - unique_ptr storage; - unique_ptr catalog; - unique_ptr transaction_manager; - unique_ptr scheduler; - unique_ptr object_cache; - unique_ptr connection_manager; - unordered_set loaded_extensions; - ValidChecker db_validity; + +namespace duckdb { + +//! The ParserExtensionInfo holds static information relevant to the parser extension +//! It is made available in the parse_function, and will be kept alive as long as the database system is kept alive +struct ParserExtensionInfo { + DUCKDB_API virtual ~ParserExtensionInfo() { + } +}; + +//===--------------------------------------------------------------------===// +// Parse +//===--------------------------------------------------------------------===// +enum class ParserExtensionResultType : uint8_t { PARSE_SUCCESSFUL, DISPLAY_ORIGINAL_ERROR, DISPLAY_EXTENSION_ERROR }; + +//! The ParserExtensionParseData holds the result of a successful parse step +//! It will be passed along to the subsequent plan function +struct ParserExtensionParseData { + DUCKDB_API virtual ~ParserExtensionParseData() { + } + + virtual unique_ptr Copy() const = 0; +}; + +struct ParserExtensionParseResult { + ParserExtensionParseResult() : type(ParserExtensionResultType::DISPLAY_ORIGINAL_ERROR) { + } + ParserExtensionParseResult(string error_p) + : type(ParserExtensionResultType::DISPLAY_EXTENSION_ERROR), error(std::move(error_p)) { + } + ParserExtensionParseResult(unique_ptr parse_data_p) + : type(ParserExtensionResultType::PARSE_SUCCESSFUL), parse_data(std::move(parse_data_p)) { + } + + //! Whether or not parsing was successful + ParserExtensionResultType type; + //! The parse data (if successful) + unique_ptr parse_data; + //! The error message (if unsuccessful) + string error; +}; + +typedef ParserExtensionParseResult (*parse_function_t)(ParserExtensionInfo *info, const string &query); +//===--------------------------------------------------------------------===// +// Plan +//===--------------------------------------------------------------------===// +struct ParserExtensionPlanResult { + //! The table function to execute + TableFunction function; + //! Parameters to the function + vector parameters; + //! The set of databases that will be modified by this statement (empty for a read-only statement) + unordered_set modified_databases; + //! Whether or not the statement requires a valid transaction to be executed + bool requires_valid_transaction = true; + //! What type of result set the statement returns + StatementReturnType return_type = StatementReturnType::NOTHING; +}; + +typedef ParserExtensionPlanResult (*plan_function_t)(ParserExtensionInfo *info, ClientContext &context, + unique_ptr parse_data); + +//===--------------------------------------------------------------------===// +// ParserExtension +//===--------------------------------------------------------------------===// +class ParserExtension { +public: + //! The parse function of the parser extension. + //! Takes a query string as input and returns ParserExtensionParseData (on success) or an error + parse_function_t parse_function; + + //! The plan function of the parser extension + //! Takes as input the result of the parse_function, and outputs various properties of the resulting plan + plan_function_t plan_function; + + //! Additional parser info passed to the parse function + shared_ptr parser_info; }; -//! The database object. This object holds the catalog and all the -//! database-specific meta information. -class DuckDB { -public: - DUCKDB_API explicit DuckDB(const char *path = nullptr, DBConfig *config = nullptr); - DUCKDB_API explicit DuckDB(const string &path, DBConfig *config = nullptr); - DUCKDB_API explicit DuckDB(DatabaseInstance &instance); +} // namespace duckdb + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/operator_extension.hpp +// +// +//===----------------------------------------------------------------------===// + - DUCKDB_API ~DuckDB(); - //! Reference to the actual database instance - shared_ptr instance; -public: - template - void LoadExtension() { - T extension; - if (ExtensionIsLoaded(extension.Name())) { - return; - } - extension.Load(*this); - instance->SetExtensionLoaded(extension.Name()); - } +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/execution/physical_plan_generator.hpp +// +// +//===----------------------------------------------------------------------===// + + - DUCKDB_API FileSystem &GetFileSystem(); - DUCKDB_API idx_t NumberOfThreads(); - DUCKDB_API static const char *SourceID(); - DUCKDB_API static const char *LibraryVersion(); - DUCKDB_API static string Platform(); - DUCKDB_API bool ExtensionIsLoaded(const std::string &name); -}; -} // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB // -// duckdb/main/loadable_extension.hpp +// duckdb/planner/operator/logical_limit_percent.hpp // // //===----------------------------------------------------------------------===// -#if defined(DUCKDB_BUILD_LOADABLE_EXTENSION) && defined(DUCKDB_EXTENSION_MAIN) -#ifdef _WIN32 -#ifndef NOMINMAX -#define NOMINMAX -#endif -#ifndef _WINSOCKAPI_ -#define _WINSOCKAPI_ -#endif -#include -#undef CreateDirectory -#undef MoveFile -#undef RemoveDirectory +namespace duckdb { -#include +//! LogicalLimitPercent represents a LIMIT PERCENT clause +class LogicalLimitPercent : public LogicalOperator { +public: + LogicalLimitPercent(double limit_percent, int64_t offset_val, unique_ptr limit, + unique_ptr offset) + : LogicalOperator(LogicalOperatorType::LOGICAL_LIMIT_PERCENT), limit_percent(limit_percent), + offset_val(offset_val), limit(std::move(limit)), offset(std::move(offset)) { + } -extern "C" { -/* -This is interesting: Windows would normally require a duckdb.dll being on the DLL search path when we load an extension -using LoadLibrary(). However, there is likely no such dll, because DuckDB was statically linked, or is running as part -of an R or Python module with a completely different name (that we don't know) or something of the sorts. Amazingly, -Windows supports lazy-loading DLLs by linking them with /DELAYLOAD. Then a callback will be triggered whenever we access -symbols in the extension. Since DuckDB is already running in the host process (hopefully), we can use -GetModuleHandle(NULL) to return the current process so the symbols are looked for there. See here for another -explanation of this crazy process: + //! Limit percent and offset values in case they are constants, used in optimizations. + double limit_percent; + int64_t offset_val; + //! The maximum amount of elements to emit + unique_ptr limit; + //! The offset from the start to begin emitting elements + unique_ptr offset; -* https://docs.microsoft.com/en-us/cpp/build/reference/linker-support-for-delay-loaded-dlls?view=msvc-160 -* https://docs.microsoft.com/en-us/cpp/build/reference/understanding-the-helper-function?view=msvc-160 -*/ -FARPROC WINAPI duckdb_dllimport_delay_hook(unsigned dliNotify, PDelayLoadInfo pdli) { - switch (dliNotify) { - case dliNotePreLoadLibrary: - if (strcmp(pdli->szDll, "duckdb.dll") != 0) { - return NULL; - } - return (FARPROC)GetModuleHandle(NULL); - default: - return NULL; +public: + vector GetColumnBindings() override { + return children[0]->GetColumnBindings(); } - return NULL; -} + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(LogicalDeserializationState &state, FieldReader &reader); + idx_t EstimateCardinality(ClientContext &context) override; -ExternC const PfnDliHook __pfnDliNotifyHook2 = duckdb_dllimport_delay_hook; -ExternC const PfnDliHook __pfnDliFailureHook2 = duckdb_dllimport_delay_hook; -} -#endif -#endif +protected: + void ResolveTypes() override { + types = children[0]->types; + } +}; +} // namespace duckdb //===----------------------------------------------------------------------===// -// // DuckDB // -// duckdb.h +// duckdb/catalog/dependency_list.hpp // // //===----------------------------------------------------------------------===// -// duplicate of duckdb/main/winapi.hpp -#ifndef DUCKDB_API -#ifdef _WIN32 -#if defined(DUCKDB_BUILD_LIBRARY) && !defined(DUCKDB_BUILD_LOADABLE_EXTENSION) -#define DUCKDB_API __declspec(dllexport) -#else -#define DUCKDB_API __declspec(dllimport) -#endif -#else -#define DUCKDB_API -#endif -#endif -// duplicate of duckdb/main/winapi.hpp -#ifndef DUCKDB_EXTENSION_API -#ifdef _WIN32 -#ifdef DUCKDB_BUILD_LOADABLE_EXTENSION -#define DUCKDB_EXTENSION_API __declspec(dllexport) -#else -#define DUCKDB_EXTENSION_API -#endif -#else -#define DUCKDB_EXTENSION_API __attribute__((visibility("default"))) -#endif -#endif -// duplicate of duckdb/common/constants.hpp -#ifndef DUCKDB_API_0_3_1 -#define DUCKDB_API_0_3_1 1 -#endif -#ifndef DUCKDB_API_0_3_2 -#define DUCKDB_API_0_3_2 2 -#endif -#ifndef DUCKDB_API_LATEST -#define DUCKDB_API_LATEST DUCKDB_API_0_3_2 -#endif -#ifndef DUCKDB_API_VERSION -#define DUCKDB_API_VERSION DUCKDB_API_LATEST -#endif +namespace duckdb { +class CatalogEntry; -#include -#include -#include +//! The DependencyList +class DependencyList { + friend class DependencyManager; -#ifdef __cplusplus -extern "C" { -#endif +public: + DUCKDB_API void AddDependency(CatalogEntry *entry); -//===--------------------------------------------------------------------===// -// Type Information -//===--------------------------------------------------------------------===// -typedef uint64_t idx_t; +private: + unordered_set set; +}; +} // namespace duckdb -typedef enum DUCKDB_TYPE { - DUCKDB_TYPE_INVALID = 0, - // bool - DUCKDB_TYPE_BOOLEAN, - // int8_t - DUCKDB_TYPE_TINYINT, - // int16_t - DUCKDB_TYPE_SMALLINT, - // int32_t - DUCKDB_TYPE_INTEGER, - // int64_t - DUCKDB_TYPE_BIGINT, - // uint8_t - DUCKDB_TYPE_UTINYINT, - // uint16_t - DUCKDB_TYPE_USMALLINT, - // uint32_t - DUCKDB_TYPE_UINTEGER, - // uint64_t - DUCKDB_TYPE_UBIGINT, - // float - DUCKDB_TYPE_FLOAT, - // double - DUCKDB_TYPE_DOUBLE, - // duckdb_timestamp, in microseconds - DUCKDB_TYPE_TIMESTAMP, - // duckdb_date - DUCKDB_TYPE_DATE, - // duckdb_time - DUCKDB_TYPE_TIME, - // duckdb_interval - DUCKDB_TYPE_INTERVAL, - // duckdb_hugeint - DUCKDB_TYPE_HUGEINT, - // const char* - DUCKDB_TYPE_VARCHAR, - // duckdb_blob - DUCKDB_TYPE_BLOB, - // decimal - DUCKDB_TYPE_DECIMAL, - // duckdb_timestamp, in seconds - DUCKDB_TYPE_TIMESTAMP_S, - // duckdb_timestamp, in milliseconds - DUCKDB_TYPE_TIMESTAMP_MS, - // duckdb_timestamp, in nanoseconds - DUCKDB_TYPE_TIMESTAMP_NS, - // enum type, only useful as logical type - DUCKDB_TYPE_ENUM, - // list type, only useful as logical type - DUCKDB_TYPE_LIST, - // struct type, only useful as logical type - DUCKDB_TYPE_STRUCT, - // map type, only useful as logical type - DUCKDB_TYPE_MAP, - // duckdb_hugeint - DUCKDB_TYPE_UUID, - // const char* - DUCKDB_TYPE_JSON, - // union type, only useful as logical type - DUCKDB_TYPE_UNION, -} duckdb_type; -//! Days are stored as days since 1970-01-01 -//! Use the duckdb_from_date/duckdb_to_date function to extract individual information -typedef struct { - int32_t days; -} duckdb_date; -typedef struct { - int32_t year; - int8_t month; - int8_t day; -} duckdb_date_struct; -//! Time is stored as microseconds since 00:00:00 -//! Use the duckdb_from_time/duckdb_to_time function to extract individual information -typedef struct { - int64_t micros; -} duckdb_time; +namespace duckdb { +class ClientContext; +class ColumnDataCollection; + +//! The physical plan generator generates a physical execution plan from a +//! logical query plan +class PhysicalPlanGenerator { +public: + explicit PhysicalPlanGenerator(ClientContext &context); + ~PhysicalPlanGenerator(); + + DependencyList dependencies; + //! Recursive CTEs require at least one ChunkScan, referencing the working_table. + //! This data structure is used to establish it. + unordered_map> recursive_cte_tables; + +public: + //! Creates a plan from the logical operator. This involves resolving column bindings and generating physical + //! operator nodes. + unique_ptr CreatePlan(unique_ptr logical); + + //! Whether or not we can (or should) use a batch-index based operator for executing the given sink + static bool UseBatchIndex(ClientContext &context, PhysicalOperator &plan); + //! Whether or not we should preserve insertion order for executing the given sink + static bool PreserveInsertionOrder(ClientContext &context, PhysicalOperator &plan); + +protected: + unique_ptr CreatePlan(LogicalOperator &op); + + unique_ptr CreatePlan(LogicalAggregate &op); + unique_ptr CreatePlan(LogicalAnyJoin &op); + unique_ptr CreatePlan(LogicalColumnDataGet &op); + unique_ptr CreatePlan(LogicalComparisonJoin &op); + unique_ptr CreatePlan(LogicalCreate &op); + unique_ptr CreatePlan(LogicalCreateTable &op); + unique_ptr CreatePlan(LogicalCreateIndex &op); + unique_ptr CreatePlan(LogicalCrossProduct &op); + unique_ptr CreatePlan(LogicalDelete &op); + unique_ptr CreatePlan(LogicalDelimGet &op); + unique_ptr CreatePlan(LogicalDelimJoin &op); + unique_ptr CreatePlan(LogicalDistinct &op); + unique_ptr CreatePlan(LogicalDummyScan &expr); + unique_ptr CreatePlan(LogicalEmptyResult &op); + unique_ptr CreatePlan(LogicalExpressionGet &op); + unique_ptr CreatePlan(LogicalExport &op); + unique_ptr CreatePlan(LogicalFilter &op); + unique_ptr CreatePlan(LogicalGet &op); + unique_ptr CreatePlan(LogicalLimit &op); + unique_ptr CreatePlan(LogicalLimitPercent &op); + unique_ptr CreatePlan(LogicalOrder &op); + unique_ptr CreatePlan(LogicalTopN &op); + unique_ptr CreatePlan(LogicalPositionalJoin &op); + unique_ptr CreatePlan(LogicalProjection &op); + unique_ptr CreatePlan(LogicalInsert &op); + unique_ptr CreatePlan(LogicalCopyToFile &op); + unique_ptr CreatePlan(LogicalExplain &op); + unique_ptr CreatePlan(LogicalSetOperation &op); + unique_ptr CreatePlan(LogicalUpdate &op); + unique_ptr CreatePlan(LogicalPrepare &expr); + unique_ptr CreatePlan(LogicalWindow &expr); + unique_ptr CreatePlan(LogicalExecute &op); + unique_ptr CreatePlan(LogicalPragma &op); + unique_ptr CreatePlan(LogicalSample &op); + unique_ptr CreatePlan(LogicalSet &op); + unique_ptr CreatePlan(LogicalReset &op); + unique_ptr CreatePlan(LogicalShow &op); + unique_ptr CreatePlan(LogicalSimple &op); + unique_ptr CreatePlan(LogicalUnnest &op); + unique_ptr CreatePlan(LogicalRecursiveCTE &op); + unique_ptr CreatePlan(LogicalCTERef &op); + + unique_ptr CreateDistinctOn(unique_ptr child, + vector> distinct_targets); + + unique_ptr ExtractAggregateExpressions(unique_ptr child, + vector> &expressions, + vector> &groups); -typedef struct { - int8_t hour; - int8_t min; - int8_t sec; - int32_t micros; -} duckdb_time_struct; +private: + bool PreserveInsertionOrder(PhysicalOperator &plan); + bool UseBatchIndex(PhysicalOperator &plan); -//! Timestamps are stored as microseconds since 1970-01-01 -//! Use the duckdb_from_timestamp/duckdb_to_timestamp function to extract individual information -typedef struct { - int64_t micros; -} duckdb_timestamp; +private: + ClientContext &context; +}; +} // namespace duckdb -typedef struct { - duckdb_date_struct date; - duckdb_time_struct time; -} duckdb_timestamp_struct; +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/binder.hpp +// +// +//===----------------------------------------------------------------------===// -typedef struct { - int32_t months; - int32_t days; - int64_t micros; -} duckdb_interval; -//! Hugeints are composed in a (lower, upper) component -//! The value of the hugeint is upper * 2^64 + lower -//! For easy usage, the functions duckdb_hugeint_to_double/duckdb_double_to_hugeint are recommended -typedef struct { - uint64_t lower; - int64_t upper; -} duckdb_hugeint; -typedef struct { - uint8_t width; - uint8_t scale; - duckdb_hugeint value; -} duckdb_decimal; -typedef struct { - char *data; - idx_t size; -} duckdb_string; -typedef struct { - void *data; - idx_t size; -} duckdb_blob; -typedef struct { -#if DUCKDB_API_VERSION < DUCKDB_API_0_3_2 - void *data; - bool *nullmask; - duckdb_type type; - char *name; -#else - // deprecated, use duckdb_column_data - void *__deprecated_data; - // deprecated, use duckdb_nullmask_data - bool *__deprecated_nullmask; - // deprecated, use duckdb_column_type - duckdb_type __deprecated_type; - // deprecated, use duckdb_column_name - char *__deprecated_name; -#endif - void *internal_data; -} duckdb_column; -typedef struct { -#if DUCKDB_API_VERSION < DUCKDB_API_0_3_2 - idx_t column_count; - idx_t row_count; - idx_t rows_changed; - duckdb_column *columns; - char *error_message; -#else - // deprecated, use duckdb_column_count - idx_t __deprecated_column_count; - // deprecated, use duckdb_row_count - idx_t __deprecated_row_count; - // deprecated, use duckdb_rows_changed - idx_t __deprecated_rows_changed; - // deprecated, use duckdb_column_ family of functions - duckdb_column *__deprecated_columns; - // deprecated, use duckdb_result_error - char *__deprecated_error_message; -#endif - void *internal_data; -} duckdb_result; +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/query_node.hpp +// +// +//===----------------------------------------------------------------------===// -typedef void *duckdb_database; -typedef void *duckdb_connection; -typedef void *duckdb_prepared_statement; -typedef void *duckdb_pending_result; -typedef void *duckdb_appender; -typedef void *duckdb_arrow; -typedef void *duckdb_config; -typedef void *duckdb_arrow_schema; -typedef void *duckdb_arrow_array; -typedef void *duckdb_logical_type; -typedef void *duckdb_data_chunk; -typedef void *duckdb_vector; -typedef void *duckdb_value; -typedef enum { DuckDBSuccess = 0, DuckDBError = 1 } duckdb_state; -typedef enum { - DUCKDB_PENDING_RESULT_READY = 0, - DUCKDB_PENDING_RESULT_NOT_READY = 1, - DUCKDB_PENDING_ERROR = 2 -} duckdb_pending_state; -//===--------------------------------------------------------------------===// -// Open/Connect -//===--------------------------------------------------------------------===// -/*! -Creates a new database or opens an existing database file stored at the the given path. -If no path is given a new in-memory database is created instead. -* path: Path to the database file on disk, or `nullptr` or `:memory:` to open an in-memory database. -* out_database: The result database object. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_open(const char *path, duckdb_database *out_database); -/*! -Extended version of duckdb_open. Creates a new database or opens an existing database file stored at the the given path. -* path: Path to the database file on disk, or `nullptr` or `:memory:` to open an in-memory database. -* out_database: The result database object. -* config: (Optional) configuration used to start up the database system. -* out_error: If set and the function returns DuckDBError, this will contain the reason why the start-up failed. -Note that the error must be freed using `duckdb_free`. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_open_ext(const char *path, duckdb_database *out_database, duckdb_config config, - char **out_error); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/common_table_expression_info.hpp +// +// +//===----------------------------------------------------------------------===// -/*! -Closes the specified database and de-allocates all memory allocated for that database. -This should be called after you are done with any database allocated through `duckdb_open`. -Note that failing to call `duckdb_close` (in case of e.g. a program crash) will not cause data corruption. -Still it is recommended to always correctly close a database object after you are done with it. -* database: The database object to shut down. -*/ -DUCKDB_API void duckdb_close(duckdb_database *database); -/*! -Opens a connection to a database. Connections are required to query the database, and store transactional state -associated with the connection. +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/statement/select_statement.hpp +// +// +//===----------------------------------------------------------------------===// -* database: The database file to connect to. -* out_connection: The result connection object. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_connect(duckdb_database database, duckdb_connection *out_connection); -/*! -Closes the specified connection and de-allocates all memory allocated for that connection. -* connection: The connection to close. -*/ -DUCKDB_API void duckdb_disconnect(duckdb_connection *connection); -/*! -Returns the version of the linked DuckDB, with a version postfix for dev versions -Usually used for developing C extensions that must return this for a compatibility check. -*/ -DUCKDB_API const char *duckdb_library_version(); -//===--------------------------------------------------------------------===// -// Configuration -//===--------------------------------------------------------------------===// -/*! -Initializes an empty configuration object that can be used to provide start-up options for the DuckDB instance -through `duckdb_open_ext`. -This will always succeed unless there is a malloc failure. +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/tableref.hpp +// +// +//===----------------------------------------------------------------------===// -* out_config: The result configuration object. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_create_config(duckdb_config *out_config); -/*! -This returns the total amount of configuration options available for usage with `duckdb_get_config_flag`. -This should not be called in a loop as it internally loops over all the options. -* returns: The amount of config options available. -*/ -DUCKDB_API size_t duckdb_config_count(); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/enums/tableref_type.hpp +// +// +//===----------------------------------------------------------------------===// + -/*! -Obtains a human-readable name and description of a specific configuration option. This can be used to e.g. -display configuration options. This will succeed unless `index` is out of range (i.e. `>= duckdb_config_count`). -The result name or description MUST NOT be freed. -* index: The index of the configuration option (between 0 and `duckdb_config_count`) -* out_name: A name of the configuration flag. -* out_description: A description of the configuration flag. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_get_config_flag(size_t index, const char **out_name, const char **out_description); -/*! -Sets the specified option for the specified configuration. The configuration option is indicated by name. -To obtain a list of config options, see `duckdb_get_config_flag`. +namespace duckdb { -In the source code, configuration options are defined in `config.cpp`. +//===--------------------------------------------------------------------===// +// Table Reference Types +//===--------------------------------------------------------------------===// +enum class TableReferenceType : uint8_t { + INVALID = 0, // invalid table reference type + BASE_TABLE = 1, // base table reference + SUBQUERY = 2, // output of a subquery + JOIN = 3, // output of join + TABLE_FUNCTION = 5, // table producing function + EXPRESSION_LIST = 6, // expression list + CTE = 7, // Recursive CTE + EMPTY = 8 // placeholder for empty FROM +}; -This can fail if either the name is invalid, or if the value provided for the option is invalid. +} // namespace duckdb -* duckdb_config: The configuration object to set the option on. -* name: The name of the configuration flag to set. -* option: The value to set the configuration flag to. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_set_config(duckdb_config config, const char *name, const char *option); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/parsed_data/sample_options.hpp +// +// +//===----------------------------------------------------------------------===// -/*! -Destroys the specified configuration option and de-allocates all memory allocated for the object. -* config: The configuration object to destroy. -*/ -DUCKDB_API void duckdb_destroy_config(duckdb_config *config); -//===--------------------------------------------------------------------===// -// Query Execution -//===--------------------------------------------------------------------===// -/*! -Executes a SQL query within a connection and stores the full (materialized) result in the out_result pointer. -If the query fails to execute, DuckDBError is returned and the error message can be retrieved by calling -`duckdb_result_error`. -Note that after running `duckdb_query`, `duckdb_destroy_result` must be called on the result object even if the -query fails, otherwise the error stored within the result will not be freed correctly. -* connection: The connection to perform the query in. -* query: The SQL query to run. -* out_result: The query result. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_query(duckdb_connection connection, const char *query, duckdb_result *out_result); -/*! -Closes the result and de-allocates all memory allocated for that connection. -* result: The result to destroy. -*/ -DUCKDB_API void duckdb_destroy_result(duckdb_result *result); -/*! -Returns the column name of the specified column. The result should not need be freed; the column names will -automatically be destroyed when the result is destroyed. +namespace duckdb { -Returns `NULL` if the column is out of range. +enum class SampleMethod : uint8_t { SYSTEM_SAMPLE = 0, BERNOULLI_SAMPLE = 1, RESERVOIR_SAMPLE = 2 }; -* result: The result object to fetch the column name from. -* col: The column index. -* returns: The column name of the specified column. -*/ -DUCKDB_API const char *duckdb_column_name(duckdb_result *result, idx_t col); +string SampleMethodToString(SampleMethod method); -/*! -Returns the column type of the specified column. +struct SampleOptions { + Value sample_size; + bool is_percentage; + SampleMethod method; + int64_t seed = -1; -Returns `DUCKDB_TYPE_INVALID` if the column is out of range. + unique_ptr Copy(); + void Serialize(Serializer &serializer); + static unique_ptr Deserialize(Deserializer &source); + static bool Equals(SampleOptions *a, SampleOptions *b); +}; -* result: The result object to fetch the column type from. -* col: The column index. -* returns: The column type of the specified column. -*/ -DUCKDB_API duckdb_type duckdb_column_type(duckdb_result *result, idx_t col); +} // namespace duckdb -/*! -Returns the logical column type of the specified column. -The return type of this call should be destroyed with `duckdb_destroy_logical_type`. +namespace duckdb { +class Deserializer; +class Serializer; -Returns `NULL` if the column is out of range. +//! Represents a generic expression that returns a table. +class TableRef { +public: + explicit TableRef(TableReferenceType type) : type(type) { + } + virtual ~TableRef() { + } -* result: The result object to fetch the column type from. -* col: The column index. -* returns: The logical column type of the specified column. -*/ -DUCKDB_API duckdb_logical_type duckdb_column_logical_type(duckdb_result *result, idx_t col); + TableReferenceType type; + string alias; + //! Sample options (if any) + unique_ptr sample; + //! The location in the query (if any) + idx_t query_location = DConstants::INVALID_INDEX; -/*! -Returns the number of columns present in a the result object. +public: + //! Convert the object to a string + virtual string ToString() const = 0; + string BaseToString(string result) const; + string BaseToString(string result, const vector &column_name_alias) const; + void Print(); -* result: The result object. -* returns: The number of columns present in the result object. -*/ -DUCKDB_API idx_t duckdb_column_count(duckdb_result *result); + virtual bool Equals(const TableRef *other) const; -/*! -Returns the number of rows present in a the result object. + virtual unique_ptr Copy() = 0; -* result: The result object. -* returns: The number of rows present in the result object. -*/ -DUCKDB_API idx_t duckdb_row_count(duckdb_result *result); + //! Serializes a TableRef to a stand-alone binary blob + DUCKDB_API void Serialize(Serializer &serializer) const; + //! Serializes a TableRef to a stand-alone binary blob + DUCKDB_API virtual void Serialize(FieldWriter &writer) const = 0; + //! Deserializes a blob back into a TableRef + DUCKDB_API static unique_ptr Deserialize(Deserializer &source); -/*! -Returns the number of rows changed by the query stored in the result. This is relevant only for INSERT/UPDATE/DELETE -queries. For other queries the rows_changed will be 0. + //! Copy the properties of this table ref to the target + void CopyProperties(TableRef &target) const; +}; +} // namespace duckdb -* result: The result object. -* returns: The number of rows changed. -*/ -DUCKDB_API idx_t duckdb_rows_changed(duckdb_result *result); -/*! -**DEPRECATED**: Prefer using `duckdb_result_get_chunk` instead. +namespace duckdb { -Returns the data of a specific column of a result in columnar format. +class QueryNode; -The function returns a dense array which contains the result data. The exact type stored in the array depends on the -corresponding duckdb_type (as provided by `duckdb_column_type`). For the exact type by which the data should be -accessed, see the comments in [the types section](types) or the `DUCKDB_TYPE` enum. +//! SelectStatement is a typical SELECT clause +class SelectStatement : public SQLStatement { +public: + SelectStatement() : SQLStatement(StatementType::SELECT_STATEMENT) { + } -For example, for a column of type `DUCKDB_TYPE_INTEGER`, rows can be accessed in the following manner: -```c -int32_t *data = (int32_t *) duckdb_column_data(&result, 0); -printf("Data for row %d: %d\n", row, data[row]); -``` + //! The main query node + unique_ptr node; -* result: The result object to fetch the column data from. -* col: The column index. -* returns: The column data of the specified column. -*/ -DUCKDB_API void *duckdb_column_data(duckdb_result *result, idx_t col); +protected: + SelectStatement(const SelectStatement &other); -/*! -**DEPRECATED**: Prefer using `duckdb_result_get_chunk` instead. +public: + //! Convert the SELECT statement to a string + string ToString() const override; + //! Create a copy of this SelectStatement + unique_ptr Copy() const override; + //! Serializes a SelectStatement to a stand-alone binary blob + void Serialize(Serializer &serializer) const; + //! Deserializes a blob back into a SelectStatement, returns nullptr if + //! deserialization is not possible + static unique_ptr Deserialize(Deserializer &source); + //! Whether or not the statements are equivalent + bool Equals(const SQLStatement *other) const; +}; +} // namespace duckdb -Returns the nullmask of a specific column of a result in columnar format. The nullmask indicates for every row -whether or not the corresponding row is `NULL`. If a row is `NULL`, the values present in the array provided -by `duckdb_column_data` are undefined. -```c -int32_t *data = (int32_t *) duckdb_column_data(&result, 0); -bool *nullmask = duckdb_nullmask_data(&result, 0); -if (nullmask[row]) { - printf("Data for row %d: NULL\n", row); -} else { - printf("Data for row %d: %d\n", row, data[row]); -} -``` +namespace duckdb { -* result: The result object to fetch the nullmask from. -* col: The column index. -* returns: The nullmask of the specified column. -*/ -DUCKDB_API bool *duckdb_nullmask_data(duckdb_result *result, idx_t col); +class SelectStatement; -/*! -Returns the error message contained within the result. The error is only set if `duckdb_query` returns `DuckDBError`. +struct CommonTableExpressionInfo { + vector aliases; + unique_ptr query; +}; -The result of this function must not be freed. It will be cleaned up when `duckdb_destroy_result` is called. +} // namespace duckdb -* result: The result object to fetch the error from. -* returns: The error of the result. -*/ -DUCKDB_API const char *duckdb_result_error(duckdb_result *result); -//===--------------------------------------------------------------------===// -// Result Functions -//===--------------------------------------------------------------------===// +namespace duckdb { -/*! -Fetches a data chunk from the duckdb_result. This function should be called repeatedly until the result is exhausted. +enum QueryNodeType : uint8_t { + SELECT_NODE = 1, + SET_OPERATION_NODE = 2, + BOUND_SUBQUERY_NODE = 3, + RECURSIVE_CTE_NODE = 4 +}; -The result must be destroyed with `duckdb_destroy_data_chunk`. +struct CommonTableExpressionInfo; -This function supersedes all `duckdb_value` functions, as well as the `duckdb_column_data` and `duckdb_nullmask_data` -functions. It results in significantly better performance, and should be preferred in newer code-bases. +class CommonTableExpressionMap { +public: + CommonTableExpressionMap(); -If this function is used, none of the other result functions can be used and vice versa (i.e. this function cannot be -mixed with the legacy result functions). + unordered_map> map; -Use `duckdb_result_chunk_count` to figure out how many chunks there are in the result. +public: + string ToString() const; + CommonTableExpressionMap Copy() const; +}; -* result: The result object to fetch the data chunk from. -* chunk_index: The chunk index to fetch from. -* returns: The resulting data chunk. Returns `NULL` if the chunk index is out of bounds. -*/ -DUCKDB_API duckdb_data_chunk duckdb_result_get_chunk(duckdb_result result, idx_t chunk_index); +class QueryNode { +public: + explicit QueryNode(QueryNodeType type) : type(type) { + } + virtual ~QueryNode() { + } -/*! -Returns the number of data chunks present in the result. + //! The type of the query node, either SetOperation or Select + QueryNodeType type; + //! The set of result modifiers associated with this query node + vector> modifiers; + //! CTEs (used by SelectNode and SetOperationNode) + CommonTableExpressionMap cte_map; -* result: The result object -* returns: The resulting data chunk. Returns `NULL` if the chunk index is out of bounds. -*/ -DUCKDB_API idx_t duckdb_result_chunk_count(duckdb_result result); + virtual const vector> &GetSelectList() const = 0; -// Safe fetch functions -// These functions will perform conversions if necessary. -// On failure (e.g. if conversion cannot be performed or if the value is NULL) a default value is returned. -// Note that these functions are slow since they perform bounds checking and conversion -// For fast access of values prefer using `duckdb_result_get_chunk` +public: + //! Convert the query node to a string + virtual string ToString() const = 0; -/*! - * returns: The boolean value at the specified location, or false if the value cannot be converted. - */ -DUCKDB_API bool duckdb_value_boolean(duckdb_result *result, idx_t col, idx_t row); + virtual bool Equals(const QueryNode *other) const; -/*! - * returns: The int8_t value at the specified location, or 0 if the value cannot be converted. - */ -DUCKDB_API int8_t duckdb_value_int8(duckdb_result *result, idx_t col, idx_t row); + //! Create a copy of this QueryNode + virtual unique_ptr Copy() const = 0; + //! Serializes a QueryNode to a stand-alone binary blob + DUCKDB_API void Serialize(Serializer &serializer) const; + //! Serializes a QueryNode to a stand-alone binary blob + DUCKDB_API virtual void Serialize(FieldWriter &writer) const = 0; + //! Deserializes a blob back into a QueryNode + DUCKDB_API static unique_ptr Deserialize(Deserializer &source); -/*! - * returns: The int16_t value at the specified location, or 0 if the value cannot be converted. - */ -DUCKDB_API int16_t duckdb_value_int16(duckdb_result *result, idx_t col, idx_t row); + string ResultModifiersToString() const; -/*! - * returns: The int32_t value at the specified location, or 0 if the value cannot be converted. - */ -DUCKDB_API int32_t duckdb_value_int32(duckdb_result *result, idx_t col, idx_t row); + //! Adds a distinct modifier to the query node + void AddDistinct(); -/*! - * returns: The int64_t value at the specified location, or 0 if the value cannot be converted. - */ -DUCKDB_API int64_t duckdb_value_int64(duckdb_result *result, idx_t col, idx_t row); +protected: + //! Copy base QueryNode properties from another expression to this one, + //! used in Copy method + void CopyProperties(QueryNode &other) const; +}; -/*! - * returns: The duckdb_hugeint value at the specified location, or 0 if the value cannot be converted. - */ -DUCKDB_API duckdb_hugeint duckdb_value_hugeint(duckdb_result *result, idx_t col, idx_t row); +} // namespace duckdb -/*! - * returns: The duckdb_decimal value at the specified location, or 0 if the value cannot be converted. - */ -DUCKDB_API duckdb_decimal duckdb_value_decimal(duckdb_result *result, idx_t col, idx_t row); -/*! - * returns: The uint8_t value at the specified location, or 0 if the value cannot be converted. - */ -DUCKDB_API uint8_t duckdb_value_uint8(duckdb_result *result, idx_t col, idx_t row); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/tokens.hpp +// +// +//===----------------------------------------------------------------------===// -/*! - * returns: The uint16_t value at the specified location, or 0 if the value cannot be converted. - */ -DUCKDB_API uint16_t duckdb_value_uint16(duckdb_result *result, idx_t col, idx_t row); -/*! - * returns: The uint32_t value at the specified location, or 0 if the value cannot be converted. - */ -DUCKDB_API uint32_t duckdb_value_uint32(duckdb_result *result, idx_t col, idx_t row); -/*! - * returns: The uint64_t value at the specified location, or 0 if the value cannot be converted. - */ -DUCKDB_API uint64_t duckdb_value_uint64(duckdb_result *result, idx_t col, idx_t row); +namespace duckdb { -/*! - * returns: The float value at the specified location, or 0 if the value cannot be converted. - */ -DUCKDB_API float duckdb_value_float(duckdb_result *result, idx_t col, idx_t row); +//===--------------------------------------------------------------------===// +// Statements +//===--------------------------------------------------------------------===// +class SQLStatement; -/*! - * returns: The double value at the specified location, or 0 if the value cannot be converted. - */ -DUCKDB_API double duckdb_value_double(duckdb_result *result, idx_t col, idx_t row); +class AlterStatement; +class AttachStatement; +class CallStatement; +class CopyStatement; +class CreateStatement; +class DeleteStatement; +class DropStatement; +class ExtensionStatement; +class InsertStatement; +class SelectStatement; +class TransactionStatement; +class UpdateStatement; +class PrepareStatement; +class ExecuteStatement; +class PragmaStatement; +class ShowStatement; +class ExplainStatement; +class ExportStatement; +class VacuumStatement; +class RelationStatement; +class SetStatement; +class SetVariableStatement; +class ResetVariableStatement; +class LoadStatement; +class LogicalPlanStatement; -/*! - * returns: The duckdb_date value at the specified location, or 0 if the value cannot be converted. - */ -DUCKDB_API duckdb_date duckdb_value_date(duckdb_result *result, idx_t col, idx_t row); +//===--------------------------------------------------------------------===// +// Query Node +//===--------------------------------------------------------------------===// +class QueryNode; +class SelectNode; +class SetOperationNode; +class RecursiveCTENode; -/*! - * returns: The duckdb_time value at the specified location, or 0 if the value cannot be converted. - */ -DUCKDB_API duckdb_time duckdb_value_time(duckdb_result *result, idx_t col, idx_t row); +//===--------------------------------------------------------------------===// +// Expressions +//===--------------------------------------------------------------------===// +class ParsedExpression; -/*! - * returns: The duckdb_timestamp value at the specified location, or 0 if the value cannot be converted. - */ -DUCKDB_API duckdb_timestamp duckdb_value_timestamp(duckdb_result *result, idx_t col, idx_t row); +class BetweenExpression; +class CaseExpression; +class CastExpression; +class CollateExpression; +class ColumnRefExpression; +class ComparisonExpression; +class ConjunctionExpression; +class ConstantExpression; +class DefaultExpression; +class FunctionExpression; +class LambdaExpression; +class OperatorExpression; +class ParameterExpression; +class PositionalReferenceExpression; +class StarExpression; +class SubqueryExpression; +class WindowExpression; -/*! - * returns: The duckdb_interval value at the specified location, or 0 if the value cannot be converted. - */ -DUCKDB_API duckdb_interval duckdb_value_interval(duckdb_result *result, idx_t col, idx_t row); +//===--------------------------------------------------------------------===// +// Constraints +//===--------------------------------------------------------------------===// +class Constraint; -/*! -* DEPRECATED: use duckdb_value_string instead. This function does not work correctly if the string contains null bytes. -* returns: The text value at the specified location as a null-terminated string, or nullptr if the value cannot be -converted. The result must be freed with `duckdb_free`. -*/ -DUCKDB_API char *duckdb_value_varchar(duckdb_result *result, idx_t col, idx_t row); +class NotNullConstraint; +class CheckConstraint; +class UniqueConstraint; +class ForeignKeyConstraint; -/*!s -* returns: The string value at the specified location. -The result must be freed with `duckdb_free`. -*/ -DUCKDB_API duckdb_string duckdb_value_string(duckdb_result *result, idx_t col, idx_t row); +//===--------------------------------------------------------------------===// +// TableRefs +//===--------------------------------------------------------------------===// +class TableRef; -/*! -* DEPRECATED: use duckdb_value_string_internal instead. This function does not work correctly if the string contains -null bytes. -* returns: The char* value at the specified location. ONLY works on VARCHAR columns and does not auto-cast. -If the column is NOT a VARCHAR column this function will return NULL. +class BaseTableRef; +class JoinRef; +class SubqueryRef; +class TableFunctionRef; +class EmptyTableRef; +class ExpressionListRef; -The result must NOT be freed. -*/ -DUCKDB_API char *duckdb_value_varchar_internal(duckdb_result *result, idx_t col, idx_t row); +//===--------------------------------------------------------------------===// +// Other +//===--------------------------------------------------------------------===// +struct SampleOptions; -/*! -* DEPRECATED: use duckdb_value_string_internal instead. This function does not work correctly if the string contains -null bytes. -* returns: The char* value at the specified location. ONLY works on VARCHAR columns and does not auto-cast. -If the column is NOT a VARCHAR column this function will return NULL. +} // namespace duckdb -The result must NOT be freed. -*/ -DUCKDB_API duckdb_string duckdb_value_string_internal(duckdb_result *result, idx_t col, idx_t row); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/bind_context.hpp +// +// +//===----------------------------------------------------------------------===// -/*! -* returns: The duckdb_blob value at the specified location. Returns a blob with blob.data set to nullptr if the -value cannot be converted. The resulting "blob.data" must be freed with `duckdb_free.` -*/ -DUCKDB_API duckdb_blob duckdb_value_blob(duckdb_result *result, idx_t col, idx_t row); -/*! - * returns: Returns true if the value at the specified index is NULL, and false otherwise. - */ -DUCKDB_API bool duckdb_value_is_null(duckdb_result *result, idx_t col, idx_t row); -//===--------------------------------------------------------------------===// -// Helpers -//===--------------------------------------------------------------------===// -/*! -Allocate `size` bytes of memory using the duckdb internal malloc function. Any memory allocated in this manner -should be freed using `duckdb_free`. -* size: The number of bytes to allocate. -* returns: A pointer to the allocated memory region. -*/ -DUCKDB_API void *duckdb_malloc(size_t size); -/*! -Free a value returned from `duckdb_malloc`, `duckdb_value_varchar` or `duckdb_value_blob`. -* ptr: The memory region to de-allocate. -*/ -DUCKDB_API void duckdb_free(void *ptr); -/*! -The internal vector size used by DuckDB. -This is the amount of tuples that will fit into a data chunk created by `duckdb_create_data_chunk`. +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/expression/columnref_expression.hpp +// +// +//===----------------------------------------------------------------------===// -* returns: The vector size. -*/ -DUCKDB_API idx_t duckdb_vector_size(); -//===--------------------------------------------------------------------===// -// Date/Time/Timestamp Helpers -//===--------------------------------------------------------------------===// -/*! -Decompose a `duckdb_date` object into year, month and date (stored as `duckdb_date_struct`). -* date: The date object, as obtained from a `DUCKDB_TYPE_DATE` column. -* returns: The `duckdb_date_struct` with the decomposed elements. -*/ -DUCKDB_API duckdb_date_struct duckdb_from_date(duckdb_date date); -/*! -Re-compose a `duckdb_date` from year, month and date (`duckdb_date_struct`). -* date: The year, month and date stored in a `duckdb_date_struct`. -* returns: The `duckdb_date` element. -*/ -DUCKDB_API duckdb_date duckdb_to_date(duckdb_date_struct date); -/*! -Decompose a `duckdb_time` object into hour, minute, second and microsecond (stored as `duckdb_time_struct`). +namespace duckdb { -* time: The time object, as obtained from a `DUCKDB_TYPE_TIME` column. -* returns: The `duckdb_time_struct` with the decomposed elements. -*/ -DUCKDB_API duckdb_time_struct duckdb_from_time(duckdb_time time); +//! Represents a reference to a column from either the FROM clause or from an +//! alias +class ColumnRefExpression : public ParsedExpression { +public: + //! Specify both the column and table name + ColumnRefExpression(string column_name, string table_name); + //! Only specify the column name, the table name will be derived later + explicit ColumnRefExpression(string column_name); + //! Specify a set of names + explicit ColumnRefExpression(vector column_names); -/*! -Re-compose a `duckdb_time` from hour, minute, second and microsecond (`duckdb_time_struct`). + //! The stack of names in order of which they appear (column_names[0].column_names[1].column_names[2]....) + vector column_names; -* time: The hour, minute, second and microsecond in a `duckdb_time_struct`. -* returns: The `duckdb_time` element. -*/ -DUCKDB_API duckdb_time duckdb_to_time(duckdb_time_struct time); +public: + bool IsQualified() const; + const string &GetColumnName() const; + const string &GetTableName() const; + bool IsScalar() const override { + return false; + } -/*! -Decompose a `duckdb_timestamp` object into a `duckdb_timestamp_struct`. + string GetName() const override; + string ToString() const override; -* ts: The ts object, as obtained from a `DUCKDB_TYPE_TIMESTAMP` column. -* returns: The `duckdb_timestamp_struct` with the decomposed elements. -*/ -DUCKDB_API duckdb_timestamp_struct duckdb_from_timestamp(duckdb_timestamp ts); + static bool Equal(const ColumnRefExpression *a, const ColumnRefExpression *b); + hash_t Hash() const override; -/*! -Re-compose a `duckdb_timestamp` from a duckdb_timestamp_struct. + unique_ptr Copy() const override; -* ts: The de-composed elements in a `duckdb_timestamp_struct`. -* returns: The `duckdb_timestamp` element. -*/ -DUCKDB_API duckdb_timestamp duckdb_to_timestamp(duckdb_timestamp_struct ts); + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(ExpressionType type, FieldReader &source); +}; +} // namespace duckdb -//===--------------------------------------------------------------------===// -// Hugeint Helpers -//===--------------------------------------------------------------------===// -/*! -Converts a duckdb_hugeint object (as obtained from a `DUCKDB_TYPE_HUGEINT` column) into a double. -* val: The hugeint value. -* returns: The converted `double` element. -*/ -DUCKDB_API double duckdb_hugeint_to_double(duckdb_hugeint val); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/qualified_name_set.hpp +// +// +//===----------------------------------------------------------------------===// -/*! -Converts a double value to a duckdb_hugeint object. -If the conversion fails because the double value is too big the result will be 0. -* val: The double value. -* returns: The converted `duckdb_hugeint` element. -*/ -DUCKDB_API duckdb_hugeint duckdb_double_to_hugeint(double val); -/*! -Converts a double value to a duckdb_decimal object. +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/common/types/hash.hpp +// +// +//===----------------------------------------------------------------------===// -If the conversion fails because the double value is too big, or the width/scale are invalid the result will be 0. -* val: The double value. -* returns: The converted `duckdb_decimal` element. -*/ -DUCKDB_API duckdb_decimal duckdb_double_to_decimal(double val, uint8_t width, uint8_t scale); -//===--------------------------------------------------------------------===// -// Decimal Helpers -//===--------------------------------------------------------------------===// -/*! -Converts a duckdb_decimal object (as obtained from a `DUCKDB_TYPE_DECIMAL` column) into a double. -* val: The decimal value. -* returns: The converted `double` element. -*/ -DUCKDB_API double duckdb_decimal_to_double(duckdb_decimal val); -//===--------------------------------------------------------------------===// -// Prepared Statements -//===--------------------------------------------------------------------===// -// A prepared statement is a parameterized query that allows you to bind parameters to it. -// * This is useful to easily supply parameters to functions and avoid SQL injection attacks. -// * This is useful to speed up queries that you will execute several times with different parameters. -// Because the query will only be parsed, bound, optimized and planned once during the prepare stage, -// rather than once per execution. -// For example: -// SELECT * FROM tbl WHERE id=? -// Or a query with multiple parameters: -// SELECT * FROM tbl WHERE id=$1 OR name=$2 -/*! -Create a prepared statement object from a query. +namespace duckdb { -Note that after calling `duckdb_prepare`, the prepared statement should always be destroyed using -`duckdb_destroy_prepare`, even if the prepare fails. +struct string_t; +struct interval_t; -If the prepare fails, `duckdb_prepare_error` can be called to obtain the reason why the prepare failed. +// efficient hash function that maximizes the avalanche effect and minimizes +// bias +// see: https://nullprogram.com/blog/2018/07/31/ -* connection: The connection object -* query: The SQL query to prepare -* out_prepared_statement: The resulting prepared statement object -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_prepare(duckdb_connection connection, const char *query, - duckdb_prepared_statement *out_prepared_statement); +inline hash_t murmurhash64(uint64_t x) { + x ^= x >> 32; + x *= 0xd6e8feb86659fd93U; + x ^= x >> 32; + x *= 0xd6e8feb86659fd93U; + x ^= x >> 32; + return x; +} -/*! -Closes the prepared statement and de-allocates all memory allocated for the statement. +inline hash_t murmurhash32(uint32_t x) { + return murmurhash64(x); +} -* prepared_statement: The prepared statement to destroy. -*/ -DUCKDB_API void duckdb_destroy_prepare(duckdb_prepared_statement *prepared_statement); +template +hash_t Hash(T value) { + return murmurhash32(value); +} -/*! -Returns the error message associated with the given prepared statement. -If the prepared statement has no error message, this returns `nullptr` instead. +//! Combine two hashes by XORing them +inline hash_t CombineHash(hash_t left, hash_t right) { + return left ^ right; +} -The error message should not be freed. It will be de-allocated when `duckdb_destroy_prepare` is called. +template <> +DUCKDB_API hash_t Hash(uint64_t val); +template <> +DUCKDB_API hash_t Hash(int64_t val); +template <> +DUCKDB_API hash_t Hash(hugeint_t val); +template <> +DUCKDB_API hash_t Hash(float val); +template <> +DUCKDB_API hash_t Hash(double val); +template <> +DUCKDB_API hash_t Hash(const char *val); +template <> +DUCKDB_API hash_t Hash(char *val); +template <> +DUCKDB_API hash_t Hash(string_t val); +template <> +DUCKDB_API hash_t Hash(interval_t val); +DUCKDB_API hash_t Hash(const char *val, size_t size); +DUCKDB_API hash_t Hash(uint8_t *val, size_t size); -* prepared_statement: The prepared statement to obtain the error from. -* returns: The error message, or `nullptr` if there is none. -*/ -DUCKDB_API const char *duckdb_prepare_error(duckdb_prepared_statement prepared_statement); +} // namespace duckdb -/*! -Returns the number of parameters that can be provided to the given prepared statement. -Returns 0 if the query was not successfully prepared. -* prepared_statement: The prepared statement to obtain the number of parameters for. -*/ -DUCKDB_API idx_t duckdb_nparams(duckdb_prepared_statement prepared_statement); +namespace duckdb { -/*! -Returns the parameter type for the parameter at the given index. +struct QualifiedColumnHashFunction { + uint64_t operator()(const QualifiedColumnName &a) const { + std::hash str_hasher; + return str_hasher(a.schema) ^ str_hasher(a.table) ^ str_hasher(a.column); + } +}; -Returns `DUCKDB_TYPE_INVALID` if the parameter index is out of range or the statement was not successfully prepared. +struct QualifiedColumnEquality { + bool operator()(const QualifiedColumnName &a, const QualifiedColumnName &b) const { + return a.schema == b.schema && a.table == b.table && a.column == b.column; + } +}; -* prepared_statement: The prepared statement. -* param_idx: The parameter index. -* returns: The parameter type -*/ -DUCKDB_API duckdb_type duckdb_param_type(duckdb_prepared_statement prepared_statement, idx_t param_idx); +using qualified_column_set_t = unordered_set; -/*! -Clear the params bind to the prepared statement. -*/ -DUCKDB_API duckdb_state duckdb_clear_bindings(duckdb_prepared_statement prepared_statement); +} // namespace duckdb -/*! -Binds a bool value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_boolean(duckdb_prepared_statement prepared_statement, idx_t param_idx, bool val); -/*! -Binds an int8_t value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_int8(duckdb_prepared_statement prepared_statement, idx_t param_idx, int8_t val); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/expression_binder.hpp +// +// +//===----------------------------------------------------------------------===// -/*! -Binds an int16_t value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_int16(duckdb_prepared_statement prepared_statement, idx_t param_idx, int16_t val); -/*! -Binds an int32_t value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_int32(duckdb_prepared_statement prepared_statement, idx_t param_idx, int32_t val); -/*! -Binds an int64_t value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_int64(duckdb_prepared_statement prepared_statement, idx_t param_idx, int64_t val); -/*! -Binds an duckdb_hugeint value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_hugeint(duckdb_prepared_statement prepared_statement, idx_t param_idx, - duckdb_hugeint val); -/*! -Binds a duckdb_decimal value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_decimal(duckdb_prepared_statement prepared_statement, idx_t param_idx, - duckdb_decimal val); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/expression/bound_expression.hpp +// +// +//===----------------------------------------------------------------------===// -/*! -Binds an uint8_t value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_uint8(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint8_t val); -/*! -Binds an uint16_t value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_uint16(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint16_t val); -/*! -Binds an uint32_t value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_uint32(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint32_t val); -/*! -Binds an uint64_t value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_uint64(duckdb_prepared_statement prepared_statement, idx_t param_idx, uint64_t val); -/*! -Binds an float value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_float(duckdb_prepared_statement prepared_statement, idx_t param_idx, float val); -/*! -Binds an double value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_double(duckdb_prepared_statement prepared_statement, idx_t param_idx, double val); -/*! -Binds a duckdb_date value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_date(duckdb_prepared_statement prepared_statement, idx_t param_idx, - duckdb_date val); -/*! -Binds a duckdb_time value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_time(duckdb_prepared_statement prepared_statement, idx_t param_idx, - duckdb_time val); +namespace duckdb { -/*! -Binds a duckdb_timestamp value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_timestamp(duckdb_prepared_statement prepared_statement, idx_t param_idx, - duckdb_timestamp val); +//! BoundExpression is an intermediate dummy class used by the binder. It is a ParsedExpression but holds an Expression. +//! It represents a successfully bound expression. It is used in the Binder to prevent re-binding of already bound parts +//! when dealing with subqueries. +class BoundExpression : public ParsedExpression { +public: + BoundExpression(unique_ptr expr); -/*! -Binds a duckdb_interval value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_interval(duckdb_prepared_statement prepared_statement, idx_t param_idx, - duckdb_interval val); + unique_ptr expr; -/*! -Binds a null-terminated varchar value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_varchar(duckdb_prepared_statement prepared_statement, idx_t param_idx, - const char *val); +public: + string ToString() const override; -/*! -Binds a varchar value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_varchar_length(duckdb_prepared_statement prepared_statement, idx_t param_idx, - const char *val, idx_t length); + bool Equals(const BaseExpression *other) const override; + hash_t Hash() const override; -/*! -Binds a blob value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_blob(duckdb_prepared_statement prepared_statement, idx_t param_idx, - const void *data, idx_t length); + unique_ptr Copy() const override; -/*! -Binds a NULL value to the prepared statement at the specified index. -*/ -DUCKDB_API duckdb_state duckdb_bind_null(duckdb_prepared_statement prepared_statement, idx_t param_idx); + void Serialize(FieldWriter &writer) const override; +}; -/*! -Executes the prepared statement with the given bound parameters, and returns a materialized query result. +} // namespace duckdb -This method can be called multiple times for each prepared statement, and the parameters can be modified -between calls to this function. -* prepared_statement: The prepared statement to execute. -* out_result: The query result. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_execute_prepared(duckdb_prepared_statement prepared_statement, - duckdb_result *out_result); -/*! -Executes the prepared statement with the given bound parameters, and returns an arrow query result. -* prepared_statement: The prepared statement to execute. -* out_result: The query result. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_execute_prepared_arrow(duckdb_prepared_statement prepared_statement, - duckdb_arrow *out_result); -//===--------------------------------------------------------------------===// -// Pending Result Interface -//===--------------------------------------------------------------------===// -/*! -Executes the prepared statement with the given bound parameters, and returns a pending result. -The pending result represents an intermediate structure for a query that is not yet fully executed. -The pending result can be used to incrementally execute a query, returning control to the client between tasks. -Note that after calling `duckdb_pending_prepared`, the pending result should always be destroyed using -`duckdb_destroy_pending`, even if this function returns DuckDBError. +namespace duckdb { -* prepared_statement: The prepared statement to execute. -* out_result: The pending query result. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_pending_prepared(duckdb_prepared_statement prepared_statement, - duckdb_pending_result *out_result); +class Binder; +class ClientContext; +class QueryNode; -/*! -Closes the pending result and de-allocates all memory allocated for the result. +class ScalarFunctionCatalogEntry; +class AggregateFunctionCatalogEntry; +class ScalarMacroCatalogEntry; +class CatalogEntry; +class SimpleFunction; -* pending_result: The pending result to destroy. -*/ -DUCKDB_API void duckdb_destroy_pending(duckdb_pending_result *pending_result); +struct DummyBinding; -/*! -Returns the error message contained within the pending result. +struct BoundColumnReferenceInfo { + string name; + idx_t query_location; +}; -The result of this function must not be freed. It will be cleaned up when `duckdb_destroy_pending` is called. +struct BindResult { + BindResult() { + } + explicit BindResult(string error) : error(error) { + } + explicit BindResult(unique_ptr expr) : expression(std::move(expr)) { + } -* result: The pending result to fetch the error from. -* returns: The error of the pending result. -*/ -DUCKDB_API const char *duckdb_pending_error(duckdb_pending_result pending_result); + bool HasError() { + return !error.empty(); + } -/*! -Executes a single task within the query, returning whether or not the query is ready. + unique_ptr expression; + string error; +}; -If this returns DUCKDB_PENDING_RESULT_READY, the duckdb_execute_pending function can be called to obtain the result. -If this returns DUCKDB_PENDING_RESULT_NOT_READY, the duckdb_pending_execute_task function should be called again. -If this returns DUCKDB_PENDING_ERROR, an error occurred during execution. +class ExpressionBinder { +public: + ExpressionBinder(Binder &binder, ClientContext &context, bool replace_binder = false); + virtual ~ExpressionBinder(); -The error message can be obtained by calling duckdb_pending_error on the pending_result. + //! The target type that should result from the binder. If the result is not of this type, a cast to this type will + //! be added. Defaults to INVALID. + LogicalType target_type; -* pending_result: The pending result to execute a task within.. -* returns: The state of the pending result after the execution. -*/ -DUCKDB_API duckdb_pending_state duckdb_pending_execute_task(duckdb_pending_result pending_result); + DummyBinding *macro_binding; + vector *lambda_bindings = nullptr; -/*! -Fully execute a pending query result, returning the final query result. +public: + unique_ptr Bind(unique_ptr &expr, LogicalType *result_type = nullptr, + bool root_expression = true); -If duckdb_pending_execute_task has been called until DUCKDB_PENDING_RESULT_READY was returned, this will return fast. -Otherwise, all remaining tasks must be executed first. + //! Returns whether or not any columns have been bound by the expression binder + bool HasBoundColumns() { + return !bound_columns.empty(); + } + const vector &GetBoundColumns() { + return bound_columns; + } -* pending_result: The pending result to execute. -* out_result: The result object. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_execute_pending(duckdb_pending_result pending_result, duckdb_result *out_result); + string Bind(unique_ptr *expr, idx_t depth, bool root_expression = false); -//===--------------------------------------------------------------------===// -// Value Interface -//===--------------------------------------------------------------------===// -/*! -Destroys the value and de-allocates all memory allocated for that type. + unique_ptr CreateStructExtract(unique_ptr base, string field_name); + unique_ptr CreateStructPack(ColumnRefExpression &colref); + BindResult BindQualifiedColumnName(ColumnRefExpression &colref, const string &table_name); -* value: The value to destroy. -*/ -DUCKDB_API void duckdb_destroy_value(duckdb_value *value); + unique_ptr QualifyColumnName(const string &column_name, string &error_message); + unique_ptr QualifyColumnName(ColumnRefExpression &colref, string &error_message); -/*! -Creates a value from a null-terminated string + // Bind table names to ColumnRefExpressions + void QualifyColumnNames(unique_ptr &expr); + static void QualifyColumnNames(Binder &binder, unique_ptr &expr); -* value: The null-terminated string -* returns: The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_varchar(const char *text); + static unique_ptr PushCollation(ClientContext &context, unique_ptr source, + const string &collation, bool equality_only = false); + static void TestCollation(ClientContext &context, const string &collation); -/*! -Creates a value from a string + bool BindCorrelatedColumns(unique_ptr &expr); -* value: The text -* length: The length of the text -* returns: The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_varchar_length(const char *text, idx_t length); + void BindChild(unique_ptr &expr, idx_t depth, string &error); + static void ExtractCorrelatedExpressions(Binder &binder, Expression &expr); -/*! -Creates a value from an int64 + static bool ContainsNullType(const LogicalType &type); + static LogicalType ExchangeNullType(const LogicalType &type); + static bool ContainsType(const LogicalType &type, LogicalTypeId target); + static LogicalType ExchangeType(const LogicalType &type, LogicalTypeId target, LogicalType new_type); -* value: The bigint value -* returns: The value. This must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_create_int64(int64_t val); + //! Bind the given expresion. Unlike Bind(), this does *not* mute the given ParsedExpression. + //! Exposed to be used from sub-binders that aren't subclasses of ExpressionBinder. + virtual BindResult BindExpression(unique_ptr *expr_ptr, idx_t depth, + bool root_expression = false); -/*! -Obtains a string representation of the given value. -The result must be destroyed with `duckdb_free`. + void ReplaceMacroParametersRecursive(unique_ptr &expr); -* value: The value -* returns: The string value. This must be destroyed with `duckdb_free`. -*/ -DUCKDB_API char *duckdb_get_varchar(duckdb_value value); +protected: + BindResult BindExpression(BetweenExpression &expr, idx_t depth); + BindResult BindExpression(CaseExpression &expr, idx_t depth); + BindResult BindExpression(CollateExpression &expr, idx_t depth); + BindResult BindExpression(CastExpression &expr, idx_t depth); + BindResult BindExpression(ColumnRefExpression &expr, idx_t depth); + BindResult BindExpression(ComparisonExpression &expr, idx_t depth); + BindResult BindExpression(ConjunctionExpression &expr, idx_t depth); + BindResult BindExpression(ConstantExpression &expr, idx_t depth); + BindResult BindExpression(FunctionExpression &expr, idx_t depth, unique_ptr *expr_ptr); + BindResult BindExpression(LambdaExpression &expr, idx_t depth, const bool is_lambda, + const LogicalType &list_child_type); + BindResult BindExpression(OperatorExpression &expr, idx_t depth); + BindResult BindExpression(ParameterExpression &expr, idx_t depth); + BindResult BindExpression(PositionalReferenceExpression &ref, idx_t depth); + BindResult BindExpression(SubqueryExpression &expr, idx_t depth); -/*! -Obtains an int64 of the given value. + void TransformCapturedLambdaColumn(unique_ptr &original, unique_ptr &replacement, + vector> &captures, LogicalType &list_child_type); + void CaptureLambdaColumns(vector> &captures, LogicalType &list_child_type, + unique_ptr &expr); -* value: The value -* returns: The int64 value, or 0 if no conversion is possible -*/ -DUCKDB_API int64_t duckdb_get_int64(duckdb_value value); +protected: + virtual BindResult BindGroupingFunction(OperatorExpression &op, idx_t depth); + virtual BindResult BindFunction(FunctionExpression &expr, ScalarFunctionCatalogEntry *function, idx_t depth); + virtual BindResult BindLambdaFunction(FunctionExpression &expr, ScalarFunctionCatalogEntry *function, idx_t depth); + virtual BindResult BindAggregate(FunctionExpression &expr, AggregateFunctionCatalogEntry *function, idx_t depth); + virtual BindResult BindUnnest(FunctionExpression &expr, idx_t depth); + virtual BindResult BindMacro(FunctionExpression &expr, ScalarMacroCatalogEntry *macro, idx_t depth, + unique_ptr *expr_ptr); -//===--------------------------------------------------------------------===// -// Logical Type Interface -//===--------------------------------------------------------------------===// + virtual string UnsupportedAggregateMessage(); + virtual string UnsupportedUnnestMessage(); -/*! -Creates a `duckdb_logical_type` from a standard primitive type. -The resulting type should be destroyed with `duckdb_destroy_logical_type`. + Binder &binder; + ClientContext &context; + ExpressionBinder *stored_binder; + vector bound_columns; +}; -This should not be used with `DUCKDB_TYPE_DECIMAL`. +} // namespace duckdb -* type: The primitive type to create. -* returns: The logical type. -*/ -DUCKDB_API duckdb_logical_type duckdb_create_logical_type(duckdb_type type); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/table_binding.hpp +// +// +//===----------------------------------------------------------------------===// -/*! -Creates a list type from its child type. -The resulting type should be destroyed with `duckdb_destroy_logical_type`. -* type: The child type of list type to create. -* returns: The logical type. -*/ -DUCKDB_API duckdb_logical_type duckdb_create_list_type(duckdb_logical_type type); -/*! -Creates a map type from its key type and value type. -The resulting type should be destroyed with `duckdb_destroy_logical_type`. -* type: The key type and value type of map type to create. -* returns: The logical type. -*/ -DUCKDB_API duckdb_logical_type duckdb_create_map_type(duckdb_logical_type key_type, duckdb_logical_type value_type); -/*! -Creates a `duckdb_logical_type` of type decimal with the specified width and scale -The resulting type should be destroyed with `duckdb_destroy_logical_type`. -* width: The width of the decimal type -* scale: The scale of the decimal type -* returns: The logical type. -*/ -DUCKDB_API duckdb_logical_type duckdb_create_decimal_type(uint8_t width, uint8_t scale); -/*! -Retrieves the type class of a `duckdb_logical_type`. -* type: The logical type object -* returns: The type id -*/ -DUCKDB_API duckdb_type duckdb_get_type_id(duckdb_logical_type type); -/*! -Retrieves the width of a decimal type. -* type: The logical type object -* returns: The width of the decimal type -*/ -DUCKDB_API uint8_t duckdb_decimal_width(duckdb_logical_type type); +namespace duckdb { +class BindContext; +class BoundQueryNode; +class ColumnRefExpression; +class SubqueryRef; +class LogicalGet; +class TableCatalogEntry; +class TableFunctionCatalogEntry; +class BoundTableFunction; +class StandardEntry; +struct ColumnBinding; -/*! -Retrieves the scale of a decimal type. +enum class BindingType { BASE, TABLE, DUMMY, CATALOG_ENTRY }; -* type: The logical type object -* returns: The scale of the decimal type -*/ -DUCKDB_API uint8_t duckdb_decimal_scale(duckdb_logical_type type); +//! A Binding represents a binding to a table, table-producing function or subquery with a specified table index. +struct Binding { + Binding(BindingType binding_type, const string &alias, vector types, vector names, + idx_t index); + virtual ~Binding() = default; -/*! -Retrieves the internal storage type of a decimal type. + //! The type of Binding + BindingType binding_type; + //! The alias of the binding + string alias; + //! The table index of the binding + idx_t index; + //! The types of the bound columns + vector types; + //! Column names of the subquery + vector names; + //! Name -> index for the names + case_insensitive_map_t name_map; -* type: The logical type object -* returns: The internal type of the decimal type -*/ -DUCKDB_API duckdb_type duckdb_decimal_internal_type(duckdb_logical_type type); +public: + bool TryGetBindingIndex(const string &column_name, column_t &column_index); + column_t GetBindingIndex(const string &column_name); + bool HasMatchingBinding(const string &column_name); + virtual string ColumnNotFoundError(const string &column_name) const; + virtual BindResult Bind(ColumnRefExpression &colref, idx_t depth); + virtual StandardEntry *GetStandardEntry(); +}; -/*! -Retrieves the internal storage type of an enum type. +struct EntryBinding : public Binding { +public: + EntryBinding(const string &alias, vector types, vector names, idx_t index, + StandardEntry &entry); + StandardEntry &entry; -* type: The logical type object -* returns: The internal type of the enum type -*/ -DUCKDB_API duckdb_type duckdb_enum_internal_type(duckdb_logical_type type); +public: + StandardEntry *GetStandardEntry() override; +}; -/*! -Retrieves the dictionary size of the enum type +//! TableBinding is exactly like the Binding, except it keeps track of which columns were bound in the linked LogicalGet +//! node for projection pushdown purposes. +struct TableBinding : public Binding { + TableBinding(const string &alias, vector types, vector names, + vector &bound_column_ids, StandardEntry *entry, idx_t index, bool add_row_id = false); -* type: The logical type object -* returns: The dictionary size of the enum type -*/ -DUCKDB_API uint32_t duckdb_enum_dictionary_size(duckdb_logical_type type); + //! A reference to the set of bound column ids + vector &bound_column_ids; + //! The underlying catalog entry (if any) + StandardEntry *entry; -/*! -Retrieves the dictionary value at the specified position from the enum. +public: + unique_ptr ExpandGeneratedColumn(const string &column_name); + BindResult Bind(ColumnRefExpression &colref, idx_t depth) override; + StandardEntry *GetStandardEntry() override; + string ColumnNotFoundError(const string &column_name) const override; + // These are columns that are present in the name_map, appearing in the order that they're bound + const vector &GetBoundColumnIds() const; -The result must be freed with `duckdb_free` +protected: + ColumnBinding GetColumnBinding(column_t column_index); +}; -* type: The logical type object -* index: The index in the dictionary -* returns: The string value of the enum type. Must be freed with `duckdb_free`. -*/ -DUCKDB_API char *duckdb_enum_dictionary_value(duckdb_logical_type type, idx_t index); +//! DummyBinding is like the Binding, except the alias and index are set by default. Used for binding lambdas and macro +//! parameters. +struct DummyBinding : public Binding { + // NOTE: changing this string conflicts with the storage version + static constexpr const char *DUMMY_NAME = "0_macro_parameters"; -/*! -Retrieves the child type of the given list type. +public: + DummyBinding(vector types_p, vector names_p, string dummy_name_p); -The result must be freed with `duckdb_destroy_logical_type` + //! Arguments + vector> *arguments; + //! The name of the dummy binding + string dummy_name; -* type: The logical type object -* returns: The child type of the list type. Must be destroyed with `duckdb_destroy_logical_type`. -*/ -DUCKDB_API duckdb_logical_type duckdb_list_type_child_type(duckdb_logical_type type); +public: + BindResult Bind(ColumnRefExpression &colref, idx_t depth) override; + BindResult Bind(ColumnRefExpression &colref, idx_t lambda_index, idx_t depth); -/*! -Retrieves the key type of the given map type. + //! Given the parameter colref, returns a copy of the argument that was supplied for this parameter + unique_ptr ParamToArg(ColumnRefExpression &colref); +}; -The result must be freed with `duckdb_destroy_logical_type` +} // namespace duckdb -* type: The logical type object -* returns: The key type of the map type. Must be destroyed with `duckdb_destroy_logical_type`. -*/ -DUCKDB_API duckdb_logical_type duckdb_map_type_key_type(duckdb_logical_type type); -/*! -Retrieves the value type of the given map type. +namespace duckdb { +class Binder; +class LogicalGet; +class BoundQueryNode; + +class StarExpression; -The result must be freed with `duckdb_destroy_logical_type` +class TableCatalogEntry; +class TableFunctionCatalogEntry; -* type: The logical type object -* returns: The value type of the map type. Must be destroyed with `duckdb_destroy_logical_type`. -*/ -DUCKDB_API duckdb_logical_type duckdb_map_type_value_type(duckdb_logical_type type); +struct UsingColumnSet { + string primary_binding; + unordered_set bindings; +}; -/*! -Returns the number of children of a struct type. +//! The BindContext object keeps track of all the tables and columns that are +//! encountered during the binding process. +class BindContext { +public: + //! Keep track of recursive CTE references + case_insensitive_map_t> cte_references; -* type: The logical type object -* returns: The number of children of a struct type. -*/ -DUCKDB_API idx_t duckdb_struct_type_child_count(duckdb_logical_type type); +public: + //! Given a column name, find the matching table it belongs to. Throws an + //! exception if no table has a column of the given name. + string GetMatchingBinding(const string &column_name); + //! Like GetMatchingBinding, but instead of throwing an error if multiple tables have the same binding it will + //! return a list of all the matching ones + unordered_set GetMatchingBindings(const string &column_name); + //! Like GetMatchingBindings, but returns the top 3 most similar bindings (in levenshtein distance) instead of the + //! matching ones + vector GetSimilarBindings(const string &column_name); -/*! -Retrieves the name of the struct child. + Binding *GetCTEBinding(const string &ctename); + //! Binds a column expression to the base table. Returns the bound expression + //! or throws an exception if the column could not be bound. + BindResult BindColumn(ColumnRefExpression &colref, idx_t depth); + string BindColumn(PositionalReferenceExpression &ref, string &table_name, string &column_name); + BindResult BindColumn(PositionalReferenceExpression &ref, idx_t depth); -The result must be freed with `duckdb_free` + unique_ptr ExpandGeneratedColumn(const string &table_name, const string &column_name); -* type: The logical type object -* index: The child index -* returns: The name of the struct type. Must be freed with `duckdb_free`. -*/ -DUCKDB_API char *duckdb_struct_type_child_name(duckdb_logical_type type, idx_t index); + unique_ptr CreateColumnReference(const string &table_name, const string &column_name); + unique_ptr CreateColumnReference(const string &schema_name, const string &table_name, + const string &column_name); + unique_ptr CreateColumnReference(const string &catalog_name, const string &schema_name, + const string &table_name, const string &column_name); -/*! -Retrieves the child type of the given struct type at the specified index. + //! Generate column expressions for all columns that are present in the + //! referenced tables. This is used to resolve the * expression in a + //! selection list. + void GenerateAllColumnExpressions(StarExpression &expr, vector> &new_select_list); + //! Check if the given (binding, column_name) is in the exclusion/replacement lists. + //! Returns true if it is in one of these lists, and should therefore be skipped. + bool CheckExclusionList(StarExpression &expr, Binding *binding, const string &column_name, + vector> &new_select_list, + case_insensitive_set_t &excluded_columns); -The result must be freed with `duckdb_destroy_logical_type` + const vector> &GetBindingsList() { + return bindings_list; + } -* type: The logical type object -* index: The child index -* returns: The child type of the struct type. Must be destroyed with `duckdb_destroy_logical_type`. -*/ -DUCKDB_API duckdb_logical_type duckdb_struct_type_child_type(duckdb_logical_type type, idx_t index); + //! Adds a base table with the given alias to the BindContext. + void AddBaseTable(idx_t index, const string &alias, const vector &names, const vector &types, + vector &bound_column_ids, StandardEntry *entry, bool add_row_id = true); + //! Adds a call to a table function with the given alias to the BindContext. + void AddTableFunction(idx_t index, const string &alias, const vector &names, + const vector &types, vector &bound_column_ids, StandardEntry *entry); + //! Adds a table view with a given alias to the BindContext. + void AddView(idx_t index, const string &alias, SubqueryRef &ref, BoundQueryNode &subquery, ViewCatalogEntry *view); + //! Adds a subquery with a given alias to the BindContext. + void AddSubquery(idx_t index, const string &alias, SubqueryRef &ref, BoundQueryNode &subquery); + //! Adds a subquery with a given alias to the BindContext. + void AddSubquery(idx_t index, const string &alias, TableFunctionRef &ref, BoundQueryNode &subquery); + //! Adds a binding to a catalog entry with a given alias to the BindContext. + void AddEntryBinding(idx_t index, const string &alias, const vector &names, + const vector &types, StandardEntry *entry); + //! Adds a base table with the given alias to the BindContext. + void AddGenericBinding(idx_t index, const string &alias, const vector &names, + const vector &types); -/*! -Destroys the logical type and de-allocates all memory allocated for that type. + //! Adds a base table with the given alias to the CTE BindContext. + //! We need this to correctly bind recursive CTEs with multiple references. + void AddCTEBinding(idx_t index, const string &alias, const vector &names, const vector &types); -* type: The logical type to destroy. -*/ -DUCKDB_API void duckdb_destroy_logical_type(duckdb_logical_type *type); + //! Add an implicit join condition (e.g. USING (x)) + void AddUsingBinding(const string &column_name, UsingColumnSet *set); -//===--------------------------------------------------------------------===// -// Data Chunk Interface -//===--------------------------------------------------------------------===// -/*! -Creates an empty DataChunk with the specified set of types. + void AddUsingBindingSet(unique_ptr set); -* types: An array of types of the data chunk. -* column_count: The number of columns. -* returns: The data chunk. -*/ -DUCKDB_API duckdb_data_chunk duckdb_create_data_chunk(duckdb_logical_type *types, idx_t column_count); + //! Returns any using column set for the given column name, or nullptr if there is none. On conflict (multiple using + //! column sets with the same name) throw an exception. + UsingColumnSet *GetUsingBinding(const string &column_name); + //! Returns any using column set for the given column name, or nullptr if there is none + UsingColumnSet *GetUsingBinding(const string &column_name, const string &binding_name); + //! Erase a using binding from the set of using bindings + void RemoveUsingBinding(const string &column_name, UsingColumnSet *set); + //! Finds the using bindings for a given column. Returns true if any exists, false otherwise. + bool FindUsingBinding(const string &column_name, unordered_set **using_columns); + //! Transfer a using binding from one bind context to this bind context + void TransferUsingBinding(BindContext ¤t_context, UsingColumnSet *current_set, UsingColumnSet *new_set, + const string &binding, const string &using_column); -/*! -Destroys the data chunk and de-allocates all memory allocated for that chunk. + //! Fetch the actual column name from the given binding, or throws if none exists + //! This can be different from "column_name" because of case insensitivity + //! (e.g. "column_name" might return "COLUMN_NAME") + string GetActualColumnName(const string &binding, const string &column_name); -* chunk: The data chunk to destroy. -*/ -DUCKDB_API void duckdb_destroy_data_chunk(duckdb_data_chunk *chunk); + case_insensitive_map_t> GetCTEBindings() { + return cte_bindings; + } + void SetCTEBindings(case_insensitive_map_t> bindings) { + cte_bindings = bindings; + } -/*! -Resets a data chunk, clearing the validity masks and setting the cardinality of the data chunk to 0. + //! Alias a set of column names for the specified table, using the original names if there are not enough aliases + //! specified. + static vector AliasColumnNames(const string &table_name, const vector &names, + const vector &column_aliases); -* chunk: The data chunk to reset. -*/ -DUCKDB_API void duckdb_data_chunk_reset(duckdb_data_chunk chunk); + //! Add all the bindings from a BindContext to this BindContext. The other BindContext is destroyed in the process. + void AddContext(BindContext other); -/*! -Retrieves the number of columns in a data chunk. + //! Gets a binding of the specified name. Returns a nullptr and sets the out_error if the binding could not be + //! found. + Binding *GetBinding(const string &name, string &out_error); -* chunk: The data chunk to get the data from -* returns: The number of columns in the data chunk -*/ -DUCKDB_API idx_t duckdb_data_chunk_get_column_count(duckdb_data_chunk chunk); +private: + void AddBinding(const string &alias, unique_ptr binding); -/*! -Retrieves the vector at the specified column index in the data chunk. +private: + //! The set of bindings + case_insensitive_map_t> bindings; + //! The list of bindings in insertion order + vector> bindings_list; + //! The set of columns used in USING join conditions + case_insensitive_map_t> using_columns; + //! Using column sets + vector> using_column_sets; -The pointer to the vector is valid for as long as the chunk is alive. -It does NOT need to be destroyed. + //! The set of CTE bindings + case_insensitive_map_t> cte_bindings; +}; +} // namespace duckdb -* chunk: The data chunk to get the data from -* returns: The vector -*/ -DUCKDB_API duckdb_vector duckdb_data_chunk_get_vector(duckdb_data_chunk chunk, idx_t col_idx); -/*! -Retrieves the current number of tuples in a data chunk. -* chunk: The data chunk to get the data from -* returns: The number of tuples in the data chunk -*/ -DUCKDB_API idx_t duckdb_data_chunk_get_size(duckdb_data_chunk chunk); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/planner/expression/bound_columnref_expression.hpp +// +// +//===----------------------------------------------------------------------===// -/*! -Sets the current number of tuples in a data chunk. -* chunk: The data chunk to set the size in -* size: The number of tuples in the data chunk -*/ -DUCKDB_API void duckdb_data_chunk_set_size(duckdb_data_chunk chunk, idx_t size); -//===--------------------------------------------------------------------===// -// Vector Interface -//===--------------------------------------------------------------------===// -/*! -Retrieves the column type of the specified vector. -The result must be destroyed with `duckdb_destroy_logical_type`. -* vector: The vector get the data from -* returns: The type of the vector -*/ -DUCKDB_API duckdb_logical_type duckdb_vector_get_column_type(duckdb_vector vector); -/*! -Retrieves the data pointer of the vector. +namespace duckdb { -The data pointer can be used to read or write values from the vector. -How to read or write values depends on the type of the vector. +class FieldReader; +class FieldWriter; -* vector: The vector to get the data from -* returns: The data pointer -*/ -DUCKDB_API void *duckdb_vector_get_data(duckdb_vector vector); +//! A BoundColumnRef expression represents a ColumnRef expression that was bound to an actual table and column index. It +//! is not yet executable, however. The ColumnBindingResolver transforms the BoundColumnRefExpressions into +//! BoundExpressions, which refer to indexes into the physical chunks that pass through the executor. +class BoundColumnRefExpression : public Expression { +public: + BoundColumnRefExpression(LogicalType type, ColumnBinding binding, idx_t depth = 0); + BoundColumnRefExpression(string alias, LogicalType type, ColumnBinding binding, idx_t depth = 0); -/*! -Retrieves the validity mask pointer of the specified vector. + //! Column index set by the binder, used to generate the final BoundExpression + ColumnBinding binding; + //! The subquery depth (i.e. depth 0 = current query, depth 1 = parent query, depth 2 = parent of parent, etc...). + //! This is only non-zero for correlated expressions inside subqueries. + idx_t depth; -If all values are valid, this function MIGHT return NULL! +public: + bool IsScalar() const override { + return false; + } + bool IsFoldable() const override { + return false; + } -The validity mask is a bitset that signifies null-ness within the data chunk. -It is a series of uint64_t values, where each uint64_t value contains validity for 64 tuples. -The bit is set to 1 if the value is valid (i.e. not NULL) or 0 if the value is invalid (i.e. NULL). + string ToString() const override; -Validity of a specific value can be obtained like this: + bool Equals(const BaseExpression *other) const override; + hash_t Hash() const override; -idx_t entry_idx = row_idx / 64; -idx_t idx_in_entry = row_idx % 64; -bool is_valid = validity_mask[entry_idx] & (1 << idx_in_entry); + unique_ptr Copy() override; + + void Serialize(FieldWriter &writer) const override; + static unique_ptr Deserialize(ExpressionDeserializationState &state, FieldReader &reader); +}; +} // namespace duckdb -Alternatively, the (slower) duckdb_validity_row_is_valid function can be used. -* vector: The vector to get the data from -* returns: The pointer to the validity mask, or NULL if no validity mask is present -*/ -DUCKDB_API uint64_t *duckdb_vector_get_validity(duckdb_vector vector); -/*! -Ensures the validity mask is writable by allocating it. +namespace duckdb { +class BoundResultModifier; +class BoundSelectNode; +class ClientContext; +class ExpressionBinder; +class LimitModifier; +class OrderBinder; +class TableCatalogEntry; +class ViewCatalogEntry; +class TableMacroCatalogEntry; +class UpdateSetInfo; +class LogicalProjection; -After this function is called, `duckdb_vector_get_validity` will ALWAYS return non-NULL. -This allows null values to be written to the vector, regardless of whether a validity mask was present before. +class ColumnList; +class ExternalDependency; +class TableFunction; -* vector: The vector to alter -*/ -DUCKDB_API void duckdb_vector_ensure_validity_writable(duckdb_vector vector); +struct CreateInfo; +struct BoundCreateTableInfo; +struct BoundCreateFunctionInfo; +struct CommonTableExpressionInfo; +struct BoundParameterMap; -/*! -Assigns a string element in the vector at the specified location. +enum class BindingMode : uint8_t { STANDARD_BINDING, EXTRACT_NAMES }; -* vector: The vector to alter -* index: The row position in the vector to assign the string to -* str: The null-terminated string -*/ -DUCKDB_API void duckdb_vector_assign_string_element(duckdb_vector vector, idx_t index, const char *str); +struct CorrelatedColumnInfo { + ColumnBinding binding; + LogicalType type; + string name; + idx_t depth; -/*! -Assigns a string element in the vector at the specified location. + CorrelatedColumnInfo(ColumnBinding binding, LogicalType type_p, string name_p, idx_t depth) + : binding(binding), type(std::move(type_p)), name(std::move(name_p)), depth(depth) { + } + explicit CorrelatedColumnInfo(BoundColumnRefExpression &expr) + : CorrelatedColumnInfo(expr.binding, expr.return_type, expr.GetName(), expr.depth) { + } -* vector: The vector to alter -* index: The row position in the vector to assign the string to -* str: The string -* str_len: The length of the string (in bytes) -*/ -DUCKDB_API void duckdb_vector_assign_string_element_len(duckdb_vector vector, idx_t index, const char *str, - idx_t str_len); + bool operator==(const CorrelatedColumnInfo &rhs) const { + return binding == rhs.binding; + } +}; +//! Bind the parsed query tree to the actual columns present in the catalog. /*! -Retrieves the child vector of a list vector. + The binder is responsible for binding tables and columns to actual physical + tables and columns in the catalog. In the process, it also resolves types of + all expressions. +*/ +class Binder : public std::enable_shared_from_this { + friend class ExpressionBinder; + friend class SelectBinder; + friend class RecursiveSubqueryPlanner; -The resulting vector is valid as long as the parent vector is valid. +public: + DUCKDB_API static shared_ptr CreateBinder(ClientContext &context, Binder *parent = nullptr, + bool inherit_ctes = true); -* vector: The vector -* returns: The child vector -*/ -DUCKDB_API duckdb_vector duckdb_list_vector_get_child(duckdb_vector vector); + //! The client context + ClientContext &context; + //! A mapping of names to common table expressions + case_insensitive_map_t CTE_bindings; // NOLINT + //! The CTEs that have already been bound + unordered_set bound_ctes; + //! The bind context + BindContext bind_context; + //! The set of correlated columns bound by this binder (FIXME: this should probably be an unordered_set and not a + //! vector) + vector correlated_columns; + //! The set of parameter expressions bound by this binder + BoundParameterMap *parameters; + //! Statement properties + StatementProperties properties; + //! The alias for the currently processing subquery, if it exists + string alias; + //! Macro parameter bindings (if any) + DummyBinding *macro_binding = nullptr; + //! The intermediate lambda bindings to bind nested lambdas (if any) + vector *lambda_bindings = nullptr; -/*! -Returns the size of the child vector of the list +public: + DUCKDB_API BoundStatement Bind(SQLStatement &statement); + DUCKDB_API BoundStatement Bind(QueryNode &node); -* vector: The vector -* returns: The size of the child list -*/ -DUCKDB_API idx_t duckdb_list_vector_get_size(duckdb_vector vector); + unique_ptr BindCreateTableInfo(unique_ptr info); + unique_ptr BindCreateTableInfo(unique_ptr info, SchemaCatalogEntry *schema); + void BindCreateViewInfo(CreateViewInfo &base); + SchemaCatalogEntry *BindSchema(CreateInfo &info); + SchemaCatalogEntry *BindCreateFunctionInfo(CreateInfo &info); -/*! -Retrieves the child vector of a struct vector. + //! Check usage, and cast named parameters to their types + static void BindNamedParameters(named_parameter_type_map_t &types, named_parameter_map_t &values, + QueryErrorContext &error_context, string &func_name); -The resulting vector is valid as long as the parent vector is valid. + unique_ptr Bind(TableRef &ref); + unique_ptr CreatePlan(BoundTableRef &ref); -* vector: The vector -* index: The child index -* returns: The child vector -*/ -DUCKDB_API duckdb_vector duckdb_struct_vector_get_child(duckdb_vector vector, idx_t index); + //! Generates an unused index for a table + idx_t GenerateTableIndex(); -//===--------------------------------------------------------------------===// -// Validity Mask Functions -//===--------------------------------------------------------------------===// -/*! -Returns whether or not a row is valid (i.e. not NULL) in the given validity mask. + //! Add a common table expression to the binder + void AddCTE(const string &name, CommonTableExpressionInfo *cte); + //! Find a common table expression by name; returns nullptr if none exists + CommonTableExpressionInfo *FindCTE(const string &name, bool skip = false); -* validity: The validity mask, as obtained through `duckdb_data_chunk_get_validity` -* row: The row index -* returns: true if the row is valid, false otherwise -*/ -DUCKDB_API bool duckdb_validity_row_is_valid(uint64_t *validity, idx_t row); + bool CTEIsAlreadyBound(CommonTableExpressionInfo *cte); -/*! -In a validity mask, sets a specific row to either valid or invalid. + //! Add the view to the set of currently bound views - used for detecting recursive view definitions + void AddBoundView(ViewCatalogEntry *view); -Note that `duckdb_data_chunk_ensure_validity_writable` should be called before calling `duckdb_data_chunk_get_validity`, -to ensure that there is a validity mask to write to. + void PushExpressionBinder(ExpressionBinder *binder); + void PopExpressionBinder(); + void SetActiveBinder(ExpressionBinder *binder); + ExpressionBinder *GetActiveBinder(); + bool HasActiveBinder(); -* validity: The validity mask, as obtained through `duckdb_data_chunk_get_validity`. -* row: The row index -* valid: Whether or not to set the row to valid, or invalid -*/ -DUCKDB_API void duckdb_validity_set_row_validity(uint64_t *validity, idx_t row, bool valid); + vector &GetActiveBinders(); -/*! -In a validity mask, sets a specific row to invalid. + void MergeCorrelatedColumns(vector &other); + //! Add a correlated column to this binder (if it does not exist) + void AddCorrelatedColumn(const CorrelatedColumnInfo &info); -Equivalent to `duckdb_validity_set_row_validity` with valid set to false. + string FormatError(ParsedExpression &expr_context, const string &message); + string FormatError(TableRef &ref_context, const string &message); -* validity: The validity mask -* row: The row index -*/ -DUCKDB_API void duckdb_validity_set_row_invalid(uint64_t *validity, idx_t row); + string FormatErrorRecursive(idx_t query_location, const string &message, vector &values); + template + string FormatErrorRecursive(idx_t query_location, const string &msg, vector &values, T param, + ARGS... params) { + values.push_back(ExceptionFormatValue::CreateFormatValue(param)); + return FormatErrorRecursive(query_location, msg, values, params...); + } -/*! -In a validity mask, sets a specific row to valid. + template + string FormatError(idx_t query_location, const string &msg, ARGS... params) { + vector values; + return FormatErrorRecursive(query_location, msg, values, params...); + } -Equivalent to `duckdb_validity_set_row_validity` with valid set to true. + unique_ptr BindUpdateSet(LogicalOperator *op, unique_ptr root, + UpdateSetInfo &set_info, TableCatalogEntry *table, + vector &columns); + void BindDoUpdateSetExpressions(const string &table_alias, LogicalInsert *insert, UpdateSetInfo &set_info, + TableCatalogEntry &table); + void BindOnConflictClause(LogicalInsert &insert, TableCatalogEntry &table, InsertStatement &stmt); -* validity: The validity mask -* row: The row index -*/ -DUCKDB_API void duckdb_validity_set_row_valid(uint64_t *validity, idx_t row); + static void BindSchemaOrCatalog(ClientContext &context, string &catalog, string &schema); + static void BindLogicalType(ClientContext &context, LogicalType &type, Catalog *catalog = nullptr, + const string &schema = INVALID_SCHEMA); -//===--------------------------------------------------------------------===// -// Table Functions -//===--------------------------------------------------------------------===// -typedef void *duckdb_table_function; -typedef void *duckdb_bind_info; -typedef void *duckdb_init_info; -typedef void *duckdb_function_info; + bool HasMatchingBinding(const string &table_name, const string &column_name, string &error_message); + bool HasMatchingBinding(const string &schema_name, const string &table_name, const string &column_name, + string &error_message); + bool HasMatchingBinding(const string &catalog_name, const string &schema_name, const string &table_name, + const string &column_name, string &error_message); -typedef void (*duckdb_table_function_bind_t)(duckdb_bind_info info); -typedef void (*duckdb_table_function_init_t)(duckdb_init_info info); -typedef void (*duckdb_table_function_t)(duckdb_function_info info, duckdb_data_chunk output); -typedef void (*duckdb_delete_callback_t)(void *data); + void SetBindingMode(BindingMode mode); + BindingMode GetBindingMode(); + void AddTableName(string table_name); + const unordered_set &GetTableNames(); -/*! -Creates a new empty table function. + void SetCanContainNulls(bool can_contain_nulls); -The return value should be destroyed with `duckdb_destroy_table_function`. +private: + //! The parent binder (if any) + shared_ptr parent; + //! The vector of active binders + vector active_binders; + //! The count of bound_tables + idx_t bound_tables; + //! Whether or not the binder has any unplanned subqueries that still need to be planned + bool has_unplanned_subqueries = false; + //! Whether or not subqueries should be planned already + bool plan_subquery = true; + //! Whether CTEs should reference the parent binder (if it exists) + bool inherit_ctes = true; + //! Whether or not the binder can contain NULLs as the root of expressions + bool can_contain_nulls = false; + //! The root statement of the query that is currently being parsed + SQLStatement *root_statement = nullptr; + //! Binding mode + BindingMode mode = BindingMode::STANDARD_BINDING; + //! Table names extracted for BindingMode::EXTRACT_NAMES + unordered_set table_names; + //! The set of bound views + unordered_set bound_views; -* returns: The table function object. -*/ -DUCKDB_API duckdb_table_function duckdb_create_table_function(); +private: + //! Bind the expressions of generated columns to check for errors + void BindGeneratedColumns(BoundCreateTableInfo &info); + //! Bind the default values of the columns of a table + void BindDefaultValues(const ColumnList &columns, vector> &bound_defaults); + //! Bind a limit value (LIMIT or OFFSET) + unique_ptr BindDelimiter(ClientContext &context, OrderBinder &order_binder, + unique_ptr delimiter, const LogicalType &type, + Value &delimiter_value); -/*! -Destroys the given table function object. + //! Move correlated expressions from the child binder to this binder + void MoveCorrelatedExpressions(Binder &other); -* table_function: The table function to destroy -*/ -DUCKDB_API void duckdb_destroy_table_function(duckdb_table_function *table_function); + BoundStatement Bind(SelectStatement &stmt); + BoundStatement Bind(InsertStatement &stmt); + BoundStatement Bind(CopyStatement &stmt); + BoundStatement Bind(DeleteStatement &stmt); + BoundStatement Bind(UpdateStatement &stmt); + BoundStatement Bind(CreateStatement &stmt); + BoundStatement Bind(DropStatement &stmt); + BoundStatement Bind(AlterStatement &stmt); + BoundStatement Bind(PrepareStatement &stmt); + BoundStatement Bind(ExecuteStatement &stmt); + BoundStatement Bind(TransactionStatement &stmt); + BoundStatement Bind(PragmaStatement &stmt); + BoundStatement Bind(ExplainStatement &stmt); + BoundStatement Bind(VacuumStatement &stmt); + BoundStatement Bind(RelationStatement &stmt); + BoundStatement Bind(ShowStatement &stmt); + BoundStatement Bind(CallStatement &stmt); + BoundStatement Bind(ExportStatement &stmt); + BoundStatement Bind(ExtensionStatement &stmt); + BoundStatement Bind(SetStatement &stmt); + BoundStatement Bind(SetVariableStatement &stmt); + BoundStatement Bind(ResetVariableStatement &stmt); + BoundStatement Bind(LoadStatement &stmt); + BoundStatement Bind(LogicalPlanStatement &stmt); + BoundStatement Bind(AttachStatement &stmt); -/*! -Sets the name of the given table function. + BoundStatement BindReturning(vector> returning_list, TableCatalogEntry *table, + idx_t update_table_index, unique_ptr child_operator, + BoundStatement result); -* table_function: The table function -* name: The name of the table function -*/ -DUCKDB_API void duckdb_table_function_set_name(duckdb_table_function table_function, const char *name); + unique_ptr BindTableMacro(FunctionExpression &function, TableMacroCatalogEntry *macro_func, idx_t depth); -/*! -Adds a parameter to the table function. + unique_ptr BindNode(SelectNode &node); + unique_ptr BindNode(SetOperationNode &node); + unique_ptr BindNode(RecursiveCTENode &node); + unique_ptr BindNode(QueryNode &node); -* table_function: The table function -* type: The type of the parameter to add. -*/ -DUCKDB_API void duckdb_table_function_add_parameter(duckdb_table_function table_function, duckdb_logical_type type); + unique_ptr VisitQueryNode(BoundQueryNode &node, unique_ptr root); + unique_ptr CreatePlan(BoundRecursiveCTENode &node); + unique_ptr CreatePlan(BoundSelectNode &statement); + unique_ptr CreatePlan(BoundSetOperationNode &node); + unique_ptr CreatePlan(BoundQueryNode &node); -/*! -Assigns extra information to the table function that can be fetched during binding, etc. + unique_ptr Bind(BaseTableRef &ref); + unique_ptr Bind(JoinRef &ref); + unique_ptr Bind(SubqueryRef &ref, CommonTableExpressionInfo *cte = nullptr); + unique_ptr Bind(TableFunctionRef &ref); + unique_ptr Bind(EmptyTableRef &ref); + unique_ptr Bind(ExpressionListRef &ref); -* table_function: The table function -* extra_info: The extra information -* destroy: The callback that will be called to destroy the bind data (if any) -*/ -DUCKDB_API void duckdb_table_function_set_extra_info(duckdb_table_function table_function, void *extra_info, - duckdb_delete_callback_t destroy); + bool BindTableFunctionParameters(TableFunctionCatalogEntry &table_function, + vector> &expressions, vector &arguments, + vector ¶meters, named_parameter_map_t &named_parameters, + unique_ptr &subquery, string &error); + bool BindTableInTableOutFunction(vector> &expressions, + unique_ptr &subquery, string &error); + unique_ptr BindTableFunction(TableFunction &function, vector parameters); + unique_ptr + BindTableFunctionInternal(TableFunction &table_function, const string &function_name, vector parameters, + named_parameter_map_t named_parameters, vector input_table_types, + vector input_table_names, const vector &column_name_alias, + unique_ptr external_dependency); -/*! -Sets the bind function of the table function + unique_ptr CreatePlan(BoundBaseTableRef &ref); + unique_ptr CreatePlan(BoundJoinRef &ref); + unique_ptr CreatePlan(BoundSubqueryRef &ref); + unique_ptr CreatePlan(BoundTableFunction &ref); + unique_ptr CreatePlan(BoundEmptyTableRef &ref); + unique_ptr CreatePlan(BoundExpressionListRef &ref); + unique_ptr CreatePlan(BoundCTERef &ref); -* table_function: The table function -* bind: The bind function -*/ -DUCKDB_API void duckdb_table_function_set_bind(duckdb_table_function table_function, duckdb_table_function_bind_t bind); + BoundStatement BindCopyTo(CopyStatement &stmt); + BoundStatement BindCopyFrom(CopyStatement &stmt); -/*! -Sets the init function of the table function + void BindModifiers(OrderBinder &order_binder, QueryNode &statement, BoundQueryNode &result); + void BindModifierTypes(BoundQueryNode &result, const vector &sql_types, idx_t projection_index); -* table_function: The table function -* init: The init function -*/ -DUCKDB_API void duckdb_table_function_set_init(duckdb_table_function table_function, duckdb_table_function_init_t init); + BoundStatement BindSummarize(ShowStatement &stmt); + unique_ptr BindLimit(OrderBinder &order_binder, LimitModifier &limit_mod); + unique_ptr BindLimitPercent(OrderBinder &order_binder, LimitPercentModifier &limit_mod); + unique_ptr BindOrderExpression(OrderBinder &order_binder, unique_ptr expr); -/*! -Sets the thread-local init function of the table function + unique_ptr PlanFilter(unique_ptr condition, unique_ptr root); -* table_function: The table function -* init: The init function -*/ -DUCKDB_API void duckdb_table_function_set_local_init(duckdb_table_function table_function, - duckdb_table_function_init_t init); + void PlanSubqueries(unique_ptr *expr, unique_ptr *root); + unique_ptr PlanSubquery(BoundSubqueryExpression &expr, unique_ptr &root); + unique_ptr PlanLateralJoin(unique_ptr left, unique_ptr right, + vector &correlated_columns, + JoinType join_type = JoinType::INNER, + unique_ptr condition = nullptr); -/*! -Sets the main function of the table function + unique_ptr CastLogicalOperatorToTypes(vector &source_types, + vector &target_types, + unique_ptr op); -* table_function: The table function -* function: The function -*/ -DUCKDB_API void duckdb_table_function_set_function(duckdb_table_function table_function, - duckdb_table_function_t function); + string FindBinding(const string &using_column, const string &join_side); + bool TryFindBinding(const string &using_column, const string &join_side, string &result); -/*! -Sets whether or not the given table function supports projection pushdown. + void AddUsingBindingSet(unique_ptr set); + string RetrieveUsingBinding(Binder ¤t_binder, UsingColumnSet *current_set, const string &column_name, + const string &join_side, UsingColumnSet *new_set); -If this is set to true, the system will provide a list of all required columns in the `init` stage through -the `duckdb_init_get_column_count` and `duckdb_init_get_column_index` functions. -If this is set to false (the default), the system will expect all columns to be projected. + void AddCTEMap(CommonTableExpressionMap &cte_map); -* table_function: The table function -* pushdown: True if the table function supports projection pushdown, false otherwise. -*/ -DUCKDB_API void duckdb_table_function_supports_projection_pushdown(duckdb_table_function table_function, bool pushdown); + void ExpandStarExpressions(vector> &select_list, + vector> &new_select_list); + void ExpandStarExpression(unique_ptr expr, vector> &new_select_list); + bool FindStarExpression(ParsedExpression &expr, StarExpression **star); + void ReplaceStarExpression(unique_ptr &expr, unique_ptr &replacement); -/*! -Register the table function object within the given connection. + //! If only a schema name is provided (e.g. "a.b") then figure out if "a" is a schema or a catalog name + void BindSchemaOrCatalog(string &catalog_name, string &schema_name); + SchemaCatalogEntry *BindCreateSchema(CreateInfo &info); -The function requires at least a name, a bind function, an init function and a main function. +public: + // This should really be a private constructor, but make_shared does not allow it... + // If you are thinking about calling this, you should probably call Binder::CreateBinder + Binder(bool i_know_what_i_am_doing, ClientContext &context, shared_ptr parent, bool inherit_ctes); +}; -If the function is incomplete or a function with this name already exists DuckDBError is returned. +} // namespace duckdb -* con: The connection to register it in. -* function: The function pointer -* returns: Whether or not the registration was successful. -*/ -DUCKDB_API duckdb_state duckdb_register_table_function(duckdb_connection con, duckdb_table_function function); -//===--------------------------------------------------------------------===// -// Table Function Bind -//===--------------------------------------------------------------------===// -/*! -Retrieves the extra info of the function as set in `duckdb_table_function_set_extra_info` +namespace duckdb { -* info: The info object -* returns: The extra info -*/ -DUCKDB_API void *duckdb_bind_get_extra_info(duckdb_bind_info info); +//! The OperatorExtensionInfo holds static information relevant to the operator extension +struct OperatorExtensionInfo { + DUCKDB_API virtual ~OperatorExtensionInfo() { + } +}; -/*! -Adds a result column to the output of the table function. +typedef BoundStatement (*bind_function_t)(ClientContext &context, Binder &binder, OperatorExtensionInfo *info, + SQLStatement &statement); -* info: The info object -* name: The name of the column -* type: The logical type of the column -*/ -DUCKDB_API void duckdb_bind_add_result_column(duckdb_bind_info info, const char *name, duckdb_logical_type type); +// forward declaration to avoid circular reference +struct LogicalExtensionOperator; -/*! -Retrieves the number of regular (non-named) parameters to the function. +class OperatorExtension { +public: + bind_function_t Bind; -* info: The info object -* returns: The number of parameters -*/ -DUCKDB_API idx_t duckdb_bind_get_parameter_count(duckdb_bind_info info); + //! Additional info passed to the CreatePlan & Bind functions + shared_ptr operator_info; -/*! -Retrieves the parameter at the given index. + virtual std::string GetName() = 0; + virtual std::unique_ptr Deserialize(LogicalDeserializationState &state, + FieldReader &reader) = 0; -The result must be destroyed with `duckdb_destroy_value`. + DUCKDB_API virtual ~OperatorExtension() { + } +}; -* info: The info object -* index: The index of the parameter to get -* returns: The value of the parameter. Must be destroyed with `duckdb_destroy_value`. -*/ -DUCKDB_API duckdb_value duckdb_bind_get_parameter(duckdb_bind_info info, idx_t index); +} // namespace duckdb -/*! -Sets the user-provided bind data in the bind object. This object can be retrieved again during execution. -* info: The info object -* extra_data: The bind data object. -* destroy: The callback that will be called to destroy the bind data (if any) -*/ -DUCKDB_API void duckdb_bind_set_bind_data(duckdb_bind_info info, void *bind_data, duckdb_delete_callback_t destroy); +namespace duckdb { +class CastFunctionSet; +class ClientContext; +class ErrorManager; +class CompressionFunction; +class TableFunctionRef; +class OperatorExtension; +class StorageExtension; -/*! -Sets the cardinality estimate for the table function, used for optimization. +struct CompressionFunctionSet; +struct DBConfig; -* info: The bind data object. -* is_exact: Whether or not the cardinality estimate is exact, or an approximation -*/ -DUCKDB_API void duckdb_bind_set_cardinality(duckdb_bind_info info, idx_t cardinality, bool is_exact); +enum class CheckpointAbort : uint8_t { + NO_ABORT = 0, + DEBUG_ABORT_BEFORE_TRUNCATE = 1, + DEBUG_ABORT_BEFORE_HEADER = 2, + DEBUG_ABORT_AFTER_FREE_LIST_WRITE = 3 +}; -/*! -Report that an error has occurred while calling bind. +typedef void (*set_global_function_t)(DatabaseInstance *db, DBConfig &config, const Value ¶meter); +typedef void (*set_local_function_t)(ClientContext &context, const Value ¶meter); +typedef void (*reset_global_function_t)(DatabaseInstance *db, DBConfig &config); +typedef void (*reset_local_function_t)(ClientContext &context); +typedef Value (*get_setting_function_t)(ClientContext &context); -* info: The info object -* error: The error message -*/ -DUCKDB_API void duckdb_bind_set_error(duckdb_bind_info info, const char *error); +struct ConfigurationOption { + const char *name; + const char *description; + LogicalTypeId parameter_type; + set_global_function_t set_global; + set_local_function_t set_local; + reset_global_function_t reset_global; + reset_local_function_t reset_local; + get_setting_function_t get_setting; +}; -//===--------------------------------------------------------------------===// -// Table Function Init -//===--------------------------------------------------------------------===// +typedef void (*set_option_callback_t)(ClientContext &context, SetScope scope, Value ¶meter); -/*! -Retrieves the extra info of the function as set in `duckdb_table_function_set_extra_info` +struct ExtensionOption { + ExtensionOption(string description_p, LogicalType type_p, set_option_callback_t set_function_p, + Value default_value_p) + : description(std::move(description_p)), type(std::move(type_p)), set_function(set_function_p), + default_value(std::move(default_value_p)) { + } -* info: The info object -* returns: The extra info -*/ -DUCKDB_API void *duckdb_init_get_extra_info(duckdb_init_info info); + string description; + LogicalType type; + set_option_callback_t set_function; + Value default_value; +}; -/*! -Gets the bind data set by `duckdb_bind_set_bind_data` during the bind. +struct DBConfigOptions { + //! Database file path. May be empty for in-memory mode + string database_path; + //! Access mode of the database (AUTOMATIC, READ_ONLY or READ_WRITE) + AccessMode access_mode = AccessMode::AUTOMATIC; + //! Checkpoint when WAL reaches this size (default: 16MB) + idx_t checkpoint_wal_size = 1 << 24; + //! Whether or not to use Direct IO, bypassing operating system buffers + bool use_direct_io = false; + //! Whether extensions should be loaded on start-up + bool load_extensions = true; + //! The maximum memory used by the database system (in bytes). Default: 80% of System available memory + idx_t maximum_memory = (idx_t)-1; + //! The maximum amount of CPU threads used by the database system. Default: all available. + idx_t maximum_threads = (idx_t)-1; + //! The number of external threads that work on DuckDB tasks. Default: none. + idx_t external_threads = 0; + //! Whether or not to create and use a temporary directory to store intermediates that do not fit in memory + bool use_temporary_directory = true; + //! Directory to store temporary structures that do not fit in memory + string temporary_directory; + //! The collation type of the database + string collation = string(); + //! The order type used when none is specified (default: ASC) + OrderType default_order_type = OrderType::ASCENDING; + //! Null ordering used when none is specified (default: NULLS FIRST) + OrderByNullType default_null_order = OrderByNullType::NULLS_FIRST; + //! enable COPY and related commands + bool enable_external_access = true; + //! Whether or not object cache is used + bool object_cache_enable = false; + //! Whether or not the global http metadata cache is used + bool http_metadata_cache_enable = false; + //! Force checkpoint when CHECKPOINT is called or on shutdown, even if no changes have been made + bool force_checkpoint = false; + //! Run a checkpoint on successful shutdown and delete the WAL, to leave only a single database file behind + bool checkpoint_on_shutdown = true; + //! Debug flag that decides when a checkpoing should be aborted. Only used for testing purposes. + CheckpointAbort checkpoint_abort = CheckpointAbort::NO_ABORT; + //! Initialize the database with the standard set of DuckDB functions + //! You should probably not touch this unless you know what you are doing + bool initialize_default_database = true; + //! The set of disabled optimizers (default empty) + set disabled_optimizers; + //! Force a specific compression method to be used when checkpointing (if available) + CompressionType force_compression = CompressionType::COMPRESSION_AUTO; + //! Force a specific bitpacking mode to be used when using the bitpacking compression method + BitpackingMode force_bitpacking_mode = BitpackingMode::AUTO; + //! Debug setting for window aggregation mode: (window, combine, separate) + WindowAggregationMode window_mode = WindowAggregationMode::WINDOW; + //! Whether or not preserving insertion order should be preserved + bool preserve_insertion_order = true; + //! Database configuration variables as controlled by SET + case_insensitive_map_t set_variables; + //! Database configuration variable default values; + case_insensitive_map_t set_variable_defaults; + //! Whether unsigned extensions should be loaded + bool allow_unsigned_extensions = false; + //! Enable emitting FSST Vectors + bool enable_fsst_vectors = false; + //! Experimental parallel CSV reader + bool experimental_parallel_csv_reader = false; + //! Start transactions immediately in all attached databases - instead of lazily when a database is referenced + bool immediate_transaction_mode = false; + //! The set of unrecognized (other) options + unordered_map unrecognized_options; -Note that the bind data should be considered as read-only. -For tracking state, use the init data instead. + bool operator==(const DBConfigOptions &other) const; +}; -* info: The info object -* returns: The bind data object -*/ -DUCKDB_API void *duckdb_init_get_bind_data(duckdb_init_info info); +struct DBConfig { + friend class DatabaseInstance; + friend class StorageManager; -/*! -Sets the user-provided init data in the init object. This object can be retrieved again during execution. +public: + DUCKDB_API DBConfig(); + DUCKDB_API DBConfig(std::unordered_map &config_dict, bool read_only); + DUCKDB_API ~DBConfig(); -* info: The info object -* extra_data: The init data object. -* destroy: The callback that will be called to destroy the init data (if any) -*/ -DUCKDB_API void duckdb_init_set_init_data(duckdb_init_info info, void *init_data, duckdb_delete_callback_t destroy); + mutex config_lock; + //! Replacement table scans are automatically attempted when a table name cannot be found in the schema + vector replacement_scans; -/*! -Returns the number of projected columns. + //! Extra parameters that can be SET for loaded extensions + case_insensitive_map_t extension_parameters; + //! The FileSystem to use, can be overwritten to allow for injecting custom file systems for testing purposes (e.g. + //! RamFS or something similar) + unique_ptr file_system; + //! The allocator used by the system + unique_ptr allocator; + //! Database configuration options + DBConfigOptions options; + //! Extensions made to the parser + vector parser_extensions; + //! Extensions made to the optimizer + vector optimizer_extensions; + //! Error manager + unique_ptr error_manager; + //! A reference to the (shared) default allocator (Allocator::DefaultAllocator) + shared_ptr default_allocator; + //! Extensions made to binder + vector> operator_extensions; + //! Extensions made to storage + case_insensitive_map_t> storage_extensions; + //! Extensions made to binder to implement the create_database functionality + vector create_database_extensions; -This function must be used if projection pushdown is enabled to figure out which columns to emit. +public: + DUCKDB_API static DBConfig &GetConfig(ClientContext &context); + DUCKDB_API static DBConfig &GetConfig(DatabaseInstance &db); + DUCKDB_API static DBConfig &Get(AttachedDatabase &db); + DUCKDB_API static const DBConfig &GetConfig(const ClientContext &context); + DUCKDB_API static const DBConfig &GetConfig(const DatabaseInstance &db); + DUCKDB_API static vector GetOptions(); + DUCKDB_API static idx_t GetOptionCount(); + DUCKDB_API static vector GetOptionNames(); -* info: The info object -* returns: The number of projected columns. -*/ -DUCKDB_API idx_t duckdb_init_get_column_count(duckdb_init_info info); + DUCKDB_API void AddExtensionOption(const string &name, string description, LogicalType parameter, + const Value &default_value = Value(), set_option_callback_t function = nullptr); + //! Fetch an option by index. Returns a pointer to the option, or nullptr if out of range + DUCKDB_API static ConfigurationOption *GetOptionByIndex(idx_t index); + //! Fetch an option by name. Returns a pointer to the option, or nullptr if none exists. + DUCKDB_API static ConfigurationOption *GetOptionByName(const string &name); -/*! -Returns the column index of the projected column at the specified position. + DUCKDB_API void SetOption(const ConfigurationOption &option, const Value &value); + DUCKDB_API void SetOption(DatabaseInstance *db, const ConfigurationOption &option, const Value &value); + DUCKDB_API void SetOptionByName(const string &name, const Value &value); + DUCKDB_API void ResetOption(DatabaseInstance *db, const ConfigurationOption &option); + DUCKDB_API void SetOption(const string &name, Value value); + DUCKDB_API void ResetOption(const string &name); -This function must be used if projection pushdown is enabled to figure out which columns to emit. + DUCKDB_API static idx_t ParseMemoryLimit(const string &arg); -* info: The info object -* column_index: The index at which to get the projected column index, from 0..duckdb_init_get_column_count(info) -* returns: The column index of the projected column. -*/ -DUCKDB_API idx_t duckdb_init_get_column_index(duckdb_init_info info, idx_t column_index); + //! Return the list of possible compression functions for the specific physical type + DUCKDB_API vector GetCompressionFunctions(PhysicalType data_type); + //! Return the compression function for the specified compression type/physical type combo + DUCKDB_API CompressionFunction *GetCompressionFunction(CompressionType type, PhysicalType data_type); -/*! -Sets how many threads can process this table function in parallel (default: 1) + bool operator==(const DBConfig &other); + bool operator!=(const DBConfig &other); -* info: The info object -* max_threads: The maximum amount of threads that can process this table function -*/ -DUCKDB_API void duckdb_init_set_max_threads(duckdb_init_info info, idx_t max_threads); + DUCKDB_API CastFunctionSet &GetCastFunctions(); + void SetDefaultMaxThreads(); + void SetDefaultMaxMemory(); -/*! -Report that an error has occurred while calling init. +private: + unique_ptr compression_functions; + unique_ptr cast_functions; +}; -* info: The info object -* error: The error message -*/ -DUCKDB_API void duckdb_init_set_error(duckdb_init_info info, const char *error); +} // namespace duckdb -//===--------------------------------------------------------------------===// -// Table Function -//===--------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/valid_checker.hpp +// +// +//===----------------------------------------------------------------------===// -/*! -Retrieves the extra info of the function as set in `duckdb_table_function_set_extra_info` -* info: The info object -* returns: The extra info -*/ -DUCKDB_API void *duckdb_function_get_extra_info(duckdb_function_info info); -/*! -Gets the bind data set by `duckdb_bind_set_bind_data` during the bind. -Note that the bind data should be considered as read-only. -For tracking state, use the init data instead. -* info: The info object -* returns: The bind data object -*/ -DUCKDB_API void *duckdb_function_get_bind_data(duckdb_function_info info); -/*! -Gets the init data set by `duckdb_init_set_init_data` during the init. -* info: The info object -* returns: The init data object -*/ -DUCKDB_API void *duckdb_function_get_init_data(duckdb_function_info info); -/*! -Gets the thread-local init data set by `duckdb_init_set_init_data` during the local_init. +namespace duckdb { +class DatabaseInstance; +class MetaTransaction; -* info: The info object -* returns: The init data object -*/ -DUCKDB_API void *duckdb_function_get_local_init_data(duckdb_function_info info); +class ValidChecker { +public: + ValidChecker(); -/*! -Report that an error has occurred while executing the function. + DUCKDB_API static ValidChecker &Get(DatabaseInstance &db); + DUCKDB_API static ValidChecker &Get(MetaTransaction &transaction); -* info: The info object -* error: The error message -*/ -DUCKDB_API void duckdb_function_set_error(duckdb_function_info info, const char *error); + DUCKDB_API void Invalidate(string error); + DUCKDB_API bool IsInvalidated(); + DUCKDB_API string InvalidatedMessage(); -//===--------------------------------------------------------------------===// -// Replacement Scans -//===--------------------------------------------------------------------===// -typedef void *duckdb_replacement_scan_info; + template + static bool IsInvalidated(T &o) { + return Get(o).IsInvalidated(); + } + template + static void Invalidate(T &o, string error) { + Get(o).Invalidate(std::move(error)); + } -typedef void (*duckdb_replacement_callback_t)(duckdb_replacement_scan_info info, const char *table_name, void *data); + template + static string InvalidatedMessage(T &o) { + return Get(o).InvalidatedMessage(); + } -/*! -Add a replacement scan definition to the specified database +private: + //! Set to true if a fatal exception has occurred + mutex invalidate_lock; + atomic is_invalidated; + string invalidated_msg; +}; -* db: The database object to add the replacement scan to -* replacement: The replacement scan callback -* extra_data: Extra data that is passed back into the specified callback -* delete_callback: The delete callback to call on the extra data, if any -*/ -DUCKDB_API void duckdb_add_replacement_scan(duckdb_database db, duckdb_replacement_callback_t replacement, - void *extra_data, duckdb_delete_callback_t delete_callback); +} // namespace duckdb -/*! -Sets the replacement function name to use. If this function is called in the replacement callback, - the replacement scan is performed. If it is not called, the replacement callback is not performed. -* info: The info object -* function_name: The function name to substitute. -*/ -DUCKDB_API void duckdb_replacement_scan_set_function_name(duckdb_replacement_scan_info info, const char *function_name); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/extension.hpp +// +// +//===----------------------------------------------------------------------===// -/*! -Adds a parameter to the replacement scan function. -* info: The info object -* parameter: The parameter to add. -*/ -DUCKDB_API void duckdb_replacement_scan_add_parameter(duckdb_replacement_scan_info info, duckdb_value parameter); -/*! -Report that an error has occurred while executing the replacement scan. -* info: The info object -* error: The error message -*/ -DUCKDB_API void duckdb_replacement_scan_set_error(duckdb_replacement_scan_info info, const char *error); -//===--------------------------------------------------------------------===// -// Appender -//===--------------------------------------------------------------------===// -// Appenders are the most efficient way of loading data into DuckDB from within the C interface, and are recommended for -// fast data loading. The appender is much faster than using prepared statements or individual `INSERT INTO` statements. +namespace duckdb { +class DuckDB; -// Appends are made in row-wise format. For every column, a `duckdb_append_[type]` call should be made, after which -// the row should be finished by calling `duckdb_appender_end_row`. After all rows have been appended, -// `duckdb_appender_destroy` should be used to finalize the appender and clean up the resulting memory. +//! The Extension class is the base class used to define extensions +class Extension { +public: + DUCKDB_API virtual ~Extension(); -// Note that `duckdb_appender_destroy` should always be called on the resulting appender, even if the function returns -// `DuckDBError`. + DUCKDB_API virtual void Load(DuckDB &db) = 0; + DUCKDB_API virtual std::string Name() = 0; +}; -/*! -Creates an appender object. +} // namespace duckdb -* connection: The connection context to create the appender in. -* schema: The schema of the table to append to, or `nullptr` for the default schema. -* table: The table name to append to. -* out_appender: The resulting appender object. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_appender_create(duckdb_connection connection, const char *schema, const char *table, - duckdb_appender *out_appender); -/*! -Returns the error message associated with the given appender. -If the appender has no error message, this returns `nullptr` instead. +namespace duckdb { +class BufferManager; +class DatabaseManager; +class StorageManager; +class Catalog; +class TransactionManager; +class ConnectionManager; +class FileSystem; +class TaskScheduler; +class ObjectCache; +struct AttachInfo; -The error message should not be freed. It will be de-allocated when `duckdb_appender_destroy` is called. +class DatabaseInstance : public std::enable_shared_from_this { + friend class DuckDB; -* appender: The appender to get the error from. -* returns: The error message, or `nullptr` if there is none. -*/ -DUCKDB_API const char *duckdb_appender_error(duckdb_appender appender); +public: + DUCKDB_API DatabaseInstance(); + DUCKDB_API ~DatabaseInstance(); -/*! -Flush the appender to the table, forcing the cache of the appender to be cleared and the data to be appended to the -base table. + DBConfig config; -This should generally not be used unless you know what you are doing. Instead, call `duckdb_appender_destroy` when you -are done with the appender. +public: + DUCKDB_API BufferManager &GetBufferManager(); + DUCKDB_API DatabaseManager &GetDatabaseManager(); + DUCKDB_API FileSystem &GetFileSystem(); + DUCKDB_API TaskScheduler &GetScheduler(); + DUCKDB_API ObjectCache &GetObjectCache(); + DUCKDB_API ConnectionManager &GetConnectionManager(); + DUCKDB_API ValidChecker &GetValidChecker(); + DUCKDB_API void SetExtensionLoaded(const std::string &extension_name); -* appender: The appender to flush. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_appender_flush(duckdb_appender appender); + idx_t NumberOfThreads(); -/*! -Close the appender, flushing all intermediate state in the appender to the table and closing it for further appends. + DUCKDB_API static DatabaseInstance &GetDatabase(ClientContext &context); -This is generally not necessary. Call `duckdb_appender_destroy` instead. + DUCKDB_API const unordered_set &LoadedExtensions(); + DUCKDB_API bool ExtensionIsLoaded(const std::string &name); -* appender: The appender to flush and close. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_appender_close(duckdb_appender appender); + DUCKDB_API bool TryGetCurrentSetting(const std::string &key, Value &result); -/*! -Close the appender and destroy it. Flushing all intermediate state in the appender to the table, and de-allocating -all memory associated with the appender. + //! Get the database extension type from a given path + string ExtractDatabaseType(string &path); + unique_ptr CreateAttachedDatabase(AttachInfo &info, const string &type, AccessMode access_mode); -* appender: The appender to flush, close and destroy. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_appender_destroy(duckdb_appender *appender); +private: + void Initialize(const char *path, DBConfig *config); -/*! -A nop function, provided for backwards compatibility reasons. Does nothing. Only `duckdb_appender_end_row` is required. -*/ -DUCKDB_API duckdb_state duckdb_appender_begin_row(duckdb_appender appender); + void Configure(DBConfig &config); -/*! -Finish the current row of appends. After end_row is called, the next row can be appended. +private: + unique_ptr buffer_manager; + unique_ptr db_manager; + unique_ptr scheduler; + unique_ptr object_cache; + unique_ptr connection_manager; + unordered_set loaded_extensions; + ValidChecker db_validity; +}; -* appender: The appender. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_appender_end_row(duckdb_appender appender); +//! The database object. This object holds the catalog and all the +//! database-specific meta information. +class DuckDB { +public: + DUCKDB_API explicit DuckDB(const char *path = nullptr, DBConfig *config = nullptr); + DUCKDB_API explicit DuckDB(const string &path, DBConfig *config = nullptr); + DUCKDB_API explicit DuckDB(DatabaseInstance &instance); -/*! -Append a bool value to the appender. -*/ -DUCKDB_API duckdb_state duckdb_append_bool(duckdb_appender appender, bool value); + DUCKDB_API ~DuckDB(); -/*! -Append an int8_t value to the appender. -*/ -DUCKDB_API duckdb_state duckdb_append_int8(duckdb_appender appender, int8_t value); -/*! -Append an int16_t value to the appender. -*/ -DUCKDB_API duckdb_state duckdb_append_int16(duckdb_appender appender, int16_t value); -/*! -Append an int32_t value to the appender. -*/ -DUCKDB_API duckdb_state duckdb_append_int32(duckdb_appender appender, int32_t value); -/*! -Append an int64_t value to the appender. -*/ -DUCKDB_API duckdb_state duckdb_append_int64(duckdb_appender appender, int64_t value); -/*! -Append a duckdb_hugeint value to the appender. -*/ -DUCKDB_API duckdb_state duckdb_append_hugeint(duckdb_appender appender, duckdb_hugeint value); + //! Reference to the actual database instance + shared_ptr instance; -/*! -Append a uint8_t value to the appender. -*/ -DUCKDB_API duckdb_state duckdb_append_uint8(duckdb_appender appender, uint8_t value); -/*! -Append a uint16_t value to the appender. -*/ -DUCKDB_API duckdb_state duckdb_append_uint16(duckdb_appender appender, uint16_t value); -/*! -Append a uint32_t value to the appender. -*/ -DUCKDB_API duckdb_state duckdb_append_uint32(duckdb_appender appender, uint32_t value); -/*! -Append a uint64_t value to the appender. -*/ -DUCKDB_API duckdb_state duckdb_append_uint64(duckdb_appender appender, uint64_t value); +public: + template + void LoadExtension() { + T extension; + if (ExtensionIsLoaded(extension.Name())) { + return; + } + extension.Load(*this); + instance->SetExtensionLoaded(extension.Name()); + } -/*! -Append a float value to the appender. -*/ -DUCKDB_API duckdb_state duckdb_append_float(duckdb_appender appender, float value); -/*! -Append a double value to the appender. -*/ -DUCKDB_API duckdb_state duckdb_append_double(duckdb_appender appender, double value); + DUCKDB_API FileSystem &GetFileSystem(); -/*! -Append a duckdb_date value to the appender. -*/ -DUCKDB_API duckdb_state duckdb_append_date(duckdb_appender appender, duckdb_date value); -/*! -Append a duckdb_time value to the appender. -*/ -DUCKDB_API duckdb_state duckdb_append_time(duckdb_appender appender, duckdb_time value); -/*! -Append a duckdb_timestamp value to the appender. -*/ -DUCKDB_API duckdb_state duckdb_append_timestamp(duckdb_appender appender, duckdb_timestamp value); -/*! -Append a duckdb_interval value to the appender. -*/ -DUCKDB_API duckdb_state duckdb_append_interval(duckdb_appender appender, duckdb_interval value); + DUCKDB_API idx_t NumberOfThreads(); + DUCKDB_API static const char *SourceID(); + DUCKDB_API static const char *LibraryVersion(); + DUCKDB_API static idx_t StandardVectorSize(); + DUCKDB_API static string Platform(); + DUCKDB_API bool ExtensionIsLoaded(const std::string &name); +}; -/*! -Append a varchar value to the appender. -*/ -DUCKDB_API duckdb_state duckdb_append_varchar(duckdb_appender appender, const char *val); -/*! -Append a varchar value to the appender. -*/ -DUCKDB_API duckdb_state duckdb_append_varchar_length(duckdb_appender appender, const char *val, idx_t length); -/*! -Append a blob value to the appender. -*/ -DUCKDB_API duckdb_state duckdb_append_blob(duckdb_appender appender, const void *data, idx_t length); -/*! -Append a NULL value to the appender (of any type). -*/ -DUCKDB_API duckdb_state duckdb_append_null(duckdb_appender appender); +} // namespace duckdb -/*! -Appends a pre-filled data chunk to the specified appender. -The types of the data chunk must exactly match the types of the table, no casting is performed. -If the types do not match or the appender is in an invalid state, DuckDBError is returned. -If the append is successful, DuckDBSuccess is returned. +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/loadable_extension.hpp +// +// +//===----------------------------------------------------------------------===// -* appender: The appender to append to. -* chunk: The data chunk to append. -* returns: The return state. -*/ -DUCKDB_API duckdb_state duckdb_append_data_chunk(duckdb_appender appender, duckdb_data_chunk chunk); -//===--------------------------------------------------------------------===// -// Arrow Interface -//===--------------------------------------------------------------------===// -/*! -Executes a SQL query within a connection and stores the full (materialized) result in an arrow structure. -If the query fails to execute, DuckDBError is returned and the error message can be retrieved by calling -`duckdb_query_arrow_error`. -Note that after running `duckdb_query_arrow`, `duckdb_destroy_arrow` must be called on the result object even if the -query fails, otherwise the error stored within the result will not be freed correctly. +#if defined(DUCKDB_BUILD_LOADABLE_EXTENSION) && defined(DUCKDB_EXTENSION_MAIN) +#if defined(_WIN32) || defined(_WIN64) +#ifndef NOMINMAX +#define NOMINMAX +#endif + +#ifndef _WINSOCKAPI_ +#define _WINSOCKAPI_ +#endif +#include -* connection: The connection to perform the query in. -* query: The SQL query to run. -* out_result: The query result. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_query_arrow(duckdb_connection connection, const char *query, duckdb_arrow *out_result); +#undef CreateDirectory +#undef MoveFile +#undef RemoveDirectory -/*! -Fetch the internal arrow schema from the arrow result. +#include -* result: The result to fetch the schema from. -* out_schema: The output schema. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. +extern "C" { +/* +This is interesting: Windows would normally require a duckdb.dll being on the DLL search path when we load an extension +using LoadLibrary(). However, there is likely no such dll, because DuckDB was statically linked, or is running as part +of an R or Python module with a completely different name (that we don't know) or something of the sorts. Amazingly, +Windows supports lazy-loading DLLs by linking them with /DELAYLOAD. Then a callback will be triggered whenever we access +symbols in the extension. Since DuckDB is already running in the host process (hopefully), we can use +GetModuleHandle(NULL) to return the current process so the symbols are looked for there. See here for another +explanation of this crazy process: + +* https://docs.microsoft.com/en-us/cpp/build/reference/linker-support-for-delay-loaded-dlls?view=msvc-160 +* https://docs.microsoft.com/en-us/cpp/build/reference/understanding-the-helper-function?view=msvc-160 */ -DUCKDB_API duckdb_state duckdb_query_arrow_schema(duckdb_arrow result, duckdb_arrow_schema *out_schema); +FARPROC WINAPI duckdb_dllimport_delay_hook(unsigned dliNotify, PDelayLoadInfo pdli) { + switch (dliNotify) { + case dliNotePreLoadLibrary: + if (strcmp(pdli->szDll, "duckdb.dll") != 0) { + return NULL; + } + return (FARPROC)GetModuleHandle(NULL); + default: + return NULL; + } -/*! -Fetch an internal arrow array from the arrow result. + return NULL; +} -This function can be called multiple time to get next chunks, which will free the previous out_array. -So consume the out_array before calling this function again. +ExternC const PfnDliHook __pfnDliNotifyHook2 = duckdb_dllimport_delay_hook; +ExternC const PfnDliHook __pfnDliFailureHook2 = duckdb_dllimport_delay_hook; +} +#endif +#endif -* result: The result to fetch the array from. -* out_array: The output array. -* returns: `DuckDBSuccess` on success or `DuckDBError` on failure. -*/ -DUCKDB_API duckdb_state duckdb_query_arrow_array(duckdb_arrow result, duckdb_arrow_array *out_array); +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/main/appender.hpp +// +// +//===----------------------------------------------------------------------===// -/*! -Returns the number of columns present in a the arrow result object. -* result: The result object. -* returns: The number of columns present in the result object. -*/ -DUCKDB_API idx_t duckdb_arrow_column_count(duckdb_arrow result); -/*! -Returns the number of rows present in a the arrow result object. -* result: The result object. -* returns: The number of rows present in the result object. -*/ -DUCKDB_API idx_t duckdb_arrow_row_count(duckdb_arrow result); -/*! -Returns the number of rows changed by the query stored in the arrow result. This is relevant only for -INSERT/UPDATE/DELETE queries. For other queries the rows_changed will be 0. -* result: The result object. -* returns: The number of rows changed. -*/ -DUCKDB_API idx_t duckdb_arrow_rows_changed(duckdb_arrow result); -/*! -Returns the error message contained within the result. The error is only set if `duckdb_query_arrow` returns -`DuckDBError`. +namespace duckdb { -The error message should not be freed. It will be de-allocated when `duckdb_destroy_arrow` is called. +class ColumnDataCollection; +class ClientContext; +class DuckDB; +class TableCatalogEntry; +class Connection; -* result: The result object to fetch the nullmask from. -* returns: The error of the result. -*/ -DUCKDB_API const char *duckdb_query_arrow_error(duckdb_arrow result); +enum class AppenderType : uint8_t { + LOGICAL, // Cast input -> LogicalType + PHYSICAL // Cast input -> PhysicalType +}; -/*! -Closes the result and de-allocates all memory allocated for the arrow result. +//! The Appender class can be used to append elements to a table. +class BaseAppender { +protected: + //! The amount of tuples that will be gathered in the column data collection before flushing + static constexpr const idx_t FLUSH_COUNT = STANDARD_VECTOR_SIZE * 100; -* result: The result to destroy. -*/ -DUCKDB_API void duckdb_destroy_arrow(duckdb_arrow *result); + Allocator &allocator; + //! The append types + vector types; + //! The buffered data for the append + unique_ptr collection; + //! Internal chunk used for appends + DataChunk chunk; + //! The current column to append to + idx_t column = 0; + //! The type of the appender + AppenderType appender_type; -//===--------------------------------------------------------------------===// -// Threading Information -//===--------------------------------------------------------------------===// -typedef void *duckdb_task_state; +protected: + DUCKDB_API BaseAppender(Allocator &allocator, AppenderType type); + DUCKDB_API BaseAppender(Allocator &allocator, vector types, AppenderType type); -/*! -Execute DuckDB tasks on this thread. +public: + DUCKDB_API virtual ~BaseAppender(); -Will return after `max_tasks` have been executed, or if there are no more tasks present. + //! Begins a new row append, after calling this the other AppendX() functions + //! should be called the correct amount of times. After that, + //! EndRow() should be called. + DUCKDB_API void BeginRow(); + //! Finishes appending the current row. + DUCKDB_API void EndRow(); -* database: The database object to execute tasks for -* max_tasks: The maximum amount of tasks to execute -*/ -DUCKDB_API void duckdb_execute_tasks(duckdb_database database, idx_t max_tasks); + // Append functions + template + void Append(T value) { + throw Exception("Undefined type for Appender::Append!"); + } -/*! -Creates a task state that can be used with duckdb_execute_tasks_state to execute tasks until - duckdb_finish_execution is called on the state. + DUCKDB_API void Append(const char *value, uint32_t length); -duckdb_destroy_state should be called on the result in order to free memory. + // prepared statements + template + void AppendRow(Args... args) { + BeginRow(); + AppendRowRecursive(args...); + } -* database: The database object to create the task state for -* returns: The task state that can be used with duckdb_execute_tasks_state. -*/ -DUCKDB_API duckdb_task_state duckdb_create_task_state(duckdb_database database); + //! Commit the changes made by the appender. + DUCKDB_API void Flush(); + //! Flush the changes made by the appender and close it. The appender cannot be used after this point + DUCKDB_API void Close(); -/*! -Execute DuckDB tasks on this thread. + DUCKDB_API vector &GetTypes() { + return types; + } + DUCKDB_API idx_t CurrentColumn() { + return column; + } + DUCKDB_API void AppendDataChunk(DataChunk &value); -The thread will keep on executing tasks forever, until duckdb_finish_execution is called on the state. -Multiple threads can share the same duckdb_task_state. +protected: + void Destructor(); + virtual void FlushInternal(ColumnDataCollection &collection) = 0; + void InitializeChunk(); + void FlushChunk(); -* state: The task state of the executor -*/ -DUCKDB_API void duckdb_execute_tasks_state(duckdb_task_state state); + template + void AppendValueInternal(T value); + template + void AppendValueInternal(Vector &vector, SRC input); + template + void AppendDecimalValueInternal(Vector &vector, SRC input); -/*! -Execute DuckDB tasks on this thread. + void AppendRowRecursive() { + EndRow(); + } -The thread will keep on executing tasks until either duckdb_finish_execution is called on the state, -max_tasks tasks have been executed or there are no more tasks to be executed. + template + void AppendRowRecursive(T value, Args... args) { + Append(value); + AppendRowRecursive(args...); + } -Multiple threads can share the same duckdb_task_state. + void AppendValue(const Value &value); +}; -* state: The task state of the executor -* max_tasks: The maximum amount of tasks to execute -* returns: The amount of tasks that have actually been executed -*/ -DUCKDB_API idx_t duckdb_execute_n_tasks_state(duckdb_task_state state, idx_t max_tasks); +class Appender : public BaseAppender { + //! A reference to a database connection that created this appender + shared_ptr context; + //! The table description (including column names) + unique_ptr description; -/*! -Finish execution on a specific task. +public: + DUCKDB_API Appender(Connection &con, const string &schema_name, const string &table_name); + DUCKDB_API Appender(Connection &con, const string &table_name); + DUCKDB_API ~Appender() override; -* state: The task state to finish execution -*/ -DUCKDB_API void duckdb_finish_execution(duckdb_task_state state); +protected: + void FlushInternal(ColumnDataCollection &collection) override; +}; -/*! -Check if the provided duckdb_task_state has finished execution +class InternalAppender : public BaseAppender { + //! The client context + ClientContext &context; + //! The internal table entry to append to + TableCatalogEntry &table; -* state: The task state to inspect -* returns: Whether or not duckdb_finish_execution has been called on the task state -*/ -DUCKDB_API bool duckdb_task_state_is_finished(duckdb_task_state state); +public: + DUCKDB_API InternalAppender(ClientContext &context, TableCatalogEntry &table); + DUCKDB_API ~InternalAppender() override; -/*! -Destroys the task state returned from duckdb_create_task_state. +protected: + void FlushInternal(ColumnDataCollection &collection) override; +}; -Note that this should not be called while there is an active duckdb_execute_tasks_state running -on the task state. +template <> +DUCKDB_API void BaseAppender::Append(bool value); +template <> +DUCKDB_API void BaseAppender::Append(int8_t value); +template <> +DUCKDB_API void BaseAppender::Append(int16_t value); +template <> +DUCKDB_API void BaseAppender::Append(int32_t value); +template <> +DUCKDB_API void BaseAppender::Append(int64_t value); +template <> +DUCKDB_API void BaseAppender::Append(hugeint_t value); +template <> +DUCKDB_API void BaseAppender::Append(uint8_t value); +template <> +DUCKDB_API void BaseAppender::Append(uint16_t value); +template <> +DUCKDB_API void BaseAppender::Append(uint32_t value); +template <> +DUCKDB_API void BaseAppender::Append(uint64_t value); +template <> +DUCKDB_API void BaseAppender::Append(float value); +template <> +DUCKDB_API void BaseAppender::Append(double value); +template <> +DUCKDB_API void BaseAppender::Append(date_t value); +template <> +DUCKDB_API void BaseAppender::Append(dtime_t value); +template <> +DUCKDB_API void BaseAppender::Append(timestamp_t value); +template <> +DUCKDB_API void BaseAppender::Append(interval_t value); +template <> +DUCKDB_API void BaseAppender::Append(const char *value); +template <> +DUCKDB_API void BaseAppender::Append(string_t value); +template <> +DUCKDB_API void BaseAppender::Append(Value value); +template <> +DUCKDB_API void BaseAppender::Append(std::nullptr_t value); -* state: The task state to clean up -*/ -DUCKDB_API void duckdb_destroy_task_state(duckdb_task_state state); +} // namespace duckdb -#ifdef __cplusplus -} -#endif //===----------------------------------------------------------------------===// // DuckDB // @@ -21698,217 +22145,33 @@ namespace duckdb { struct dtime_t; -//! The Time class is a static class that holds helper functions for the Time -//! type. -class Time { -public: - //! Convert a string in the format "hh:mm:ss" to a time object - DUCKDB_API static dtime_t FromString(const string &str, bool strict = false); - DUCKDB_API static dtime_t FromCString(const char *buf, idx_t len, bool strict = false); - DUCKDB_API static bool TryConvertTime(const char *buf, idx_t len, idx_t &pos, dtime_t &result, bool strict = false); - - //! Convert a time object to a string in the format "hh:mm:ss" - DUCKDB_API static string ToString(dtime_t time); - //! Convert a UTC offset to ±HH[:MM] - DUCKDB_API static string ToUTCOffset(int hour_offset, int minute_offset); - - DUCKDB_API static dtime_t FromTime(int32_t hour, int32_t minute, int32_t second, int32_t microseconds = 0); - - //! Extract the time from a given timestamp object - DUCKDB_API static void Convert(dtime_t time, int32_t &out_hour, int32_t &out_min, int32_t &out_sec, - int32_t &out_micros); - - DUCKDB_API static string ConversionError(const string &str); - DUCKDB_API static string ConversionError(string_t str); - -private: - static bool TryConvertInternal(const char *buf, idx_t len, idx_t &pos, dtime_t &result, bool strict); -}; - -} // namespace duckdb -//===----------------------------------------------------------------------===// -// DuckDB -// -// duckdb/main/appender.hpp -// -// -//===----------------------------------------------------------------------===// - - - - - - - -namespace duckdb { - -class ColumnDataCollection; -class ClientContext; -class DuckDB; -class TableCatalogEntry; -class Connection; - -enum class AppenderType : uint8_t { - LOGICAL, // Cast input -> LogicalType - PHYSICAL // Cast input -> PhysicalType -}; - -//! The Appender class can be used to append elements to a table. -class BaseAppender { -protected: - //! The amount of tuples that will be gathered in the column data collection before flushing - static constexpr const idx_t FLUSH_COUNT = STANDARD_VECTOR_SIZE * 100; - - Allocator &allocator; - //! The append types - vector types; - //! The buffered data for the append - unique_ptr collection; - //! Internal chunk used for appends - DataChunk chunk; - //! The current column to append to - idx_t column = 0; - //! The type of the appender - AppenderType appender_type; - -protected: - DUCKDB_API BaseAppender(Allocator &allocator, AppenderType type); - DUCKDB_API BaseAppender(Allocator &allocator, vector types, AppenderType type); - -public: - DUCKDB_API virtual ~BaseAppender(); - - //! Begins a new row append, after calling this the other AppendX() functions - //! should be called the correct amount of times. After that, - //! EndRow() should be called. - DUCKDB_API void BeginRow(); - //! Finishes appending the current row. - DUCKDB_API void EndRow(); - - // Append functions - template - void Append(T value) { - throw Exception("Undefined type for Appender::Append!"); - } - - DUCKDB_API void Append(const char *value, uint32_t length); - - // prepared statements - template - void AppendRow(Args... args) { - BeginRow(); - AppendRowRecursive(args...); - } - - //! Commit the changes made by the appender. - DUCKDB_API void Flush(); - //! Flush the changes made by the appender and close it. The appender cannot be used after this point - DUCKDB_API void Close(); - - DUCKDB_API vector &GetTypes() { - return types; - } - DUCKDB_API idx_t CurrentColumn() { - return column; - } - DUCKDB_API void AppendDataChunk(DataChunk &value); - -protected: - void Destructor(); - virtual void FlushInternal(ColumnDataCollection &collection) = 0; - void InitializeChunk(); - void FlushChunk(); - - template - void AppendValueInternal(T value); - template - void AppendValueInternal(Vector &vector, SRC input); - template - void AppendDecimalValueInternal(Vector &vector, SRC input); - - void AppendRowRecursive() { - EndRow(); - } - - template - void AppendRowRecursive(T value, Args... args) { - Append(value); - AppendRowRecursive(args...); - } - - void AppendValue(const Value &value); -}; - -class Appender : public BaseAppender { - //! A reference to a database connection that created this appender - shared_ptr context; - //! The table description (including column names) - unique_ptr description; - -public: - DUCKDB_API Appender(Connection &con, const string &schema_name, const string &table_name); - DUCKDB_API Appender(Connection &con, const string &table_name); - DUCKDB_API ~Appender() override; - -protected: - void FlushInternal(ColumnDataCollection &collection) override; -}; - -class InternalAppender : public BaseAppender { - //! The client context - ClientContext &context; - //! The internal table entry to append to - TableCatalogEntry &table; - -public: - DUCKDB_API InternalAppender(ClientContext &context, TableCatalogEntry &table); - DUCKDB_API ~InternalAppender() override; - -protected: - void FlushInternal(ColumnDataCollection &collection) override; -}; - -template <> -DUCKDB_API void BaseAppender::Append(bool value); -template <> -DUCKDB_API void BaseAppender::Append(int8_t value); -template <> -DUCKDB_API void BaseAppender::Append(int16_t value); -template <> -DUCKDB_API void BaseAppender::Append(int32_t value); -template <> -DUCKDB_API void BaseAppender::Append(int64_t value); -template <> -DUCKDB_API void BaseAppender::Append(hugeint_t value); -template <> -DUCKDB_API void BaseAppender::Append(uint8_t value); -template <> -DUCKDB_API void BaseAppender::Append(uint16_t value); -template <> -DUCKDB_API void BaseAppender::Append(uint32_t value); -template <> -DUCKDB_API void BaseAppender::Append(uint64_t value); -template <> -DUCKDB_API void BaseAppender::Append(float value); -template <> -DUCKDB_API void BaseAppender::Append(double value); -template <> -DUCKDB_API void BaseAppender::Append(date_t value); -template <> -DUCKDB_API void BaseAppender::Append(dtime_t value); -template <> -DUCKDB_API void BaseAppender::Append(timestamp_t value); -template <> -DUCKDB_API void BaseAppender::Append(interval_t value); -template <> -DUCKDB_API void BaseAppender::Append(const char *value); -template <> -DUCKDB_API void BaseAppender::Append(string_t value); -template <> -DUCKDB_API void BaseAppender::Append(Value value); -template <> -DUCKDB_API void BaseAppender::Append(std::nullptr_t value); - +//! The Time class is a static class that holds helper functions for the Time +//! type. +class Time { +public: + //! Convert a string in the format "hh:mm:ss" to a time object + DUCKDB_API static dtime_t FromString(const string &str, bool strict = false); + DUCKDB_API static dtime_t FromCString(const char *buf, idx_t len, bool strict = false); + DUCKDB_API static bool TryConvertTime(const char *buf, idx_t len, idx_t &pos, dtime_t &result, bool strict = false); + + //! Convert a time object to a string in the format "hh:mm:ss" + DUCKDB_API static string ToString(dtime_t time); + //! Convert a UTC offset to ±HH[:MM] + DUCKDB_API static string ToUTCOffset(int hour_offset, int minute_offset); + + DUCKDB_API static dtime_t FromTime(int32_t hour, int32_t minute, int32_t second, int32_t microseconds = 0); + + //! Extract the time from a given timestamp object + DUCKDB_API static void Convert(dtime_t time, int32_t &out_hour, int32_t &out_min, int32_t &out_sec, + int32_t &out_micros); + + DUCKDB_API static string ConversionError(const string &str); + DUCKDB_API static string ConversionError(string_t str); + +private: + static bool TryConvertInternal(const char *buf, idx_t len, idx_t &pos, dtime_t &result, bool strict); +}; + } // namespace duckdb //===----------------------------------------------------------------------===// // DuckDB @@ -21953,35 +22216,205 @@ struct CreateFunctionInfo : public CreateInfo { } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/function/function_set.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/function/pragma_function.hpp +// +// +//===----------------------------------------------------------------------===// + + + + +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/parsed_data/pragma_info.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + + +namespace duckdb { + +enum class PragmaType : uint8_t { PRAGMA_STATEMENT, PRAGMA_CALL }; + +struct PragmaInfo : public ParseInfo { + //! Name of the PRAGMA statement + string name; + //! Parameter list (if any) + vector parameters; + //! Named parameter list (if any) + named_parameter_map_t named_parameters; + +public: + unique_ptr Copy() const { + auto result = make_unique(); + result->name = name; + result->parameters = parameters; + result->named_parameters = named_parameters; + return result; + } +}; + +} // namespace duckdb + namespace duckdb { +class ClientContext; -struct CreateTableFunctionInfo : public CreateFunctionInfo { - explicit CreateTableFunctionInfo(TableFunction function) - : CreateFunctionInfo(CatalogType::TABLE_FUNCTION_ENTRY), functions(function.name) { - name = function.name; - functions.AddFunction(move(function)); - } - explicit CreateTableFunctionInfo(TableFunctionSet set) - : CreateFunctionInfo(CatalogType::TABLE_FUNCTION_ENTRY), functions(move(set)) { - name = functions.name; - for (auto &func : functions.functions) { - func.name = functions.name; +//! Return a substitute query to execute instead of this pragma statement +typedef string (*pragma_query_t)(ClientContext &context, const FunctionParameters ¶meters); +//! Execute the main pragma function +typedef void (*pragma_function_t)(ClientContext &context, const FunctionParameters ¶meters); + +//! Pragma functions are invoked by calling PRAGMA x +//! Pragma functions come in three types: +//! * Call: function call, e.g. PRAGMA table_info('tbl') +//! -> call statements can take multiple parameters +//! * Statement: statement without parameters, e.g. PRAGMA show_tables +//! -> this is similar to a call pragma but without parameters +//! Pragma functions can either return a new query to execute (pragma_query_t) +//! or they can +class PragmaFunction : public SimpleNamedParameterFunction { +public: + // Call + DUCKDB_API static PragmaFunction PragmaCall(const string &name, pragma_query_t query, vector arguments, + LogicalType varargs = LogicalType::INVALID); + DUCKDB_API static PragmaFunction PragmaCall(const string &name, pragma_function_t function, + vector arguments, + LogicalType varargs = LogicalType::INVALID); + // Statement + DUCKDB_API static PragmaFunction PragmaStatement(const string &name, pragma_query_t query); + DUCKDB_API static PragmaFunction PragmaStatement(const string &name, pragma_function_t function); + + DUCKDB_API string ToString() override; + +public: + PragmaType type; + + pragma_query_t query; + pragma_function_t function; + named_parameter_type_map_t named_parameters; + +private: + PragmaFunction(string name, PragmaType pragma_type, pragma_query_t query, pragma_function_t function, + vector arguments, LogicalType varargs); +}; + +} // namespace duckdb + + +namespace duckdb { + +template +class FunctionSet { +public: + explicit FunctionSet(string name) : name(name) { + } + + //! The name of the function set + string name; + //! The set of functions. + vector functions; + +public: + void AddFunction(T function) { + functions.push_back(std::move(function)); + } + idx_t Size() { + return functions.size(); + } + T GetFunctionByOffset(idx_t offset) { + D_ASSERT(offset < functions.size()); + return functions[offset]; + } + T &GetFunctionReferenceByOffset(idx_t offset) { + D_ASSERT(offset < functions.size()); + return functions[offset]; + } + bool MergeFunctionSet(FunctionSet new_functions) { + D_ASSERT(!new_functions.functions.empty()); + bool need_rewrite_entry = false; + for (auto &new_func : new_functions.functions) { + bool can_add = true; + for (auto &func : functions) { + if (new_func.Equal(func)) { + can_add = false; + break; + } + } + if (can_add) { + functions.push_back(new_func); + need_rewrite_entry = true; + } } + return need_rewrite_entry; + } +}; + +class ScalarFunctionSet : public FunctionSet { +public: + DUCKDB_API explicit ScalarFunctionSet(string name); + + DUCKDB_API ScalarFunction GetFunctionByArguments(ClientContext &context, const vector &arguments); +}; + +class AggregateFunctionSet : public FunctionSet { +public: + DUCKDB_API explicit AggregateFunctionSet(string name); + + DUCKDB_API AggregateFunction GetFunctionByArguments(ClientContext &context, const vector &arguments); +}; + +class TableFunctionSet : public FunctionSet { +public: + DUCKDB_API explicit TableFunctionSet(string name); + + TableFunction GetFunctionByArguments(ClientContext &context, const vector &arguments); +}; + +class PragmaFunctionSet : public FunctionSet { +public: + explicit PragmaFunctionSet(string name) : FunctionSet(std::move(name)) { } +}; + +} // namespace duckdb + + +namespace duckdb { + +struct CreateTableFunctionInfo : public CreateFunctionInfo { + DUCKDB_API explicit CreateTableFunctionInfo(TableFunction function); + DUCKDB_API explicit CreateTableFunctionInfo(TableFunctionSet set); //! The table functions TableFunctionSet functions; public: - unique_ptr Copy() const override { - TableFunctionSet set(name); - set.functions = functions.functions; - auto result = make_unique(move(set)); - CopyProperties(*result); - return move(result); - } + DUCKDB_API unique_ptr Copy() const; }; } // namespace duckdb @@ -22023,30 +22456,34 @@ struct CreateTableFunctionInfo : public CreateFunctionInfo { + namespace duckdb { struct CopyInfo : public ParseInfo { - CopyInfo() : schema(DEFAULT_SCHEMA) { + CopyInfo() : catalog(INVALID_CATALOG), schema(DEFAULT_SCHEMA) { } + //! The catalog name to copy to/from + string catalog; //! The schema name to copy to/from string schema; //! The table name to copy to/from string table; //! List of columns to copy to/from vector select_list; - //! The file path to copy to/from - string file_path; //! Whether or not this is a copy to file (false) or copy from a file (true) bool is_from; //! The file format of the external file string format; + //! The file path to copy to/from + string file_path; //! Set of (key, value) options - unordered_map> options; + case_insensitive_map_t> options; public: unique_ptr Copy() const { auto result = make_unique(); + result->catalog = catalog; result->schema = schema; result->table = table; result->select_list = select_list; @@ -22060,8 +22497,47 @@ struct CopyInfo : public ParseInfo { } // namespace duckdb +//===----------------------------------------------------------------------===// +// DuckDB +// +// duckdb/parser/statement/copy_statement.hpp +// +// +//===----------------------------------------------------------------------===// + + + + + + + +namespace duckdb { + +class CopyStatement : public SQLStatement { +public: + CopyStatement(); + + unique_ptr info; + // The SQL statement used instead of a table when copying data out to a file + unique_ptr select_statement; + string ToString() const override; + string CopyOptionsToString(const string &format, const case_insensitive_map_t> &options) const; + +protected: + CopyStatement(const CopyStatement &other); + +public: + unique_ptr Copy() const override; + +private: +}; +} // namespace duckdb + namespace duckdb { + +class Binder; +struct BoundStatement; class ExecutionContext; struct LocalFunctionData { @@ -22074,6 +22550,7 @@ struct GlobalFunctionData { } }; +typedef BoundStatement (*copy_to_plan_t)(Binder &binder, CopyStatement &stmt); typedef unique_ptr (*copy_to_bind_t)(ClientContext &context, CopyInfo &info, vector &names, vector &sql_types); typedef unique_ptr (*copy_to_initialize_local_t)(ExecutionContext &context, FunctionData &bind_data); @@ -22093,21 +22570,27 @@ typedef unique_ptr (*copy_to_deserialize_t)(ClientContext &context typedef unique_ptr (*copy_from_bind_t)(ClientContext &context, CopyInfo &info, vector &expected_names, vector &expected_types); +typedef bool (*copy_to_is_parallel_t)(ClientContext &context, FunctionData &bind_data); class CopyFunction : public Function { public: explicit CopyFunction(string name) - : Function(name), copy_to_bind(nullptr), copy_to_initialize_local(nullptr), copy_to_initialize_global(nullptr), - copy_to_sink(nullptr), copy_to_combine(nullptr), copy_to_finalize(nullptr), serialize(nullptr), - deserialize(nullptr), copy_from_bind(nullptr) { + : Function(name), plan(nullptr), copy_to_bind(nullptr), copy_to_initialize_local(nullptr), + copy_to_initialize_global(nullptr), copy_to_sink(nullptr), copy_to_combine(nullptr), + copy_to_finalize(nullptr), parallel(nullptr), serialize(nullptr), deserialize(nullptr), + copy_from_bind(nullptr) { } + //! Plan rewrite copy function + copy_to_plan_t plan; + copy_to_bind_t copy_to_bind; copy_to_initialize_local_t copy_to_initialize_local; copy_to_initialize_global_t copy_to_initialize_global; copy_to_sink_t copy_to_sink; copy_to_combine_t copy_to_combine; copy_to_finalize_t copy_to_finalize; + copy_to_is_parallel_t parallel; copy_to_serialize_t serialize; copy_to_deserialize_t deserialize; @@ -22124,10 +22607,7 @@ class CopyFunction : public Function { namespace duckdb { struct CreateCopyFunctionInfo : public CreateInfo { - explicit CreateCopyFunctionInfo(CopyFunction function) - : CreateInfo(CatalogType::COPY_FUNCTION_ENTRY), function(function) { - this->name = function.name; - } + DUCKDB_API explicit CreateCopyFunctionInfo(CopyFunction function); //! Function name string name; @@ -22135,16 +22615,10 @@ struct CreateCopyFunctionInfo : public CreateInfo { CopyFunction function; protected: - void SerializeInternal(Serializer &) const override { - throw NotImplementedException("Cannot serialize '%s'", CatalogTypeToString(type)); - } + void SerializeInternal(Serializer &) const override; public: - unique_ptr Copy() const override { - auto result = make_unique(function); - CopyProperties(*result); - return move(result); - } + unique_ptr Copy() const override; }; } // namespace duckdb diff --git a/libduckdb-sys/src/lib.rs b/libduckdb-sys/src/lib.rs index 99de767c..3e387833 100644 --- a/libduckdb-sys/src/lib.rs +++ b/libduckdb-sys/src/lib.rs @@ -23,7 +23,7 @@ mod tests { use std::convert::TryFrom; use std::ffi::{CStr, CString}; use std::mem; - use std::os::raw::{c_char, c_void}; + use std::os::raw::c_char; use std::ptr; use arrow::array::{Array, ArrayData, Int32Array, StructArray}; @@ -87,11 +87,15 @@ mod tests { let mut arrays = &FFI_ArrowArray::empty(); let mut schema = &FFI_ArrowSchema::empty(); let schema = &mut schema; - if duckdb_query_arrow_schema(result, schema as *mut _ as *mut *mut c_void) != duckdb_state_DuckDBSuccess { + if duckdb_query_arrow_schema(result, schema as *mut _ as *mut duckdb_arrow_schema) + != duckdb_state_DuckDBSuccess + { panic!("SELECT error") } let arrays = &mut arrays; - if duckdb_query_arrow_array(result, arrays as *mut _ as *mut *mut c_void) != duckdb_state_DuckDBSuccess { + if duckdb_query_arrow_array(result, arrays as *mut _ as *mut duckdb_arrow_array) + != duckdb_state_DuckDBSuccess + { panic!("SELECT error") } let arrow_array = diff --git a/libduckdb-sys/upgrade.sh b/libduckdb-sys/upgrade.sh index 75b81de8..d0229ed9 100755 --- a/libduckdb-sys/upgrade.sh +++ b/libduckdb-sys/upgrade.sh @@ -10,7 +10,7 @@ export DUCKDB_LIB_DIR="$SCRIPT_DIR/duckdb" export DU_INCLUDE_DIR="$DUCKDB_LIB_DIR" # Download and extract amalgamation -DUCKDB_VERSION=v0.6.1 +DUCKDB_VERSION=v0.7.0 wget -T 20 "https://github.com/duckdb/duckdb/releases/download/$DUCKDB_VERSION/libduckdb-src.zip" unzip -o libduckdb-src.zip -d duckdb rm -f libduckdb-src.zip diff --git a/src/cache.rs b/src/cache.rs index fed9a966..dbe3d357 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -204,14 +204,14 @@ mod test { { let mut stmt = db.prepare_cached(sql)?; assert_eq!(0, cache.len()); - assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?); + assert_eq!(4, stmt.query_row([], |r| r.get::<_, i64>(0))?); } assert_eq!(1, cache.len()); { let mut stmt = db.prepare_cached(sql)?; assert_eq!(0, cache.len()); - assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?); + assert_eq!(4, stmt.query_row([], |r| r.get::<_, i64>(0))?); } assert_eq!(1, cache.len()); @@ -230,7 +230,7 @@ mod test { { let mut stmt = db.prepare_cached(sql)?; assert_eq!(0, cache.len()); - assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?); + assert_eq!(4, stmt.query_row([], |r| r.get::<_, i64>(0))?); } assert_eq!(1, cache.len()); @@ -240,7 +240,7 @@ mod test { { let mut stmt = db.prepare_cached(sql)?; assert_eq!(0, cache.len()); - assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?); + assert_eq!(4, stmt.query_row([], |r| r.get::<_, i64>(0))?); } assert_eq!(0, cache.len()); @@ -248,7 +248,7 @@ mod test { { let mut stmt = db.prepare_cached(sql)?; assert_eq!(0, cache.len()); - assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?); + assert_eq!(4, stmt.query_row([], |r| r.get::<_, i64>(0))?); } assert_eq!(1, cache.len()); Ok(()) @@ -263,7 +263,7 @@ mod test { { let mut stmt = db.prepare_cached(sql)?; assert_eq!(0, cache.len()); - assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?); + assert_eq!(4, stmt.query_row([], |r| r.get::<_, i64>(0))?); stmt.discard(); } assert_eq!(0, cache.len()); @@ -324,14 +324,14 @@ mod test { { let mut stmt = db.prepare_cached(sql)?; assert_eq!(0, cache.len()); - assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?); + assert_eq!(4, stmt.query_row([], |r| r.get::<_, i64>(0))?); } assert_eq!(1, cache.len()); { let mut stmt = db.prepare_cached(sql)?; assert_eq!(0, cache.len()); - assert_eq!(0, stmt.query_row([], |r| r.get::<_, i64>(0))?); + assert_eq!(4, stmt.query_row([], |r| r.get::<_, i64>(0))?); } assert_eq!(1, cache.len()); Ok(()) diff --git a/src/raw_statement.rs b/src/raw_statement.rs index 1be8c7f6..87c8a808 100644 --- a/src/raw_statement.rs +++ b/src/raw_statement.rs @@ -1,6 +1,5 @@ use std::convert::TryFrom; use std::ffi::CStr; -use std::os::raw::c_void; use std::ptr; use std::sync::Arc; @@ -84,7 +83,7 @@ impl RawStatement { unsafe { let mut arrays = &FFI_ArrowArray::empty(); let arrays = &mut arrays; - if ffi::duckdb_query_arrow_array(self.result_unwrap(), arrays as *mut _ as *mut *mut c_void) + if ffi::duckdb_query_arrow_array(self.result_unwrap(), arrays as *mut _ as *mut ffi::duckdb_arrow_array) != ffi::DuckDBSuccess { return None; @@ -95,7 +94,7 @@ impl RawStatement { let mut schema = &FFI_ArrowSchema::empty(); let schema = &mut schema; - if ffi::duckdb_query_arrow_schema(self.result_unwrap(), schema as *mut _ as *mut *mut c_void) + if ffi::duckdb_query_arrow_schema(self.result_unwrap(), schema as *mut _ as *mut ffi::duckdb_arrow_schema) != ffi::DuckDBSuccess { return None; @@ -178,7 +177,7 @@ impl RawStatement { let rows_changed = ffi::duckdb_arrow_rows_changed(out); let mut c_schema = Arc::into_raw(Arc::new(FFI_ArrowSchema::empty())); - let rc = ffi::duckdb_query_arrow_schema(out, &mut c_schema as *mut _ as *mut *mut c_void); + let rc = ffi::duckdb_query_arrow_schema(out, &mut c_schema as *mut _ as *mut ffi::duckdb_arrow_schema); if rc != ffi::DuckDBSuccess { Arc::from_raw(c_schema); result_from_duckdb_arrow(rc, out)?; From 16bc9e4b7d15c158b3030ed58cb5d02b5dfc4bb4 Mon Sep 17 00:00:00 2001 From: wangfenjin Date: Mon, 13 Feb 2023 22:13:11 +0800 Subject: [PATCH 2/2] use bundled for asan Change-Id: Id42ad0dc77c5718de4cd313d9829364de7c0dbfc --- .github/workflows/rust.yaml | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml index ffbc0390..0e8e37f9 100644 --- a/.github/workflows/rust.yaml +++ b/.github/workflows/rust.yaml @@ -118,34 +118,17 @@ jobs: with: rust-version: nightly components: rust-src - # download libduckdb - - uses: robinraju/release-downloader@v1.4 - name: Download duckdb - with: - repository: "duckdb/duckdb" - tag: "v0.7.0" - fileName: "libduckdb-linux-amd64.zip" - out-file-path: . - - name: Linux extract duckdb - uses: ihiroky/extract-action@v1 - with: - file_path: ${{ github.workspace }}/libduckdb-linux-amd64.zip - extract_dir: libduckdb - name: Tests with asan env: RUSTFLAGS: -Zsanitizer=address RUSTDOCFLAGS: -Zsanitizer=address ASAN_OPTIONS: "detect_stack_use_after_return=1:detect_leaks=1" - DUCKDB_LIB_DIR: ${{ github.workspace }}/libduckdb - DUCKDB_INCLUDE_DIR: ${{ github.workspace }}/libduckdb - LD_LIBRARY_PATH: ${{ github.workspace }}/libduckdb # Work around https://github.com/rust-lang/rust/issues/59125 by # disabling backtraces. In an ideal world we'd probably suppress the # leak sanitization, but we don't care about backtraces here, so long # as the other tests have them. RUST_BACKTRACE: "0" - # run: cargo -Z build-std test --features 'bundled' --features 'modern-full' --target x86_64-unknown-linux-gnu - run: cargo -Z build-std test --features 'modern-full' --target x86_64-unknown-linux-gnu + run: cargo -Z build-std test --features 'bundled' --features 'modern-full' --target x86_64-unknown-linux-gnu - uses: wangfenjin/publish-crates@main name: cargo publish --dry-run